diff --git a/.github/actions/fetch-codeql/action.yml b/.github/actions/fetch-codeql/action.yml index 13b91525237..d1f48f40047 100644 --- a/.github/actions/fetch-codeql/action.yml +++ b/.github/actions/fetch-codeql/action.yml @@ -3,22 +3,12 @@ description: Fetches the latest version of CodeQL runs: using: composite steps: - - name: Select platform - Linux - if: runner.os == 'Linux' - shell: bash - run: echo "GA_CODEQL_CLI_PLATFORM=linux64" >> $GITHUB_ENV - - - name: Select platform - MacOS - if: runner.os == 'MacOS' - shell: bash - run: echo "GA_CODEQL_CLI_PLATFORM=osx64" >> $GITHUB_ENV - - name: Fetch CodeQL shell: bash run: | - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-$GA_CODEQL_CLI_PLATFORM.zip "$LATEST" - unzip -q -d "${RUNNER_TEMP}" codeql-$GA_CODEQL_CLI_PLATFORM.zip - echo "${RUNNER_TEMP}/codeql" >> "${GITHUB_PATH}" + gh extension install github/gh-codeql + gh codeql set-channel release + gh codeql version + gh codeql version --format=json | jq -r .unpackedLocation >> "${GITHUB_PATH}" env: GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/check-change-note.yml b/.github/workflows/check-change-note.yml index 672202444bb..b60a590ab09 100644 --- a/.github/workflows/check-change-note.yml +++ b/.github/workflows/check-change-note.yml @@ -10,6 +10,7 @@ on: - "*/ql/lib/**/*.qll" - "!**/experimental/**" - "!ql/**" + - "!swift/**" - ".github/workflows/check-change-note.yml" jobs: diff --git a/.github/workflows/check-qldoc.yml b/.github/workflows/check-qldoc.yml index 77f524b73e7..be986d5ecf6 100644 --- a/.github/workflows/check-qldoc.yml +++ b/.github/workflows/check-qldoc.yml @@ -5,6 +5,7 @@ on: paths: - "*/ql/lib/**" - .github/workflows/check-qldoc.yml + - .github/actions/fetch-codeql branches: - main - "rc/*" @@ -14,18 +15,13 @@ jobs: runs-on: ubuntu-latest steps: - - name: Install CodeQL - run: | - gh extension install github/gh-codeql - gh codeql set-channel nightly - gh codeql version - env: - GITHUB_TOKEN: ${{ github.token }} - - uses: actions/checkout@v3 with: fetch-depth: 2 + - name: Install CodeQL + uses: ./.github/actions/fetch-codeql + - name: Check QLdoc coverage shell: bash run: | @@ -34,7 +30,7 @@ jobs: changed_lib_packs="$(git diff --name-only --diff-filter=ACMRT HEAD^ HEAD | { grep -Po '^(?!swift)[a-z]*/ql/lib' || true; } | sort -u)" for pack_dir in ${changed_lib_packs}; do lang="${pack_dir%/ql/lib}" - gh codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-current.txt" --dir="${pack_dir}" + codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-current.txt" --dir="${pack_dir}" done git checkout HEAD^ for pack_dir in ${changed_lib_packs}; do @@ -42,7 +38,7 @@ jobs: # In this case the right thing to do is to skip the check. [[ ! -d "${pack_dir}" ]] && continue lang="${pack_dir%/ql/lib}" - gh codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-baseline.txt" --dir="${pack_dir}" + codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-baseline.txt" --dir="${pack_dir}" awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-current.txt" | sort -u > "${RUNNER_TEMP}/current-undocumented.txt" awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-baseline.txt" | sort -u > "${RUNNER_TEMP}/baseline-undocumented.txt" UNDOCUMENTED="$(grep -f <(comm -13 "${RUNNER_TEMP}/baseline-undocumented.txt" "${RUNNER_TEMP}/current-undocumented.txt") "${RUNNER_TEMP}/${lang}-current.txt" || true)" diff --git a/.github/workflows/csv-coverage-metrics.yml b/.github/workflows/csv-coverage-metrics.yml index 7778221dc2f..e263572398e 100644 --- a/.github/workflows/csv-coverage-metrics.yml +++ b/.github/workflows/csv-coverage-metrics.yml @@ -12,6 +12,7 @@ on: - main paths: - ".github/workflows/csv-coverage-metrics.yml" + - ".github/actions/fetch-codeql" jobs: publish-java: diff --git a/.github/workflows/csv-coverage-pr-artifacts.yml b/.github/workflows/csv-coverage-pr-artifacts.yml index 379b3c5aad8..b63d85534b4 100644 --- a/.github/workflows/csv-coverage-pr-artifacts.yml +++ b/.github/workflows/csv-coverage-pr-artifacts.yml @@ -3,18 +3,20 @@ name: Check framework coverage changes on: pull_request: paths: - - '.github/workflows/csv-coverage-pr-comment.yml' - - '*/ql/src/**/*.ql' - - '*/ql/src/**/*.qll' - - '*/ql/lib/**/*.ql' - - '*/ql/lib/**/*.qll' - - 'misc/scripts/library-coverage/*.py' + - ".github/workflows/csv-coverage-pr-comment.yml" + - ".github/workflows/csv-coverage-pr-artifacts.yml" + - ".github/actions/fetch-codeql" + - "*/ql/src/**/*.ql" + - "*/ql/src/**/*.qll" + - "*/ql/lib/**/*.ql" + - "*/ql/lib/**/*.qll" + - "misc/scripts/library-coverage/*.py" # input data files - - '*/documentation/library-coverage/cwe-sink.csv' - - '*/documentation/library-coverage/frameworks.csv' + - "*/documentation/library-coverage/cwe-sink.csv" + - "*/documentation/library-coverage/frameworks.csv" branches: - main - - 'rc/*' + - "rc/*" jobs: generate: @@ -23,77 +25,72 @@ jobs: runs-on: ubuntu-latest steps: - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJSON(github.event) }} - run: echo "$GITHUB_CONTEXT" - - name: Clone self (github/codeql) - MERGE - uses: actions/checkout@v3 - with: - path: merge - - name: Clone self (github/codeql) - BASE - uses: actions/checkout@v3 - with: - fetch-depth: 2 - path: base - - run: | - git checkout HEAD^1 - git log -1 --format='%H' - working-directory: base - - name: Set up Python 3.8 - uses: actions/setup-python@v4 - with: - python-version: 3.8 - - name: Download CodeQL CLI - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip" - - name: Unzip CodeQL CLI - run: unzip -d codeql-cli codeql-linux64.zip - - name: Generate CSV files on merge commit of the PR - run: | - echo "Running generator on merge" - PATH="$PATH:codeql-cli/codeql" python merge/misc/scripts/library-coverage/generate-report.py ci merge merge - mkdir out_merge - cp framework-coverage-*.csv out_merge/ - cp framework-coverage-*.rst out_merge/ - - name: Generate CSV files on base commit of the PR - run: | - echo "Running generator on base" - PATH="$PATH:codeql-cli/codeql" python base/misc/scripts/library-coverage/generate-report.py ci base base - mkdir out_base - cp framework-coverage-*.csv out_base/ - cp framework-coverage-*.rst out_base/ - - name: Generate diff of coverage reports - run: | - python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md - - name: Upload CSV package list - uses: actions/upload-artifact@v3 - with: - name: csv-framework-coverage-merge - path: | - out_merge/framework-coverage-*.csv - out_merge/framework-coverage-*.rst - - name: Upload CSV package list - uses: actions/upload-artifact@v3 - with: - name: csv-framework-coverage-base - path: | - out_base/framework-coverage-*.csv - out_base/framework-coverage-*.rst - - name: Upload comparison results - uses: actions/upload-artifact@v3 - with: - name: comparison - path: | - comparison.md - - name: Save PR number - run: | - mkdir -p pr - echo ${{ github.event.pull_request.number }} > pr/NR - - name: Upload PR number - uses: actions/upload-artifact@v3 - with: - name: pr - path: pr/ + - name: Dump GitHub context + env: + GITHUB_CONTEXT: ${{ toJSON(github.event) }} + run: echo "$GITHUB_CONTEXT" + - name: Clone self (github/codeql) - MERGE + uses: actions/checkout@v3 + with: + path: merge + - name: Clone self (github/codeql) - BASE + uses: actions/checkout@v3 + with: + fetch-depth: 2 + path: base + - run: | + git checkout HEAD^1 + git log -1 --format='%H' + working-directory: base + - name: Set up Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Download CodeQL CLI + uses: ./merge/.github/actions/fetch-codeql + - name: Generate CSV files on merge commit of the PR + run: | + echo "Running generator on merge" + PATH="$PATH:codeql-cli/codeql" python merge/misc/scripts/library-coverage/generate-report.py ci merge merge + mkdir out_merge + cp framework-coverage-*.csv out_merge/ + cp framework-coverage-*.rst out_merge/ + - name: Generate CSV files on base commit of the PR + run: | + echo "Running generator on base" + PATH="$PATH:codeql-cli/codeql" python base/misc/scripts/library-coverage/generate-report.py ci base base + mkdir out_base + cp framework-coverage-*.csv out_base/ + cp framework-coverage-*.rst out_base/ + - name: Generate diff of coverage reports + run: | + python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md + - name: Upload CSV package list + uses: actions/upload-artifact@v3 + with: + name: csv-framework-coverage-merge + path: | + out_merge/framework-coverage-*.csv + out_merge/framework-coverage-*.rst + - name: Upload CSV package list + uses: actions/upload-artifact@v3 + with: + name: csv-framework-coverage-base + path: | + out_base/framework-coverage-*.csv + out_base/framework-coverage-*.rst + - name: Upload comparison results + uses: actions/upload-artifact@v3 + with: + name: comparison + path: | + comparison.md + - name: Save PR number + run: | + mkdir -p pr + echo ${{ github.event.pull_request.number }} > pr/NR + - name: Upload PR number + uses: actions/upload-artifact@v3 + with: + name: pr + path: pr/ diff --git a/.github/workflows/csv-coverage-timeseries.yml b/.github/workflows/csv-coverage-timeseries.yml index 95b084ea215..2eb9d0cdf84 100644 --- a/.github/workflows/csv-coverage-timeseries.yml +++ b/.github/workflows/csv-coverage-timeseries.yml @@ -5,38 +5,31 @@ on: jobs: build: - runs-on: ubuntu-latest steps: - - name: Clone self (github/codeql) - uses: actions/checkout@v3 - with: - path: script - - name: Clone self (github/codeql) for analysis - uses: actions/checkout@v3 - with: - path: codeqlModels - fetch-depth: 0 - - name: Set up Python 3.8 - uses: actions/setup-python@v4 - with: - python-version: 3.8 - - name: Download CodeQL CLI - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip" - - name: Unzip CodeQL CLI - run: unzip -d codeql-cli codeql-linux64.zip - - name: Build modeled package list - run: | - CLI=$(realpath "codeql-cli/codeql") - echo $CLI - PATH="$PATH:$CLI" python script/misc/scripts/library-coverage/generate-timeseries.py codeqlModels - - name: Upload timeseries CSV - uses: actions/upload-artifact@v3 - with: - name: framework-coverage-timeseries - path: framework-coverage-timeseries-*.csv - + - name: Clone self (github/codeql) + uses: actions/checkout@v3 + with: + path: script + - name: Clone self (github/codeql) for analysis + uses: actions/checkout@v3 + with: + path: codeqlModels + fetch-depth: 0 + - name: Set up Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Download CodeQL CLI + uses: ./.github/actions/fetch-codeql + - name: Build modeled package list + run: | + CLI=$(realpath "codeql-cli/codeql") + echo $CLI + PATH="$PATH:$CLI" python script/misc/scripts/library-coverage/generate-timeseries.py codeqlModels + - name: Upload timeseries CSV + uses: actions/upload-artifact@v3 + with: + name: framework-coverage-timeseries + path: framework-coverage-timeseries-*.csv diff --git a/.github/workflows/csv-coverage-update.yml b/.github/workflows/csv-coverage-update.yml index c57056b6de1..58e60cc363e 100644 --- a/.github/workflows/csv-coverage-update.yml +++ b/.github/workflows/csv-coverage-update.yml @@ -12,33 +12,27 @@ jobs: runs-on: ubuntu-latest steps: - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJSON(github.event) }} - run: echo "$GITHUB_CONTEXT" - - name: Clone self (github/codeql) - uses: actions/checkout@v3 - with: - path: ql - fetch-depth: 0 - - name: Set up Python 3.8 - uses: actions/setup-python@v4 - with: - python-version: 3.8 - - name: Download CodeQL CLI - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip" - - name: Unzip CodeQL CLI - run: unzip -d codeql-cli codeql-linux64.zip + - name: Dump GitHub context + env: + GITHUB_CONTEXT: ${{ toJSON(github.event) }} + run: echo "$GITHUB_CONTEXT" + - name: Clone self (github/codeql) + uses: actions/checkout@v3 + with: + path: ql + fetch-depth: 0 + - name: Set up Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Download CodeQL CLI + uses: ./.github/actions/fetch-codeql + - name: Generate coverage files + run: | + PATH="$PATH:codeql-cli/codeql" python ql/misc/scripts/library-coverage/generate-report.py ci ql ql - - name: Generate coverage files - run: | - PATH="$PATH:codeql-cli/codeql" python ql/misc/scripts/library-coverage/generate-report.py ci ql ql - - - name: Create pull request with changes - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - python ql/misc/scripts/library-coverage/create-pr.py ql "$GITHUB_REPOSITORY" + - name: Create pull request with changes + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + python ql/misc/scripts/library-coverage/create-pr.py ql "$GITHUB_REPOSITORY" diff --git a/.github/workflows/csv-coverage.yml b/.github/workflows/csv-coverage.yml index 9a308d50265..dfce019451e 100644 --- a/.github/workflows/csv-coverage.yml +++ b/.github/workflows/csv-coverage.yml @@ -4,46 +4,39 @@ on: workflow_dispatch: inputs: qlModelShaOverride: - description: 'github/codeql repo SHA used for looking up the CSV models' + description: "github/codeql repo SHA used for looking up the CSV models" required: false jobs: build: - runs-on: ubuntu-latest steps: - - name: Clone self (github/codeql) - uses: actions/checkout@v3 - with: - path: script - - name: Clone self (github/codeql) for analysis - uses: actions/checkout@v3 - with: - path: codeqlModels - ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }} - - name: Set up Python 3.8 - uses: actions/setup-python@v4 - with: - python-version: 3.8 - - name: Download CodeQL CLI - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip" - - name: Unzip CodeQL CLI - run: unzip -d codeql-cli codeql-linux64.zip - - name: Build modeled package list - run: | - PATH="$PATH:codeql-cli/codeql" python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script - - name: Upload CSV package list - uses: actions/upload-artifact@v3 - with: - name: framework-coverage-csv - path: framework-coverage-*.csv - - name: Upload RST package list - uses: actions/upload-artifact@v3 - with: - name: framework-coverage-rst - path: framework-coverage-*.rst - + - name: Clone self (github/codeql) + uses: actions/checkout@v3 + with: + path: script + - name: Clone self (github/codeql) for analysis + uses: actions/checkout@v3 + with: + path: codeqlModels + ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }} + - name: Set up Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Download CodeQL CLI + uses: ./.github/actions/fetch-codeql + - name: Build modeled package list + run: | + PATH="$PATH:codeql-cli/codeql" python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script + - name: Upload CSV package list + uses: actions/upload-artifact@v3 + with: + name: framework-coverage-csv + path: framework-coverage-*.csv + - name: Upload RST package list + uses: actions/upload-artifact@v3 + with: + name: framework-coverage-rst + path: framework-coverage-*.rst diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index ca126d1a3ee..6001a18aad1 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -4,159 +4,111 @@ on: paths: - "go/**" - .github/workflows/go-tests.yml + - .github/actions/fetch-codeql - codeql-workspace.yml jobs: - test-linux: name: Test Linux (Ubuntu) runs-on: ubuntu-latest steps: + - name: Set up Go 1.18.1 + uses: actions/setup-go@v3 + with: + go-version: 1.18.1 + id: go - - name: Set up Go 1.18.1 - uses: actions/setup-go@v3 - with: - go-version: 1.18.1 - id: go + - name: Check out code + uses: actions/checkout@v2 - - name: Set up CodeQL CLI - run: | - echo "Removing old CodeQL Directory..." - rm -rf $HOME/codeql - echo "Done" - cd $HOME - echo "Downloading CodeQL CLI..." - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST" - echo "Done" - echo "Unpacking CodeQL CLI..." - unzip -q codeql-linux64.zip - rm -f codeql-linux64.zip - echo "Done" - env: - GITHUB_TOKEN: ${{ github.token }} + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql - - name: Check out code - uses: actions/checkout@v2 + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + - name: Build + run: | + cd go + env make - - name: Build - run: | - cd go - env PATH=$PATH:$HOME/codeql make + - name: Check that all QL and Go code is autoformatted + run: | + cd go + env make check-formatting - - name: Check that all QL and Go code is autoformatted - run: | - cd go - env PATH=$PATH:$HOME/codeql make check-formatting + - name: Compile qhelp files to markdown + run: | + cd go + env QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown - - name: Compile qhelp files to markdown - run: | - cd go - env PATH=$PATH:$HOME/codeql QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown + - name: Upload qhelp markdown + uses: actions/upload-artifact@v2 + with: + name: qhelp-markdown + path: go/qhelp-out/**/*.md - - name: Upload qhelp markdown - uses: actions/upload-artifact@v2 - with: - name: qhelp-markdown - path: go/qhelp-out/**/*.md - - - name: Test - run: | - cd go - env PATH=$PATH:$HOME/codeql make test + - name: Test + run: | + cd go + env make test test-mac: name: Test MacOS - runs-on: macOS-latest + runs-on: macos-latest steps: - - name: Set up Go 1.18.1 - uses: actions/setup-go@v3 - with: - go-version: 1.18.1 - id: go + - name: Set up Go 1.18.1 + uses: actions/setup-go@v3 + with: + go-version: 1.18.1 + id: go - - name: Set up CodeQL CLI - run: | - echo "Removing old CodeQL Directory..." - rm -rf $HOME/codeql - echo "Done" - cd $HOME - echo "Downloading CodeQL CLI..." - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-osx64.zip "$LATEST" - echo "Done" - echo "Unpacking CodeQL CLI..." - unzip -q codeql-osx64.zip - rm -f codeql-osx64.zip - echo "Done" - env: - GITHUB_TOKEN: ${{ github.token }} + - name: Check out code + uses: actions/checkout@v2 - - 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: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - name: Build - run: | - cd go - env PATH=$PATH:$HOME/codeql make + - name: Build + run: | + cd go + make - - name: Test - run: | - cd go - env PATH=$PATH:$HOME/codeql make test + - name: Test + run: | + cd go + make test test-win: name: Test Windows runs-on: windows-2019 steps: - - name: Set up Go 1.18.1 - uses: actions/setup-go@v3 - with: - go-version: 1.18.1 - id: go + - name: Set up Go 1.18.1 + uses: actions/setup-go@v3 + with: + go-version: 1.18.1 + id: go - - name: Set up CodeQL CLI - run: | - echo "Removing old CodeQL Directory..." - rm -rf $HOME/codeql - echo "Done" - cd "$HOME" - echo "Downloading CodeQL CLI..." - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-win64.zip "$LATEST" - echo "Done" - echo "Unpacking CodeQL CLI..." - unzip -q -o codeql-win64.zip - unzip -q -o codeql-win64.zip codeql/codeql.exe - rm -f codeql-win64.zip - echo "Done" - env: - GITHUB_TOKEN: ${{ github.token }} - shell: - bash + - name: Check out code + uses: actions/checkout@v2 - - 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: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - name: Build - run: | - $Env:Path += ";$HOME\codeql" - cd go - make + - name: Build + run: | + cd go + make - - name: Test - run: | - $Env:Path += ";$HOME\codeql" - cd go - make test + - name: Test + run: | + cd go + make test diff --git a/.github/workflows/js-ml-tests.yml b/.github/workflows/js-ml-tests.yml index 65db215d8c3..0b23f91ed48 100644 --- a/.github/workflows/js-ml-tests.yml +++ b/.github/workflows/js-ml-tests.yml @@ -5,6 +5,7 @@ on: paths: - "javascript/ql/experimental/adaptivethreatmodeling/**" - .github/workflows/js-ml-tests.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main @@ -13,6 +14,7 @@ on: paths: - "javascript/ql/experimental/adaptivethreatmodeling/**" - .github/workflows/js-ml-tests.yml + - .github/actions/fetch-codeql - codeql-workspace.yml workflow_dispatch: diff --git a/.github/workflows/mad_regenerate-models.yml b/.github/workflows/mad_regenerate-models.yml index d1d7e6e3791..9f16c223ec6 100644 --- a/.github/workflows/mad_regenerate-models.yml +++ b/.github/workflows/mad_regenerate-models.yml @@ -9,6 +9,7 @@ on: - main paths: - ".github/workflows/mad_regenerate-models.yml" + - ".github/actions/fetch-codeql" jobs: regenerate-models: diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 6b4f6a0abee..f5df6291b62 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -10,16 +10,16 @@ env: CARGO_TERM_COLOR: always jobs: - queries: - runs-on: ubuntu-latest + analyze: + runs-on: ubuntu-latest-xl steps: + ### Build the queries ### - uses: actions/checkout@v3 - name: Find codeql id: find-codeql uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980 with: languages: javascript # does not matter - tools: latest - name: Get CodeQL version id: get-codeql-version run: | @@ -49,14 +49,7 @@ jobs: name: query-pack-zip path: ${{ runner.temp }}/query-pack.zip - extractors: - strategy: - fail-fast: false - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 + ### Build the extractor ### - name: Cache entire extractor id: cache-extractor uses: actions/cache@v3 @@ -100,15 +93,8 @@ jobs: ql/target/release/ql-extractor ql/target/release/ql-extractor.exe retention-days: 1 - package: - runs-on: ubuntu-latest - needs: - - extractors - - queries - - steps: - - uses: actions/checkout@v3 + ### Package the queries and extractor ### - uses: actions/download-artifact@v3 with: name: query-pack-zip @@ -136,16 +122,8 @@ jobs: name: codeql-ql-pack path: codeql-ql.zip retention-days: 1 - analyze: - runs-on: ubuntu-latest - strategy: - matrix: - folder: [cpp, csharp, java, javascript, python, ql, ruby, swift, go] - needs: - - package - - steps: + ### Run the analysis ### - name: Download pack uses: actions/download-artifact@v3 with: @@ -165,14 +143,11 @@ jobs: env: PACK: ${{ runner.temp }}/pack - - name: Checkout repository - uses: actions/checkout@v3 - name: Create CodeQL config file run: | - echo "paths:" > ${CONF} - echo " - ${FOLDER}" >> ${CONF} echo "paths-ignore:" >> ${CONF} echo " - ql/ql/test" >> ${CONF} + echo " - \"*/ql/lib/upgrades/\"" >> ${CONF} echo "disable-default-queries: true" >> ${CONF} echo "packs:" >> ${CONF} echo " - codeql/ql" >> ${CONF} @@ -180,24 +155,34 @@ jobs: cat ${CONF} env: CONF: ./ql-for-ql-config.yml - FOLDER: ${{ matrix.folder }} - name: Initialize CodeQL uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980 with: languages: ql db-location: ${{ runner.temp }}/db config-file: ./ql-for-ql-config.yml - tools: latest - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@aa93aea877e5fb8841bcb1193f672abf6e9f2980 with: - category: "ql-for-ql-${{ matrix.folder }}" + category: "ql-for-ql" - name: Copy sarif file to CWD - run: cp ../results/ql.sarif ./${{ matrix.folder }}.sarif + run: cp ../results/ql.sarif ./ql-for-ql.sarif + - name: Fixup the $scema in sarif # Until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part in a stable release + run: | + sed -i 's/\$schema.*/\$schema": "https:\/\/raw.githubusercontent.com\/oasis-tcs\/sarif-spec\/master\/Schemata\/sarif-schema-2.1.0",/' ql-for-ql.sarif - name: Sarif as artifact uses: actions/upload-artifact@v3 with: - name: ${{ matrix.folder }}.sarif - path: ${{ matrix.folder }}.sarif - + name: ql-for-ql.sarif + path: ql-for-ql.sarif + - name: Split out the sarif file into langs + run: | + mkdir split-sarif + node ./ql/scripts/split-sarif.js ql-for-ql.sarif split-sarif + - name: Upload langs as artifacts + uses: actions/upload-artifact@v3 + with: + name: ql-for-ql-langs + path: split-sarif + retention-days: 1 \ No newline at end of file diff --git a/.github/workflows/ql-for-ql-dataset_measure.yml b/.github/workflows/ql-for-ql-dataset_measure.yml index cf3b696f3b8..a5ed2e9b266 100644 --- a/.github/workflows/ql-for-ql-dataset_measure.yml +++ b/.github/workflows/ql-for-ql-dataset_measure.yml @@ -36,7 +36,7 @@ jobs: ql/target key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }} - name: Build Extractor - run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./create-extractor-pack.sh + run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./scripts/create-extractor-pack.sh env: CODEQL: ${{ steps.find-codeql.outputs.codeql-path }} - name: Checkout ${{ matrix.repo }} diff --git a/.github/workflows/ql-for-ql-tests.yml b/.github/workflows/ql-for-ql-tests.yml index 3b0a4963b79..b016f21f2b9 100644 --- a/.github/workflows/ql-for-ql-tests.yml +++ b/.github/workflows/ql-for-ql-tests.yml @@ -36,7 +36,7 @@ jobs: run: | cd ql; codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }}); - env "PATH=$PATH:$codeqlpath" ./create-extractor-pack.sh + env "PATH=$PATH:$codeqlpath" ./scripts/create-extractor-pack.sh - name: Run QL tests run: | "${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ql/extractor-pack" --consistency-queries ql/ql/consistency-queries ql/ql/test diff --git a/.github/workflows/query-list.yml b/.github/workflows/query-list.yml index 9416b740c99..0cf1cf30422 100644 --- a/.github/workflows/query-list.yml +++ b/.github/workflows/query-list.yml @@ -10,6 +10,7 @@ on: pull_request: paths: - '.github/workflows/query-list.yml' + - '.github/actions/fetch-codeql' - 'misc/scripts/generate-code-scanning-query-list.py' jobs: @@ -29,8 +30,6 @@ jobs: - name: Download CodeQL CLI # Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo uses: ./codeql/.github/actions/fetch-codeql - - name: Unzip CodeQL CLI - run: unzip -d codeql-cli codeql-linux64.zip - name: Build code scanning query list run: | python codeql/misc/scripts/generate-code-scanning-query-list.py > code-scanning-query-list.csv diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index c402312db0e..2f7464e47b3 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -5,6 +5,7 @@ on: paths: - "ruby/**" - .github/workflows/ruby-build.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main @@ -13,6 +14,7 @@ on: paths: - "ruby/**" - .github/workflows/ruby-build.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main @@ -90,19 +92,14 @@ jobs: steps: - uses: actions/checkout@v3 - name: Fetch CodeQL - run: | - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST" - unzip -q codeql-linux64.zip - env: - GITHUB_TOKEN: ${{ github.token }} + uses: ./.github/actions/fetch-codeql - name: Build Query Pack run: | - codeql/codeql pack create ql/lib --output target/packs - codeql/codeql pack install ql/src - codeql/codeql pack create ql/src --output target/packs + codeql pack create ql/lib --output target/packs + codeql pack install ql/src + codeql pack create ql/src --output target/packs PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*) - codeql/codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src + 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}/{}" \;) - uses: actions/upload-artifact@v3 with: @@ -179,19 +176,15 @@ jobs: runs-on: ${{ matrix.os }} needs: [package] steps: + - uses: actions/checkout@v3 + - name: Fetch CodeQL + uses: ./.github/actions/fetch-codeql + - uses: actions/checkout@v3 with: repository: Shopify/example-ruby-app ref: 67a0decc5eb550f3a9228eda53925c3afd40dfe9 - - name: Fetch CodeQL - shell: bash - run: | - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql.zip "$LATEST" - unzip -q codeql.zip - env: - GITHUB_TOKEN: ${{ github.token }} - working-directory: ${{ runner.temp }} + - name: Download Ruby bundle uses: actions/download-artifact@v3 with: @@ -215,12 +208,12 @@ jobs: - name: Run QL test shell: bash run: | - "${{ runner.temp }}/codeql/codeql" test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" . + codeql test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" . - name: Create database shell: bash run: | - "${{ runner.temp }}/codeql/codeql" database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root . ../database + codeql database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root . ../database - name: Analyze database shell: bash run: | - "${{ runner.temp }}/codeql/codeql" database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls + codeql database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index 0cf8860d8f1..e5eb7e05ecd 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -5,6 +5,7 @@ on: paths: - "ruby/**" - .github/workflows/ruby-qltest.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main @@ -13,6 +14,7 @@ on: paths: - "ruby/**" - .github/workflows/ruby-qltest.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main diff --git a/.github/workflows/swift-codegen.yml b/.github/workflows/swift-codegen.yml index 46a27709717..665ee55a247 100644 --- a/.github/workflows/swift-codegen.yml +++ b/.github/workflows/swift-codegen.yml @@ -5,6 +5,7 @@ on: paths: - "swift/**" - .github/workflows/swift-codegen.yml + - .github/actions/fetch-codeql branches: - main diff --git a/.github/workflows/swift-integration-tests.yml b/.github/workflows/swift-integration-tests.yml new file mode 100644 index 00000000000..cc365809c73 --- /dev/null +++ b/.github/workflows/swift-integration-tests.yml @@ -0,0 +1,35 @@ +name: "Swift: Run Integration Tests" + +on: + pull_request: + paths: + - "swift/**" + - .github/workflows/swift-integration-tests.yml + - .github/actions/fetch-codeql + - codeql-workspace.yml + branches: + - main +defaults: + run: + working-directory: swift + +jobs: + integration-tests: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + - ubuntu-20.04 +# - macos-latest TODO + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/fetch-codeql + - uses: bazelbuild/setup-bazelisk@v2 + - uses: actions/setup-python@v3 + - name: Build Swift extractor + run: | + bazel run //swift:create-extractor-pack + - name: Run integration tests + run: | + python integration-tests/runner.py diff --git a/.github/workflows/swift-qltest.yml b/.github/workflows/swift-qltest.yml index 915e1f331a5..76a21b0bd8a 100644 --- a/.github/workflows/swift-qltest.yml +++ b/.github/workflows/swift-qltest.yml @@ -5,6 +5,7 @@ on: paths: - "swift/**" - .github/workflows/swift-qltest.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main diff --git a/.github/workflows/validate-change-notes.yml b/.github/workflows/validate-change-notes.yml index 798913746be..b06167ea905 100644 --- a/.github/workflows/validate-change-notes.yml +++ b/.github/workflows/validate-change-notes.yml @@ -5,6 +5,7 @@ on: paths: - "*/ql/*/change-notes/**/*" - ".github/workflows/validate-change-notes.yml" + - ".github/actions/fetch-codeql" branches: - main - "rc/*" @@ -12,6 +13,7 @@ on: paths: - "*/ql/*/change-notes/**/*" - ".github/workflows/validate-change-notes.yml" + - ".github/actions/fetch-codeql" jobs: check-change-note: diff --git a/CODEOWNERS b/CODEOWNERS index da71d1ec5d8..1754d58af63 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -42,3 +42,4 @@ WORKSPACE.bazel @github/codeql-ci-reviewers /.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers /.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers /.github/workflows/ruby-* @github/codeql-ruby +/.github/workflows/swift-* @github/codeql-c diff --git a/config/identical-files.json b/config/identical-files.json index 77e39399cec..990ba49f033 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -453,11 +453,11 @@ "python/ql/src/Lexical/CommentedOutCodeReferences.inc.qhelp" ], "IDE Contextual Queries": [ - "cpp/ql/src/IDEContextual.qll", - "csharp/ql/src/IDEContextual.qll", - "java/ql/src/IDEContextual.qll", - "javascript/ql/src/IDEContextual.qll", - "python/ql/src/analysis/IDEContextual.qll" + "cpp/ql/lib/IDEContextual.qll", + "csharp/ql/lib/IDEContextual.qll", + "java/ql/lib/IDEContextual.qll", + "javascript/ql/lib/IDEContextual.qll", + "python/ql/lib/analysis/IDEContextual.qll" ], "SSA C#": [ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll", diff --git a/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/exprs.ql b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/exprs.ql new file mode 100644 index 00000000000..d00685e7cc6 --- /dev/null +++ b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/exprs.ql @@ -0,0 +1,17 @@ +class Expr extends @expr { + string toString() { none() } +} + +class Location extends @location_expr { + string toString() { none() } +} + +predicate isExprWithNewBuiltin(Expr expr) { + exists(int kind | exprs(expr, kind, _) | 330 <= kind and kind <= 334) +} + +from Expr expr, int kind, int kind_new, Location location +where + exprs(expr, kind, location) and + if isExprWithNewBuiltin(expr) then kind_new = 0 else kind_new = kind +select expr, kind_new, location diff --git a/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/old.dbscheme b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/old.dbscheme new file mode 100644 index 00000000000..23f7cbb88a4 --- /dev/null +++ b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/old.dbscheme @@ -0,0 +1,2125 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * 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: + * + * gcc -c f1.c f2.c f3.c + */ + 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 + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#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 + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_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( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int 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 +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: 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 +); + +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 +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target 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; diff --git a/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/semmlecode.cpp.dbscheme b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..19e31bf071f --- /dev/null +++ b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/semmlecode.cpp.dbscheme @@ -0,0 +1,2115 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * 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: + * + * gcc -c f1.c f2.c f3.c + */ + 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 + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#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 + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_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( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int 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 +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: 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 +); + +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 +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target 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; diff --git a/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/upgrade.properties b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/upgrade.properties new file mode 100644 index 00000000000..d697a16a42f --- /dev/null +++ b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/upgrade.properties @@ -0,0 +1,3 @@ +description: Add new builtin operations +compatibility: partial +exprs.rel: run exprs.qlo diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 52dd2c7a843..75a047d6f64 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,19 @@ +## 0.3.1 + +### Minor Analysis Improvements + +* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the C++ logical "and", and variable declarations in conditions. + +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + +### Bug Fixes + +* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`. + ## 0.2.3 ### New Features diff --git a/cpp/ql/src/IDEContextual.qll b/cpp/ql/lib/IDEContextual.qll similarity index 100% rename from cpp/ql/src/IDEContextual.qll rename to cpp/ql/lib/IDEContextual.qll diff --git a/cpp/ql/lib/change-notes/2022-05-30-braced-initializers.md b/cpp/ql/lib/change-notes/2022-05-30-braced-initializers.md deleted file mode 100644 index 8a31f06ab98..00000000000 --- a/cpp/ql/lib/change-notes/2022-05-30-braced-initializers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization. diff --git a/cpp/ql/lib/change-notes/2022-06-22-class-declaration-entry-fix.md b/cpp/ql/lib/change-notes/2022-06-22-class-declaration-entry-fix.md deleted file mode 100644 index fb301705e79..00000000000 --- a/cpp/ql/lib/change-notes/2022-06-22-class-declaration-entry-fix.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: fix ---- -* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`. diff --git a/cpp/ql/lib/change-notes/2022-06-24-unique-variable.md b/cpp/ql/lib/change-notes/2022-06-24-unique-variable.md new file mode 100644 index 00000000000..e04dde1290a --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-06-24-unique-variable.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Under certain circumstances a variable declaration that is not also a definition could be associated with a `Variable` that did not have the definition as a `VariableDeclarationEntry`. This is now fixed, and a unique `Variable` will exist that has both the declaration and the definition as a `VariableDeclarationEntry`. diff --git a/cpp/ql/lib/change-notes/2022-07-26-additional-builtin-support.md b/cpp/ql/lib/change-notes/2022-07-26-additional-builtin-support.md new file mode 100644 index 00000000000..2e4d7db69a5 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-07-26-additional-builtin-support.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Added subclasses of `BuiltInOperations` for `__builtin_bit_cast`, `__builtin_shuffle`, `__has_unique_object_representations`, `__is_aggregate`, and `__is_assignable`. diff --git a/cpp/ql/lib/change-notes/released/0.3.0.md b/cpp/ql/lib/change-notes/released/0.3.0.md new file mode 100644 index 00000000000..8c45dc21817 --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.3.0.md @@ -0,0 +1,9 @@ +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + +### Bug Fixes + +* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`. diff --git a/cpp/ql/lib/change-notes/released/0.3.1.md b/cpp/ql/lib/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..d5b251c42ab --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.3.1.md @@ -0,0 +1,5 @@ +## 0.3.1 + +### Minor Analysis Improvements + +* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the C++ logical "and", and variable declarations in conditions. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 0b605901b42..bb106b1cb63 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.3 +lastReleaseVersion: 0.3.1 diff --git a/cpp/ql/src/definitions.qll b/cpp/ql/lib/definitions.qll similarity index 100% rename from cpp/ql/src/definitions.qll rename to cpp/ql/lib/definitions.qll diff --git a/cpp/ql/src/localDefinitions.ql b/cpp/ql/lib/localDefinitions.ql similarity index 100% rename from cpp/ql/src/localDefinitions.ql rename to cpp/ql/lib/localDefinitions.ql diff --git a/cpp/ql/src/localReferences.ql b/cpp/ql/lib/localReferences.ql similarity index 100% rename from cpp/ql/src/localReferences.ql rename to cpp/ql/lib/localReferences.ql diff --git a/cpp/ql/src/printAst.ql b/cpp/ql/lib/printAst.ql similarity index 100% rename from cpp/ql/src/printAst.ql rename to cpp/ql/lib/printAst.ql diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 28cddcb3b00..ce90251f83f 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.3.0-dev +version: 0.3.2-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/lib/semmle/code/cpp/Element.qll b/cpp/ql/lib/semmle/code/cpp/Element.qll index 9e4ef7f5f8d..79df774d80f 100644 --- a/cpp/ql/lib/semmle/code/cpp/Element.qll +++ b/cpp/ql/lib/semmle/code/cpp/Element.qll @@ -6,6 +6,7 @@ import semmle.code.cpp.Location private import semmle.code.cpp.Enclosing private import semmle.code.cpp.internal.ResolveClass +private import semmle.code.cpp.internal.ResolveGlobalVariable /** * Get the `Element` that represents this `@element`. @@ -28,9 +29,12 @@ Element mkElement(@element e) { unresolveElement(result) = e } pragma[inline] @element unresolveElement(Element e) { not result instanceof @usertype and + not result instanceof @variable and result = e or e = resolveClass(result) + or + e = resolveGlobalVariable(result) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/Variable.qll b/cpp/ql/lib/semmle/code/cpp/Variable.qll index 2e3d6bf3ca2..7e188980b9c 100644 --- a/cpp/ql/lib/semmle/code/cpp/Variable.qll +++ b/cpp/ql/lib/semmle/code/cpp/Variable.qll @@ -6,6 +6,7 @@ import semmle.code.cpp.Element import semmle.code.cpp.exprs.Access import semmle.code.cpp.Initializer private import semmle.code.cpp.internal.ResolveClass +private import semmle.code.cpp.internal.ResolveGlobalVariable /** * A C/C++ variable. For example, in the following code there are four @@ -32,6 +33,8 @@ private import semmle.code.cpp.internal.ResolveClass * can have multiple declarations. */ class Variable extends Declaration, @variable { + Variable() { isVariable(underlyingElement(this)) } + override string getAPrimaryQlClass() { result = "Variable" } /** Gets the initializer of this variable, if any. */ diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll index 40c975873b4..0fb46f75c94 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll @@ -46,7 +46,7 @@ predicate nullCheckExpr(Expr checkExpr, Variable var) { or exists(LogicalAndExpr op, AnalysedExpr child | expr = op and - op.getRightOperand() = child and + op.getAnOperand() = child and nullCheckExpr(child, v) ) or @@ -99,7 +99,7 @@ predicate validCheckExpr(Expr checkExpr, Variable var) { or exists(LogicalAndExpr op, AnalysedExpr child | expr = op and - op.getRightOperand() = child and + op.getAnOperand() = child and validCheckExpr(child, v) ) or @@ -169,7 +169,10 @@ class AnalysedExpr extends Expr { */ predicate isDef(LocalScopeVariable v) { this.inCondition() and - this.(Assignment).getLValue() = v.getAnAccess() + ( + this.(Assignment).getLValue() = v.getAnAccess() or + this.(ConditionDeclExpr).getVariableAccess() = v.getAnAccess() + ) } /** 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll index 309d98cd694..979c9c03940 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -1,5 +1,5 @@ /** - * Provides classes for modeling built-in operations. Built-in operations are + * Provides classes for modeling built-in operations. Built-in operations are * typically compiler specific and are used by libraries and generated code. */ @@ -120,8 +120,8 @@ class BuiltInNoOp extends BuiltInOperation, @noopexpr { /** * A C/C++ `__builtin_offsetof` built-in operation (used by some implementations - * of `offsetof`). The operation retains its semantics even in the presence - * of an overloaded `operator &`). This is a GNU/Clang extension. + * of `offsetof`). The operation retains its semantics even in the presence + * of an overloaded `operator &`). This is a gcc/clang extension. * ``` * struct S { * int a, b; @@ -137,8 +137,8 @@ class BuiltInOperationBuiltInOffsetOf extends BuiltInOperation, @offsetofexpr { /** * A C/C++ `__INTADDR__` built-in operation (used by some implementations - * of `offsetof`). The operation retains its semantics even in the presence - * of an overloaded `operator &`). This is an EDG extension. + * of `offsetof`). The operation retains its semantics even in the presence + * of an overloaded `operator &`). This is an EDG extension. * ``` * struct S { * int a, b; @@ -173,7 +173,7 @@ class BuiltInOperationHasAssign extends BuiltInOperation, @hasassignexpr { * * Returns `true` if the type has a copy constructor. * ``` - * std::integral_constant< bool, __has_copy(_Tp)> hc; + * std::integral_constant hc; * ``` */ class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr { @@ -189,7 +189,7 @@ class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr { * Returns `true` if a copy assignment operator has an empty exception * specification. * ``` - * std::integral_constant< bool, __has_nothrow_assign(_Tp)> hnta; + * std::integral_constant hnta; * ``` */ class BuiltInOperationHasNoThrowAssign extends BuiltInOperation, @hasnothrowassign { @@ -220,7 +220,7 @@ class BuiltInOperationHasNoThrowConstructor extends BuiltInOperation, @hasnothro * * Returns `true` if the copy constructor has an empty exception specification. * ``` - * std::integral_constant< bool, __has_nothrow_copy(MyType) >; + * std::integral_constant; * ``` */ class BuiltInOperationHasNoThrowCopy extends BuiltInOperation, @hasnothrowcopy { @@ -266,7 +266,7 @@ class BuiltInOperationHasTrivialConstructor extends BuiltInOperation, @hastrivia * * Returns true if the type has a trivial copy constructor. * ``` - * std::integral_constant< bool, __has_trivial_copy(MyType) > htc; + * std::integral_constant htc; * ``` */ class BuiltInOperationHasTrivialCopy extends BuiltInOperation, @hastrivialcopy { @@ -468,7 +468,7 @@ class BuiltInOperationIsUnion extends BuiltInOperation, @isunionexpr { * ``` * template * struct types_compatible - * : public integral_constant + * : public integral_constant * { }; * ``` */ @@ -479,8 +479,7 @@ class BuiltInOperationBuiltInTypesCompatibleP extends BuiltInOperation, @typesco /** * A clang `__builtin_shufflevector` expression. * - * It outputs a permutation of elements from one or two input vectors. - * Please see + * It outputs a permutation of elements from one or two input vectors. See * https://releases.llvm.org/3.7.0/tools/clang/docs/LanguageExtensions.html#langext-builtin-shufflevector * for more information. * ``` @@ -494,11 +493,29 @@ class BuiltInOperationBuiltInShuffleVector extends BuiltInOperation, @builtinshu override string getAPrimaryQlClass() { result = "BuiltInOperationBuiltInShuffleVector" } } +/** + * A gcc `__builtin_shuffle` expression. + * + * It outputs a permutation of elements from one or two input vectors. + * See https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html + * for more information. + * ``` + * // Concatenate every other element of 4-element vectors V1 and V2. + * M = {0, 2, 4, 6}; + * V3 = __builtin_shuffle(V1, V2, M); + * ``` + */ +class BuiltInOperationBuiltInShuffle extends BuiltInOperation, @builtinshuffle { + override string toString() { result = "__builtin_shuffle" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationBuiltInShuffle" } +} + /** * A clang `__builtin_convertvector` expression. * * Allows for conversion of vectors of equal element count and compatible - * element types. Please see + * element types. See * https://releases.llvm.org/3.7.0/tools/clang/docs/LanguageExtensions.html#builtin-convertvector * for more information. * ``` @@ -547,7 +564,7 @@ class BuiltInOperationBuiltInAddressOf extends UnaryOperation, BuiltInOperation, * ``` * template * struct is_trivially_constructible - * : public integral_constant + * : public integral_constant * { }; * ``` */ @@ -612,13 +629,10 @@ class BuiltInOperationIsTriviallyDestructible extends BuiltInOperation, @istrivi * The `__is_trivially_assignable` built-in operation (used by some * implementations of the `` header). * - * Returns `true` if the assignment operator `C::operator =(const C& c)` is - * trivial. + * Returns `true` if the assignment operator `C::operator =(const D& d)` is + * trivial (i.e., it will not call any operation that is non-trivial). * ``` - * template - * struct is_trivially_assignable - * : public integral_constant - * { }; + * bool v = __is_trivially_assignable(MyType1, MyType2); * ``` */ class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istriviallyassignableexpr { @@ -631,10 +645,10 @@ class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istrivial * The `__is_nothrow_assignable` built-in operation (used by some * implementations of the `` header). * - * Returns true if there exists a `C::operator =(const C& c) nothrow` + * Returns true if there exists a `C::operator =(const D& d) nothrow` * assignment operator (i.e, with an empty exception specification). * ``` - * bool v = __is_nothrow_assignable(MyType); + * bool v = __is_nothrow_assignable(MyType1, MyType2); * ``` */ class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowassignableexpr { @@ -643,15 +657,30 @@ class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowas override string getAPrimaryQlClass() { result = "BuiltInOperationIsNothrowAssignable" } } +/** + * The `__is_assignable` built-in operation (used by some implementations + * of the `` header). + * + * Returns true if there exists a `C::operator =(const D& d)` assignment + * operator. + * ``` + * bool v = __is_assignable(MyType1, MyType2); + * ``` + */ +class BuiltInOperationIsAssignable extends BuiltInOperation, @isassignable { + override string toString() { result = "__is_assignable" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationIsAssignable" } +} + /** * The `__is_standard_layout` built-in operation (used by some implementations * of the `` header). * * Returns `true` if the type is a primitive type, or a `class`, `struct` or - * `union` WITHOUT (1) virtual functions or base classes, (2) reference member - * variable or (3) multiple occurrences of base `class` objects, among other - * restrictions. Please see - * https://en.cppreference.com/w/cpp/named_req/StandardLayoutType + * `union` without (1) virtual functions or base classes, (2) reference member + * variable, or (3) multiple occurrences of base `class` objects, among other + * restrictions. See https://en.cppreference.com/w/cpp/named_req/StandardLayoutType * for more information. * ``` * bool v = __is_standard_layout(MyType); @@ -668,7 +697,7 @@ class BuiltInOperationIsStandardLayout extends BuiltInOperation, @isstandardlayo * implementations of the `` header). * * Returns `true` if instances of this type can be copied by trivial - * means. The copying is done in a manner similar to the `memcpy` + * means. The copying is done in a manner similar to the `memcpy` * function. */ class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istriviallycopyableexpr { @@ -682,13 +711,13 @@ class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istrivially * the `` header). * * Returns `true` if the type is a scalar type, a reference type or an array of - * literal types, among others. Please see + * literal types, among others. See * https://en.cppreference.com/w/cpp/named_req/LiteralType * for more information. * * ``` * template - * std::integral_constant< bool, __is_literal_type(_Tp)> ilt; + * std::integral_constant ilt; * ``` */ class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr { @@ -705,7 +734,7 @@ class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr * compiler, with semantics of the `memcpy` operation. * ``` * template - * std::integral_constant< bool, __has_trivial_move_constructor(_Tp)> htmc; + * std::integral_constant htmc; * ``` */ class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation, @@ -723,7 +752,7 @@ class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation, * ``` * template * struct has_trivial_move_assign - * : public integral_constant + * : public integral_constant * { }; * ``` */ @@ -758,7 +787,7 @@ class BuiltInOperationHasNothrowMoveAssign extends BuiltInOperation, @hasnothrow * ``` * template * struct is_constructible - * : public integral_constant + * : public integral_constant * { }; * ``` */ @@ -785,7 +814,7 @@ class BuiltInOperationIsNothrowConstructible extends BuiltInOperation, @isnothro } /** - * The `__has_finalizer` built-in operation. This is a Microsoft extension. + * The `__has_finalizer` built-in operation. This is a Microsoft extension. * * Returns `true` if the type defines a _finalizer_ `C::!C(void)`, to be called * from either the regular destructor or the garbage collector. @@ -800,10 +829,10 @@ class BuiltInOperationHasFinalizer extends BuiltInOperation, @hasfinalizerexpr { } /** - * The `__is_delegate` built-in operation. This is a Microsoft extension. + * The `__is_delegate` built-in operation. This is a Microsoft extension. * * Returns `true` if the function has been declared as a `delegate`, used in - * message forwarding. Please see + * message forwarding. See * https://docs.microsoft.com/en-us/cpp/extensions/delegate-cpp-component-extensions * for more information. */ @@ -814,9 +843,9 @@ class BuiltInOperationIsDelegate extends BuiltInOperation, @isdelegateexpr { } /** - * The `__is_interface_class` built-in operation. This is a Microsoft extension. + * The `__is_interface_class` built-in operation. This is a Microsoft extension. * - * Returns `true` if the type has been declared as an `interface`. Please see + * Returns `true` if the type has been declared as an `interface`. See * https://docs.microsoft.com/en-us/cpp/extensions/interface-class-cpp-component-extensions * for more information. */ @@ -827,9 +856,9 @@ class BuiltInOperationIsInterfaceClass extends BuiltInOperation, @isinterfacecla } /** - * The `__is_ref_array` built-in operation. This is a Microsoft extension. + * The `__is_ref_array` built-in operation. This is a Microsoft extension. * - * Returns `true` if the object passed in is a _platform array_. Please see + * Returns `true` if the object passed in is a _platform array_. See * https://docs.microsoft.com/en-us/cpp/extensions/arrays-cpp-component-extensions * for more information. * ``` @@ -844,9 +873,9 @@ class BuiltInOperationIsRefArray extends BuiltInOperation, @isrefarrayexpr { } /** - * The `__is_ref_class` built-in operation. This is a Microsoft extension. + * The `__is_ref_class` built-in operation. This is a Microsoft extension. * - * Returns `true` if the type is a _reference class_. Please see + * Returns `true` if the type is a _reference class_. See * https://docs.microsoft.com/en-us/cpp/extensions/classes-and-structs-cpp-component-extensions * for more information. * ``` @@ -861,10 +890,10 @@ class BuiltInOperationIsRefClass extends BuiltInOperation, @isrefclassexpr { } /** - * The `__is_sealed` built-in operation. This is a Microsoft extension. + * The `__is_sealed` built-in operation. This is a Microsoft extension. * * Returns `true` if a given class or virtual function is marked as `sealed`, - * meaning that it cannot be extended or overridden. The `sealed` keyword + * meaning that it cannot be extended or overridden. The `sealed` keyword * is similar to the C++11 `final` keyword. * ``` * ref class X sealed { @@ -879,7 +908,7 @@ class BuiltInOperationIsSealed extends BuiltInOperation, @issealedexpr { } /** - * The `__is_simple_value_class` built-in operation. This is a Microsoft extension. + * The `__is_simple_value_class` built-in operation. This is a Microsoft extension. * * Returns `true` if passed a value type that contains no references to the * garbage-collected heap. @@ -898,9 +927,9 @@ class BuiltInOperationIsSimpleValueClass extends BuiltInOperation, @issimplevalu } /** - * The `__is_value_class` built-in operation. This is a Microsoft extension. + * The `__is_value_class` built-in operation. This is a Microsoft extension. * - * Returns `true` if passed a value type. Please see + * Returns `true` if passed a value type. See * https://docs.microsoft.com/en-us/cpp/extensions/classes-and-structs-cpp-component-extensions * For more information. * ``` @@ -922,7 +951,7 @@ class BuiltInOperationIsValueClass extends BuiltInOperation, @isvalueclassexpr { * ``` * template * struct is_final - * : public integral_constant + * : public integral_constant * { }; * ``` */ @@ -933,7 +962,7 @@ class BuiltInOperationIsFinal extends BuiltInOperation, @isfinalexpr { } /** - * The `__builtin_choose_expr` expression. This is a GNU/Clang extension. + * The `__builtin_choose_expr` expression. This is a gcc/clang extension. * * The expression functions similarly to the ternary `?:` operator, except * that it is evaluated at compile-time. @@ -978,3 +1007,50 @@ class BuiltInComplexOperation extends BuiltInOperation, @builtincomplex { /** Gets the operand corresponding to the imaginary part of the complex number. */ Expr getImaginaryOperand() { this.hasChild(result, 1) } } + +/** + * A C++ `__is_aggregate` built-in operation (used by some implementations of the + * `` header). + * + * Returns `true` if the type has is an aggregate type. + * ``` + * std::integral_constant ia; + * ``` + */ +class BuiltInOperationIsAggregate extends BuiltInOperation, @isaggregate { + override string toString() { result = "__is_aggregate" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationIsAggregate" } +} + +/** + * A C++ `__has_unique_object_representations` built-in operation (used by some + * implementations of the `` header). + * + * Returns `true` if the type is trivially copyable and if the object representation + * is unique for two objects with the same value. + * ``` + * bool v = __has_unique_object_representations(MyType); + * ``` + */ +class BuiltInOperationHasUniqueObjectRepresentations extends BuiltInOperation, + @hasuniqueobjectrepresentations { + override string toString() { result = "__has_unique_object_representations" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationHasUniqueObjectRepresentations" } +} + +/** + * A C/C++ `__builtin_bit_cast` built-in operation (used by some implementations + * of `std::bit_cast`). + * + * Performs a bit cast from a value to a type. + * ``` + * __builtin_bit_cast(Type, value); + * ``` + */ +class BuiltInBitCast extends BuiltInOperation, @builtinbitcast { + override string toString() { result = "__builtin_bit_cast" } + + override string getAPrimaryQlClass() { result = "BuiltInBitCast" } +} diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll index 7ceda8ddbff..dba3d16997f 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll @@ -255,8 +255,10 @@ class FunctionCall extends Call, @funbindexpr { /** * Gets the function called by this call. * - * In the case of virtual function calls, the result is the most-specific function in the override tree (as - * determined by the compiler) such that the target at runtime will be one of `result.getAnOverridingFunction*()`. + * In the case of virtual function calls, the result is the most-specific function in the override tree + * such that the target at runtime will be one of `result.getAnOverridingFunction*()`. The most-specific + * function is determined by the compiler based on the compile time type of the object the function is a + * member of. */ override Function getTarget() { funbind(underlyingElement(this), unresolveElement(result)) } diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll index 55a59cc9588..68973293425 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll @@ -596,9 +596,12 @@ class ParenthesisExpr extends Conversion, @parexpr { } /** - * A C/C++ expression that has not been resolved. + * A C/C++ expression that could not be resolved, or that can no longer be + * represented due to a database upgrade or downgrade. * - * It is assigned `ErroneousType` as its type. + * If the expression could not be resolved, it has type `ErroneousType`. In the + * case of a database upgrade or downgrade, the original type from before the + * upgrade or downgrade is kept if that type can be represented. */ class ErrorExpr extends Expr, @errorexpr { override string toString() { result = "" } diff --git a/cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll b/cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll new file mode 100644 index 00000000000..c11e1457dae --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll @@ -0,0 +1,57 @@ +private predicate hasDefinition(@globalvariable g) { + exists(@var_decl vd | var_decls(vd, g, _, _, _) | var_def(vd)) +} + +private predicate onlyOneCompleteGlobalVariableExistsWithMangledName(@mangledname name) { + strictcount(@globalvariable g | hasDefinition(g) and mangled_name(g, name)) = 1 +} + +/** Holds if `g` is a unique global variable with a definition named `name`. */ +private predicate isGlobalWithMangledNameAndWithDefinition(@mangledname name, @globalvariable g) { + hasDefinition(g) and + mangled_name(g, name) and + onlyOneCompleteGlobalVariableExistsWithMangledName(name) +} + +/** Holds if `g` is a global variable without a definition named `name`. */ +private predicate isGlobalWithMangledNameAndWithoutDefinition(@mangledname name, @globalvariable g) { + not hasDefinition(g) and + mangled_name(g, name) +} + +/** + * Holds if `incomplete` is a global variable without a definition, and there exists + * a unique global variable `complete` with the same name that does have a definition. + */ +private predicate hasTwinWithDefinition(@globalvariable incomplete, @globalvariable complete) { + exists(@mangledname name | + not variable_instantiation(incomplete, complete) and + isGlobalWithMangledNameAndWithoutDefinition(name, incomplete) and + isGlobalWithMangledNameAndWithDefinition(name, complete) + ) +} + +import Cached + +cached +private module Cached { + /** + * If `v` is a global variable without a definition, and there exists a unique + * global variable with the same name that does have a definition, then the + * result is that unique global variable. Otherwise, the result is `v`. + */ + cached + @variable resolveGlobalVariable(@variable v) { + hasTwinWithDefinition(v, result) + or + not hasTwinWithDefinition(v, _) and + result = v + } + + cached + predicate isVariable(@variable v) { + not v instanceof @globalvariable + or + v = resolveGlobalVariable(_) + } +} 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 7b9e78d2c4b..a076f7a2e45 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 @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 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 @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 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 @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 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 @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index 19e31bf071f..23f7cbb88a4 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -1650,6 +1650,11 @@ case @expr.kind of | 327 = @co_await | 328 = @co_yield | 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle ; @var_args_expr = @vastartexpr @@ -1711,6 +1716,11 @@ case @expr.kind of | @isfinalexpr | @builtinchooseexpr | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle ; new_allocated_type( diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index e439c5ac624..35eb9c7e6de 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -2,79 +2,79 @@ @compilation - 9980 + 9978 @externalDataElement 65 - - @svnentry - 575525 - @external_package 4 + + @svnentry + 575525 + @location_stmt - 3805462 + 3805465 @diagnostic - 582773 + 72312 @file - 124189 + 124196 @folder 15994 - @location_expr - 13128112 + @location_default + 30132211 - @location_default - 30128761 + @location_expr + 13128120 @macroinvocation - 33894981 + 33889080 @function - 4726273 + 4726519 @fun_decl - 5096962 + 5097227 @type_decl - 3283977 + 3284148 @namespace_decl - 306972 + 306973 @using - 374921 + 374941 @static_assert - 130417 + 130418 @var_decl - 8543232 + 8543677 @parameter - 6660155 + 6660502 @membervariable @@ -82,7 +82,7 @@ @globalvariable - 300708 + 318724 @localvariable @@ -94,55 +94,55 @@ @builtintype - 22109 + 22110 @derivedtype - 4413446 + 4413676 @decltype - 31047 + 31049 @usertype - 5342989 + 5343268 @mangledname - 1728010 + 1975901 @type_mention - 4011508 + 4011511 @routinetype - 546982 + 546661 @ptrtomember - 38103 + 38105 @specifier - 24932 + 24933 @gnuattribute - 664228 + 664262 @stdattribute - 468982 + 469081 @alignas - 8937 + 8938 @declspec - 238544 + 238545 @msattribute @@ -150,11 +150,11 @@ @attribute_arg_token - 25402 + 25403 @attribute_arg_constant - 326469 + 326486 @attribute_arg_type @@ -166,15 +166,15 @@ @derivation - 402388 + 402152 @frienddecl - 715075 + 714656 @comment - 8781270 + 8783134 @namespace @@ -186,23 +186,23 @@ @namequalifier - 1618961 + 1618866 @value - 10646146 + 10646153 @initialiser - 1731824 + 1732353 @lambdacapture - 28224 + 28226 @stmt_expr - 1480414 + 1480415 @stmt_if @@ -210,23 +210,23 @@ @stmt_while - 30207 + 30201 @stmt_label - 53046 + 53044 @stmt_return - 1306346 + 1306414 @stmt_block - 1446530 + 1446605 @stmt_end_test_while - 148604 + 148599 @stmt_for @@ -234,7 +234,7 @@ @stmt_switch_case - 191408 + 191399 @stmt_switch @@ -242,11 +242,11 @@ @stmt_try_block - 42701 + 42699 @stmt_decl - 608508 + 608387 @stmt_empty @@ -258,7 +258,7 @@ @stmt_break - 102231 + 102232 @stmt_range_based_for @@ -266,15 +266,15 @@ @stmt_handler - 59432 + 59429 @stmt_constexpr_if - 52551 + 52562 @stmt_goto - 110490 + 110487 @stmt_asm @@ -310,43 +310,43 @@ @ctordirectinit - 112813 + 112747 @ctorvirtualinit - 6534 + 6532 @ctorfieldinit - 200789 + 200671 @ctordelegatinginit - 3347 + 3345 @dtordirectdestruct - 41715 + 41690 @dtorvirtualdestruct - 4122 + 4119 @dtorfielddestruct - 41644 + 41620 @static_cast - 211821 + 211675 @reinterpret_cast - 30776 + 30783 @const_cast - 35278 + 35285 @dynamic_cast @@ -354,19 +354,19 @@ @c_style_cast - 4209393 + 4209396 @lambdaexpr - 21639 + 21640 @param_ref - 375289 + 375271 @errorexpr - 46823 + 46796 @address_of @@ -374,27 +374,27 @@ @reference_to - 1596143 + 1596067 @indirect - 292115 + 292106 @ref_indirect - 1934537 + 1938685 @array_to_pointer - 1424883 + 1424884 @vacuous_destructor_call - 8138 + 8133 @parexpr - 3572547 + 3572549 @arithnegexpr @@ -402,11 +402,11 @@ @complementexpr - 27787 + 27786 @notexpr - 277992 + 277993 @postincrexpr @@ -446,11 +446,11 @@ @remexpr - 15819 + 15810 @paddexpr - 86505 + 86502 @psubexpr @@ -458,7 +458,7 @@ @pdiffexpr - 35487 + 35495 @lshiftexpr @@ -490,11 +490,11 @@ @gtexpr - 100669 + 100674 @ltexpr - 106314 + 106319 @geexpr @@ -502,11 +502,11 @@ @leexpr - 212141 + 212134 @assignexpr - 933419 + 933420 @assignaddexpr @@ -518,7 +518,7 @@ @assignmulexpr - 7170 + 7168 @assigndivexpr @@ -546,7 +546,7 @@ @assignxorexpr - 21804 + 21803 @assignpaddexpr @@ -554,7 +554,7 @@ @andlogicalexpr - 249008 + 249009 @orlogicalexpr @@ -562,7 +562,7 @@ @commaexpr - 181539 + 181530 @subscriptexpr @@ -570,7 +570,7 @@ @callexpr - 309063 + 309079 @vastartexpr @@ -586,27 +586,27 @@ @varaccess - 6006364 + 6006368 @thisaccess - 1125914 + 1125919 @new_expr - 47598 + 47571 @delete_expr - 11732 + 11725 @throw_expr - 21765 + 21760 @condition_decl - 38595 + 38593 @braced_init_list @@ -614,7 +614,7 @@ @type_id - 36430 + 36408 @runtime_sizeof @@ -622,15 +622,15 @@ @runtime_alignof - 48550 + 48521 @sizeof_pack - 5644 + 5645 @routineexpr - 3047613 + 3047738 @type_operand @@ -642,7 +642,7 @@ @ispodexpr - 636 + 635 @hastrivialdestructor @@ -666,23 +666,23 @@ @isconstructibleexpr - 2721 + 2722 @isfinalexpr - 2093 + 2094 @noexceptexpr - 23574 + 23573 @builtinaddressof - 13282 + 13274 @temp_init - 760683 + 760646 @assume @@ -826,7 +826,7 @@ @typescompexpr - 562415 + 562416 @intaddrexpr @@ -846,7 +846,7 @@ @istriviallyconstructibleexpr - 2826 + 2827 @isdestructibleexpr @@ -866,7 +866,7 @@ @isnothrowassignableexpr - 2093 + 2094 @isstandardlayoutexpr @@ -890,7 +890,7 @@ @isnothrowconstructibleexpr - 4815 + 4816 @hasfinalizerexpr @@ -956,45 +956,65 @@ @co_yield 1 + + @isassignable + 2617 + + + @isaggregate + 2 + + + @hasuniqueobjectrepresentations + 2 + + + @builtinbitcast + 1 + + + @builtinshuffle + 1965 + @ppd_if - 672225 + 672260 @ppd_ifdef - 265314 + 265328 @ppd_ifndef - 268607 + 268621 @ppd_elif - 25402 + 25403 @ppd_else - 210746 + 210757 @ppd_endif - 1206147 + 1206210 @ppd_plain_include - 313767 + 313784 @ppd_define - 2435252 + 2435769 @ppd_undef - 262021 + 262035 @ppd_pragma - 312270 + 312337 @ppd_include_next @@ -1048,11 +1068,11 @@ compilations - 9980 + 9978 id - 9980 + 9978 cwd @@ -1070,7 +1090,7 @@ 1 2 - 9980 + 9978 @@ -1644,7 +1664,7 @@ seconds - 12490 + 9586 @@ -1725,48 +1745,48 @@ 3 4 - 198 + 715 4 5 - 795 + 278 - 5 - 9 + 6 + 8 159 - 9 + 8 + 10 + 159 + + + 10 11 - 119 + 79 11 12 - 198 - - - 13 - 18 159 - 18 - 22 + 17 + 19 + 159 + + + 20 + 27 + 159 + + + 40 + 77 119 - - 22 - 46 - 159 - - - 60 - 104 - 79 - @@ -1833,12 +1853,12 @@ 3 4 - 556 + 835 4 5 - 1233 + 914 5 @@ -1848,32 +1868,27 @@ 6 7 - 119 + 437 7 8 - 318 + 79 8 9 - 119 + 278 9 - 11 + 26 278 - 11 - 31 - 278 - - - 40 - 95 - 159 + 26 + 92 + 238 @@ -1919,18 +1934,23 @@ 12 - 4 - 5 - 79 - - - 152 - 153 + 3 + 4 39 - 160 - 161 + 4 + 5 + 39 + + + 112 + 113 + 39 + + + 129 + 130 39 @@ -1947,22 +1967,27 @@ 1 2 - 7875 + 5449 2 3 - 2704 + 1670 3 4 - 1312 + 1272 4 - 45 - 596 + 5 + 676 + + + 5 + 42 + 517 @@ -1978,27 +2003,32 @@ 1 2 - 6682 + 5091 2 3 - 3142 + 1392 3 4 - 1431 - - - 4 - 6 954 - 6 - 65 - 278 + 4 + 5 + 875 + + + 5 + 7 + 795 + + + 7 + 67 + 477 @@ -2014,12 +2044,12 @@ 1 2 - 12251 + 9307 2 3 - 238 + 278 @@ -2029,23 +2059,23 @@ diagnostic_for - 1031027 + 891808 diagnostic - 582773 + 72312 compilation - 1988 + 9585 file_number - 104 + 11 file_number_diagnostic_number - 104788 + 6856 @@ -2059,27 +2089,17 @@ 1 2 - 362937 + 9631 2 3 - 92540 + 59836 - 3 - 4 - 70033 - - - 4 - 6 - 47421 - - - 6 - 9 - 9840 + 254 + 825 + 2844 @@ -2095,7 +2115,7 @@ 1 2 - 582773 + 72312 @@ -2111,22 +2131,7 @@ 1 2 - 475263 - - - 2 - 3 - 50143 - - - 3 - 6 - 53702 - - - 6 - 7 - 3663 + 72312 @@ -2135,222 +2140,6 @@ compilation diagnostic - - - 12 - - - 32 - 33 - 104 - - - 37 - 38 - 104 - - - 77 - 78 - 104 - - - 78 - 79 - 104 - - - 155 - 156 - 104 - - - 359 - 360 - 104 - - - 418 - 419 - 104 - - - 436 - 437 - 104 - - - 509 - 510 - 104 - - - 571 - 572 - 104 - - - 639 - 640 - 104 - - - 756 - 757 - 628 - - - 1001 - 1002 - 209 - - - - - - - compilation - file_number - - - 12 - - - 1 - 2 - 1988 - - - - - - - compilation - file_number_diagnostic_number - - - 12 - - - 32 - 33 - 104 - - - 37 - 38 - 104 - - - 77 - 78 - 104 - - - 78 - 79 - 104 - - - 155 - 156 - 104 - - - 359 - 360 - 104 - - - 418 - 419 - 104 - - - 436 - 437 - 104 - - - 509 - 510 - 104 - - - 571 - 572 - 104 - - - 639 - 640 - 104 - - - 756 - 757 - 628 - - - 1001 - 1002 - 209 - - - - - - - file_number - diagnostic - - - 12 - - - 5567 - 5568 - 104 - - - - - - - file_number - compilation - - - 12 - - - 19 - 20 - 104 - - - - - - - file_number - file_number_diagnostic_number - - - 12 - - - 1001 - 1002 - 104 - - - - - - - file_number_diagnostic_number - diagnostic 12 @@ -2358,37 +2147,193 @@ 2 3 - 25647 + 57 7 8 - 10991 + 6093 8 9 - 13085 + 497 - 9 - 10 - 13608 + 247 + 248 + 1965 - 10 - 11 - 27741 + 263 + 444 + 763 - 11 - 12 - 5652 + 446 + 594 + 208 + + + + + + + compilation + file_number + + + 12 + + + 1 + 2 + 9585 + + + + + + + compilation + file_number_diagnostic_number + + + 12 + + + 2 + 3 + 57 - 12 - 15 - 8060 + 7 + 8 + 6093 + + + 8 + 9 + 497 + + + 247 + 248 + 1965 + + + 263 + 444 + 763 + + + 446 + 594 + 208 + + + + + + + file_number + diagnostic + + + 12 + + + 6254 + 6255 + 11 + + + + + + + file_number + compilation + + + 12 + + + 829 + 830 + 11 + + + + + + + file_number + file_number_diagnostic_number + + + 12 + + + 593 + 594 + 11 + + + + + + + file_number_diagnostic_number + diagnostic + + + 12 + + + 1 + 2 + 2821 + + + 2 + 5 + 601 + + + 5 + 6 + 1017 + + + 7 + 14 + 543 + + + 15 + 16 + 57 + + + 17 + 18 + 601 + + + 18 + 23 + 462 + + + 26 + 40 + 555 + + + 42 + 830 + 196 @@ -2402,49 +2347,54 @@ 12 - 2 - 3 - 25647 - - - 8 + 4 9 - 12247 - - - 9 - 10 - 7118 + 589 10 11 - 6490 - - - 11 - 13 - 9526 - - - 13 - 14 - 6176 + 1005 14 - 15 - 21355 + 27 + 543 - 15 - 16 - 8060 + 30 + 31 + 57 - 16 - 20 - 8165 + 34 + 35 + 601 + + + 36 + 45 + 462 + + + 52 + 79 + 555 + + + 84 + 85 + 185 + + + 254 + 255 + 2763 + + + 297 + 830 + 92 @@ -2460,7 +2410,7 @@ 1 2 - 104788 + 6856 @@ -2470,19 +2420,19 @@ compilation_finished - 9980 + 9978 id - 9980 + 9978 cpu_seconds - 7956 + 7850 elapsed_seconds - 138 + 161 @@ -2496,7 +2446,7 @@ 1 2 - 9980 + 9978 @@ -2512,7 +2462,7 @@ 1 2 - 9980 + 9978 @@ -2528,17 +2478,17 @@ 1 2 - 6777 + 6498 2 3 - 786 + 1005 3 - 17 - 393 + 15 + 346 @@ -2554,12 +2504,12 @@ 1 2 - 7505 + 7423 2 3 - 451 + 427 @@ -2572,10 +2522,15 @@ 12 + + 1 + 2 + 23 + 2 3 - 23 + 11 3 @@ -2583,43 +2538,43 @@ 23 - 9 - 10 + 8 + 9 + 23 + + + 11 + 12 11 - 14 - 15 + 24 + 25 11 - 22 - 23 + 49 + 50 11 - 37 - 38 + 104 + 105 11 - 144 - 145 + 155 + 156 11 - 162 - 163 + 239 + 240 11 - 222 - 223 - 11 - - - 243 - 244 + 255 + 256 11 @@ -2633,10 +2588,15 @@ 12 + + 1 + 2 + 23 + 2 3 - 23 + 11 3 @@ -2644,43 +2604,43 @@ 23 - 9 - 10 + 8 + 9 + 23 + + + 11 + 12 11 - 14 - 15 + 24 + 25 11 - 22 - 23 + 49 + 50 11 - 36 - 37 + 104 + 105 11 - 118 - 119 + 111 + 112 11 - 123 - 124 + 174 + 175 11 - 177 - 178 - 11 - - - 218 - 219 + 217 + 218 11 @@ -4405,31 +4365,31 @@ locations_default - 30128761 + 30132211 id - 30128761 + 30132211 container - 140184 + 140191 startLine - 2114992 + 2115102 startColumn - 37162 + 37164 endLine - 2117814 + 2117925 endColumn - 48452 + 48455 @@ -4443,7 +4403,7 @@ 1 2 - 30128761 + 30132211 @@ -4459,7 +4419,7 @@ 1 2 - 30128761 + 30132211 @@ -4475,7 +4435,7 @@ 1 2 - 30128761 + 30132211 @@ -4491,7 +4451,7 @@ 1 2 - 30128761 + 30132211 @@ -4507,7 +4467,7 @@ 1 2 - 30128761 + 30132211 @@ -4523,67 +4483,67 @@ 1 2 - 16464 + 16465 2 12 - 10819 + 10820 13 20 - 11760 + 11761 21 36 - 11289 + 11290 36 55 - 11289 + 11290 55 77 - 10819 + 10820 77 102 - 10819 + 10820 102 149 - 10819 + 10820 149 227 - 11289 + 11290 228 350 - 11289 + 10820 - 358 - 628 - 10819 + 351 + 604 + 10820 - 671 - 1926 - 10819 + 627 + 1479 + 10820 - 2168 + 1925 2380 - 1881 + 2352 @@ -4599,62 +4559,62 @@ 1 2 - 16464 + 16465 2 9 - 10819 + 10820 9 16 - 11760 + 11761 16 25 - 11289 + 11290 25 40 - 10819 + 10820 40 57 - 10819 + 10820 58 72 - 10819 + 10820 73 103 - 11289 + 11290 106 141 - 11760 + 11761 148 226 - 11289 + 11290 226 373 - 10819 + 10820 381 1456 - 10819 + 10820 1464 @@ -4675,62 +4635,62 @@ 1 2 - 16464 + 16465 2 4 - 8937 + 8938 4 5 - 7526 + 7527 5 6 - 7526 + 7527 6 8 - 11760 + 11761 8 13 - 12230 + 12231 13 17 - 10819 + 10820 17 25 - 11289 + 11290 25 31 - 11760 + 11761 31 38 - 10819 + 10820 38 52 - 10819 + 10820 52 64 - 10819 + 10820 65 @@ -4751,62 +4711,62 @@ 1 2 - 16464 + 16465 2 9 - 10819 + 10820 9 16 - 11760 + 11761 16 25 - 11289 + 11290 25 40 - 10819 + 10820 40 57 - 10819 + 10820 58 71 - 10819 + 10820 72 98 - 10819 + 10820 101 140 - 11760 + 11761 140 224 - 10819 + 10820 224 360 - 10819 + 10820 364 1185 - 10819 + 10820 1254 @@ -4827,27 +4787,27 @@ 1 2 - 16464 + 16465 2 10 - 11289 + 11290 10 14 - 10819 + 10820 14 21 - 11289 + 11290 22 31 - 11289 + 11290 31 @@ -4857,27 +4817,27 @@ 39 48 - 12230 + 12231 48 56 - 11760 + 11761 56 64 - 11760 + 11761 64 72 - 10819 + 10820 72 77 - 11289 + 11290 77 @@ -4898,47 +4858,47 @@ 1 2 - 581905 + 581935 2 3 - 318001 + 318018 3 4 - 199456 + 199466 4 6 - 160882 + 160890 6 10 - 190048 + 190058 10 16 - 166057 + 166065 16 25 - 168879 + 168888 25 46 - 163704 + 163713 46 169 - 159000 + 159009 170 @@ -4959,42 +4919,42 @@ 1 2 - 869799 + 869845 2 3 - 280838 + 280853 3 5 - 191459 + 191469 5 8 - 181110 + 181119 8 12 - 162293 + 162302 12 18 - 166527 + 166536 18 39 - 159941 + 159949 39 299 - 103021 + 103026 @@ -5010,47 +4970,47 @@ 1 2 - 612482 + 612514 2 3 - 313297 + 313313 3 4 - 202749 + 202760 4 6 - 184403 + 184412 6 9 - 180639 + 180649 9 13 - 166997 + 167006 13 19 - 173583 + 173592 19 29 - 167468 + 167476 29 52 - 113370 + 113376 @@ -5066,22 +5026,22 @@ 1 2 - 1545788 + 1545868 2 3 - 351401 + 351419 3 5 - 164645 + 164654 5 16 - 53157 + 53159 @@ -5097,47 +5057,47 @@ 1 2 - 586609 + 586639 2 3 - 318942 + 318958 3 4 - 201808 + 201819 4 6 - 167468 + 167476 6 9 - 160412 + 160420 9 14 - 178287 + 178297 14 21 - 176406 + 176415 21 32 - 163234 + 163243 32 61 - 159000 + 159009 61 @@ -5212,7 +5172,7 @@ 819 - 1546 + 1548 2822 @@ -5244,7 +5204,7 @@ 23 35 - 3292 + 3293 38 @@ -5263,23 +5223,23 @@ 73 - 83 - 2822 + 84 + 3293 - 83 - 95 - 2822 + 84 + 97 + 3293 - 96 + 98 101 - 3292 + 2352 101 105 - 3292 + 3293 106 @@ -5369,7 +5329,7 @@ 587 - 831 + 832 2822 @@ -5482,12 +5442,12 @@ 7 11 - 3292 + 3293 11 16 - 3292 + 3293 16 @@ -5502,7 +5462,7 @@ 24 27 - 3292 + 3293 28 @@ -5512,7 +5472,7 @@ 33 40 - 3292 + 3293 40 @@ -5553,52 +5513,52 @@ 1 2 - 589902 + 589932 2 3 - 312356 + 312372 3 4 - 198986 + 198996 4 6 - 161352 + 161361 6 10 - 189577 + 189587 10 16 - 163704 + 163713 16 25 - 171231 + 170770 25 45 - 159471 + 159949 45 160 - 159941 + 159949 160 299 - 11289 + 11290 @@ -5614,47 +5574,47 @@ 1 2 - 881560 + 881606 2 3 - 270019 + 270033 3 4 - 123249 + 123255 4 6 - 142065 + 142073 6 10 - 195693 + 195703 10 15 - 168409 + 168417 15 26 - 165586 + 165595 26 120 - 159471 + 159479 121 299 - 11760 + 11761 @@ -5670,22 +5630,22 @@ 1 2 - 1538732 + 1538812 2 3 - 349048 + 349067 3 5 - 172172 + 172181 5 10 - 57861 + 57864 @@ -5701,47 +5661,47 @@ 1 2 - 621890 + 621922 2 3 - 304359 + 304375 3 4 - 204631 + 204641 4 6 - 186755 + 186765 6 9 - 177817 + 177826 9 13 - 169349 + 169358 13 19 - 174524 + 174533 19 29 - 162764 + 162772 29 52 - 115722 + 115728 @@ -5757,47 +5717,47 @@ 1 2 - 596488 + 596519 2 3 - 311415 + 311431 3 4 - 198986 + 198996 4 6 - 171701 + 171710 6 9 - 157589 + 157597 9 14 - 173583 + 173592 14 21 - 180169 + 180178 21 32 - 165116 + 165124 32 60 - 159000 + 159009 60 @@ -5862,7 +5822,7 @@ 879 - 1081 + 1082 3763 @@ -5871,7 +5831,7 @@ 3763 - 1309 + 1310 1590 3763 @@ -5894,7 +5854,7 @@ 1 2 - 5644 + 5645 2 @@ -5970,7 +5930,7 @@ 1 2 - 5644 + 5645 2 @@ -6009,7 +5969,7 @@ 575 - 628 + 627 3763 @@ -6081,7 +6041,7 @@ 35 39 - 3292 + 3293 39 @@ -6122,7 +6082,7 @@ 1 2 - 5644 + 5645 2 @@ -6192,11 +6152,11 @@ locations_stmt - 3805462 + 3805465 id - 3805462 + 3805465 container @@ -6230,7 +6190,7 @@ 1 2 - 3805462 + 3805465 @@ -6246,7 +6206,7 @@ 1 2 - 3805462 + 3805465 @@ -6262,7 +6222,7 @@ 1 2 - 3805462 + 3805465 @@ -6278,7 +6238,7 @@ 1 2 - 3805462 + 3805465 @@ -6294,7 +6254,7 @@ 1 2 - 3805462 + 3805465 @@ -6958,7 +6918,7 @@ 10 11 - 10500 + 10501 11 @@ -8174,11 +8134,11 @@ locations_expr - 13128112 + 13128120 id - 13128112 + 13128120 container @@ -8212,7 +8172,7 @@ 1 2 - 13128112 + 13128120 @@ -8228,7 +8188,7 @@ 1 2 - 13128112 + 13128120 @@ -8244,7 +8204,7 @@ 1 2 - 13128112 + 13128120 @@ -8260,7 +8220,7 @@ 1 2 - 13128112 + 13128120 @@ -8276,7 +8236,7 @@ 1 2 - 13128112 + 13128120 @@ -10096,23 +10056,23 @@ numlines - 1406545 + 1406618 element_id - 1399488 + 1399561 num_lines - 102550 + 102556 num_code - 85615 + 85620 num_comment - 60213 + 60216 @@ -10126,7 +10086,7 @@ 1 2 - 1392432 + 1392505 2 @@ -10147,7 +10107,7 @@ 1 2 - 1393373 + 1393446 2 @@ -10168,7 +10128,7 @@ 1 2 - 1399488 + 1399561 @@ -10184,17 +10144,17 @@ 1 2 - 68680 + 68684 2 3 - 12230 + 12231 3 4 - 7526 + 7527 4 @@ -10220,12 +10180,12 @@ 1 2 - 71032 + 71036 2 3 - 12230 + 12231 3 @@ -10256,22 +10216,22 @@ 1 2 - 70092 + 70095 2 3 - 15053 + 15054 3 4 - 10819 + 10820 4 7 - 6585 + 6586 @@ -10287,22 +10247,22 @@ 1 2 - 53157 + 53159 2 3 - 14582 + 14583 3 5 - 6585 + 6586 5 42 - 6585 + 6586 44 @@ -10323,12 +10283,12 @@ 1 2 - 53157 + 53159 2 3 - 16934 + 16935 3 @@ -10338,7 +10298,7 @@ 5 8 - 6585 + 6586 8 @@ -10359,7 +10319,7 @@ 1 2 - 53627 + 53630 2 @@ -10369,7 +10329,7 @@ 3 5 - 7526 + 7527 5 @@ -10379,7 +10339,7 @@ 7 10 - 3292 + 3293 @@ -10395,7 +10355,7 @@ 1 2 - 34810 + 34812 2 @@ -10436,7 +10396,7 @@ 1 2 - 34810 + 34812 2 @@ -10477,7 +10437,7 @@ 1 2 - 34810 + 34812 2 @@ -10512,31 +10472,31 @@ diagnostics - 582773 + 72312 id - 582773 + 72312 severity - 209 + 23 error_tag - 7851 + 80 error_message - 56215 + 127 full_error_message - 582040 + 62738 location - 369218 + 150 @@ -10550,7 +10510,7 @@ 1 2 - 582773 + 72312 @@ -10566,7 +10526,7 @@ 1 2 - 582773 + 72312 @@ -10582,7 +10542,7 @@ 1 2 - 582773 + 72312 @@ -10598,7 +10558,7 @@ 1 2 - 582773 + 72312 @@ -10614,7 +10574,7 @@ 1 2 - 582773 + 72312 @@ -10628,14 +10588,14 @@ 12 - 254 - 255 - 104 + 4 + 5 + 11 - 5313 - 5314 - 104 + 6250 + 6251 + 11 @@ -10649,14 +10609,14 @@ 12 - 5 - 6 - 104 + 1 + 2 + 11 - 70 - 71 - 104 + 6 + 7 + 11 @@ -10669,508 +10629,388 @@ 12 - - 7 - 8 - 104 - - - 530 - 531 - 104 - - - - - - - severity - full_error_message - - - 12 - - - 254 - 255 - 104 - - - 5306 - 5307 - 104 - - - - - - - severity - location - - - 12 - - - 174 - 175 - 104 - - - 3429 - 3430 - 104 - - - - - - - error_tag - id - - - 12 - - - 1 - 2 - 1046 - - - 2 - 3 - 942 - 3 4 - 523 - - - 4 - 5 - 523 - - - 5 - 7 - 628 - - - 7 - 11 - 628 - - - 11 - 16 - 628 - - - 16 - 21 - 628 - - - 21 - 32 - 628 - - - 44 - 72 - 628 - - - 112 - 540 - 628 - - - 595 - 1254 - 418 - - - - - - - error_tag - severity - - - 12 - - - 1 - 2 - 7851 - - - - - - - error_tag - error_message - - - 12 - - - 1 - 2 - 5443 - - - 2 - 3 - 418 - - - 3 - 4 - 523 - - - 4 - 6 - 628 - - - 7 - 35 - 628 - - - 59 - 294 - 209 - - - - - - - error_tag - full_error_message - - - 12 - - - 1 - 2 - 1151 - - - 2 - 3 - 942 - - - 3 - 4 - 523 - - - 4 - 5 - 523 - - - 5 - 7 - 628 - - - 7 - 12 - 628 - - - 13 - 16 - 523 - - - 16 - 21 - 628 - - - 21 - 32 - 628 - - - 44 - 72 - 628 - - - 112 - 540 - 628 - - - 595 - 1254 - 418 - - - - - - - error_tag - location - - - 12 - - - 1 - 2 - 1674 - - - 2 - 3 - 942 - - - 3 - 4 - 418 - - - 4 - 5 - 523 - - - 5 - 6 - 523 - - - 6 - 7 - 523 - - - 7 - 15 - 628 - - - 15 - 20 - 628 - - - 23 - 44 - 628 - - - 44 - 95 - 628 - - - 139 - 630 - 628 - - - 764 - 765 - 104 - - - - - - - error_message - id - - - 12 - - - 1 - 2 - 24809 - - - 2 - 3 - 13608 - - - 3 - 4 - 4187 - - - 4 - 6 - 4606 - - - 6 - 14 - 4292 - - - 14 - 227 - 4292 - - - 405 - 1254 - 418 - - - - - - - error_message - severity - - - 12 - - - 1 - 2 - 56215 - - - - - - - error_message - error_tag - - - 12 - - - 1 - 2 - 56215 - - - - - - - error_message - full_error_message - - - 12 - - - 1 - 2 - 24914 - - - 2 - 3 - 13608 - - - 3 - 4 - 4187 - - - 4 - 6 - 4606 - - - 6 - 15 - 4396 - - - 15 - 540 - 4292 - - - 595 - 1254 - 209 - - - - - - - error_message - location - - - 12 - - - 1 - 2 - 36011 - - - 2 - 3 - 6909 - - - 3 - 5 - 4710 - - - 5 - 12 - 4292 - - - 12 - 765 - 4292 - - - - - - - full_error_message - id - - - 12 - - - 1 - 2 - 581935 + 11 8 9 - 104 + 11 + + + + + + + severity + full_error_message + + + 12 + + + 4 + 5 + 11 + + + 5422 + 5423 + 11 + + + + + + + severity + location + + + 12 + + + 4 + 5 + 11 + + + 9 + 10 + 11 + + + + + + + error_tag + id + + + 12 + + + 1 + 2 + 11 + + + 2 + 3 + 11 + + + 4 + 5 + 11 + + + 5 + 6 + 11 + + + 417 + 418 + 11 + + + 829 + 830 + 11 + + + 4996 + 4997 + 11 + + + + + + + error_tag + severity + + + 12 + + + 1 + 2 + 80 + + + + + + + error_tag + error_message + + + 12 + + + 1 + 2 + 57 + + + 3 + 4 + 23 + + + + + + + error_tag + full_error_message + + + 12 + + + 1 + 2 + 23 + + + 2 + 3 + 11 + + + 4 + 5 + 11 + + + 5 + 6 + 11 + + + 417 + 418 + 11 + + + 4996 + 4997 + 11 + + + + + + + error_tag + location + + + 12 + + + 1 + 2 + 46 + + + 2 + 3 + 11 + + + 4 + 5 + 11 + + + 5 + 6 + 11 + + + + + + + error_message + id + + + 12 + + + 1 + 2 + 34 + + + 2 + 3 + 23 + + + 5 + 6 + 11 + + + 10 + 11 + 11 + + + 75 + 76 + 11 + + + 332 + 333 + 11 + + + 829 + 830 + 11 + + + 4996 + 4997 + 11 + + + + + + + error_message + severity + + + 12 + + + 1 + 2 + 127 + + + + + + + error_message + error_tag + + + 12 + + + 1 + 2 + 127 + + + + + + + error_message + full_error_message + + + 12 + + + 1 + 2 + 46 + + + 2 + 3 + 23 + + + 5 + 6 + 11 + + + 10 + 11 + 11 + + + 75 + 76 + 11 + + + 332 + 333 + 11 + + + 4996 + 4997 + 11 + + + + + + + error_message + location + + + 12 + + + 1 + 2 + 92 + + + 2 + 3 + 23 + + + 5 + 6 + 11 + + + + + + + full_error_message + id + + + 12 + + + 1 + 2 + 62726 + + + 829 + 830 + 11 @@ -11186,7 +11026,7 @@ 1 2 - 582040 + 62738 @@ -11202,7 +11042,7 @@ 1 2 - 582040 + 62738 @@ -11218,7 +11058,7 @@ 1 2 - 582040 + 62738 @@ -11234,7 +11074,7 @@ 1 2 - 582040 + 62738 @@ -11250,17 +11090,12 @@ 1 2 - 206959 + 138 - 2 - 3 - 135774 - - - 3 - 13 - 26484 + 6242 + 6243 + 11 @@ -11276,12 +11111,7 @@ 1 2 - 361262 - - - 2 - 3 - 7955 + 150 @@ -11297,12 +11127,12 @@ 1 2 - 354458 + 138 - 2 - 6 - 14760 + 3 + 4 + 11 @@ -11318,12 +11148,12 @@ 1 2 - 353830 + 138 - 2 + 5 6 - 15388 + 11 @@ -11339,17 +11169,12 @@ 1 2 - 207063 + 138 - 2 - 3 - 135774 - - - 3 - 13 - 26380 + 5414 + 5415 + 11 @@ -11359,15 +11184,15 @@ files - 124189 + 124196 id - 124189 + 124196 name - 124189 + 124196 @@ -11381,7 +11206,7 @@ 1 2 - 124189 + 124196 @@ -11397,7 +11222,7 @@ 1 2 - 124189 + 124196 @@ -11455,7 +11280,7 @@ containerparent - 139243 + 139250 parent @@ -11463,7 +11288,7 @@ child - 139243 + 139250 @@ -11482,7 +11307,7 @@ 2 3 - 3292 + 3293 3 @@ -11518,7 +11343,7 @@ 1 2 - 139243 + 139250 @@ -11528,11 +11353,11 @@ fileannotations - 5254886 + 5253841 id - 5019 + 5018 kind @@ -11540,11 +11365,11 @@ name - 56112 + 56101 value - 47173 + 47163 @@ -11563,7 +11388,7 @@ 2 3 - 4845 + 4844 @@ -11624,7 +11449,7 @@ 936 937 - 1457 + 1456 1083 @@ -11690,7 +11515,7 @@ 1501 1502 - 1457 + 1456 1504 @@ -11779,12 +11604,12 @@ 1 2 - 9078 + 9076 2 3 - 6372 + 6370 3 @@ -11794,12 +11619,12 @@ 5 9 - 4371 + 4370 9 14 - 4082 + 4081 14 @@ -11809,27 +11634,27 @@ 18 20 - 4834 + 4833 20 34 - 4325 + 4324 34 128 - 4614 + 4613 128 229 - 4221 + 4220 229 387 - 4348 + 4347 387 @@ -11850,7 +11675,7 @@ 1 2 - 56112 + 56101 @@ -11866,17 +11691,17 @@ 1 2 - 9089 + 9088 2 3 - 8257 + 8255 3 4 - 2625 + 2624 4 @@ -11886,37 +11711,37 @@ 6 9 - 4232 + 4231 9 14 - 4313 + 4312 14 17 - 4232 + 4231 17 22 - 4706 + 4705 22 41 - 4313 + 4312 41 82 - 4267 + 4266 82 157 - 4209 + 4208 158 @@ -11937,7 +11762,7 @@ 1 2 - 7332 + 7330 2 @@ -11947,7 +11772,7 @@ 5 8 - 3411 + 3410 8 @@ -11957,22 +11782,22 @@ 15 17 - 2602 + 2601 17 19 - 4244 + 4243 19 34 - 3411 + 3410 34 189 - 3712 + 3711 189 @@ -11987,12 +11812,12 @@ 266 321 - 3770 + 3769 322 399 - 4047 + 4046 399 @@ -12013,7 +11838,7 @@ 1 2 - 47161 + 47152 2 @@ -12034,17 +11859,17 @@ 1 2 - 7355 + 7353 2 5 - 2648 + 2647 5 8 - 3596 + 3595 8 @@ -12059,17 +11884,17 @@ 17 19 - 3677 + 3676 19 29 - 3596 + 3595 29 39 - 3758 + 3757 39 @@ -12079,7 +11904,7 @@ 48 74 - 3654 + 3653 74 @@ -12089,7 +11914,7 @@ 102 119 - 3689 + 3688 119 @@ -12104,15 +11929,15 @@ inmacroexpansion - 109313317 + 109313388 id - 17941916 + 17941927 inv - 2682068 + 2682069 @@ -12126,32 +11951,32 @@ 1 3 - 1566018 + 1566019 3 5 - 1071344 + 1071345 5 6 - 1179814 + 1179815 6 7 - 4800000 + 4800003 7 8 - 6359380 + 6359384 8 9 - 2595248 + 2595250 9 @@ -12172,12 +11997,12 @@ 1 2 - 371855 + 371856 2 3 - 540116 + 540113 3 @@ -12212,7 +12037,7 @@ 11 337 - 223911 + 223913 339 @@ -12232,15 +12057,15 @@ affectedbymacroexpansion - 35540532 + 35540555 id - 5135277 + 5135280 inv - 2773181 + 2773183 @@ -12254,7 +12079,7 @@ 1 2 - 2804212 + 2804214 2 @@ -12279,7 +12104,7 @@ 12 50 - 405705 + 405706 50 @@ -12305,7 +12130,7 @@ 4 7 - 230823 + 230824 7 @@ -12315,7 +12140,7 @@ 9 12 - 250042 + 250043 12 @@ -12345,7 +12170,7 @@ 17 18 - 146328 + 146329 18 @@ -12370,19 +12195,19 @@ macroinvocations - 33894981 + 33889080 id - 33894981 + 33889080 macro_id - 81381 + 81423 location - 778557 + 778830 kind @@ -12400,7 +12225,7 @@ 1 2 - 33894981 + 33889080 @@ -12416,7 +12241,7 @@ 1 2 - 33894981 + 33889080 @@ -12432,7 +12257,7 @@ 1 2 - 33894981 + 33889080 @@ -12448,12 +12273,12 @@ 1 2 - 17578 + 17575 2 3 - 16977 + 16973 3 @@ -12463,42 +12288,42 @@ 4 5 - 4880 + 4879 5 8 - 6048 + 6047 8 14 - 6406 + 6440 14 29 - 6291 + 6313 29 - 72 - 6106 + 73 + 6220 - 72 - 247 - 6129 + 73 + 257 + 6139 - 248 - 4166 - 6106 + 257 + 5769 + 6116 - 4220 + 6272 168296 - 1156 + 1017 @@ -12514,32 +12339,32 @@ 1 2 - 43506 + 43498 2 3 - 10651 + 10649 3 4 - 5285 + 5284 4 6 - 6985 + 7018 6 13 - 6626 + 6636 13 66 - 6140 + 6151 66 @@ -12560,12 +12385,12 @@ 1 2 - 75553 + 75538 2 3 - 5828 + 5885 @@ -12581,37 +12406,37 @@ 1 2 - 320982 + 321115 2 3 - 177751 + 177878 3 4 - 47300 + 47313 4 5 - 59605 + 59616 5 9 - 68533 + 68542 9 23 - 58425 + 58414 23 244365 - 45958 + 45949 @@ -12627,12 +12452,12 @@ 1 2 - 731280 + 731563 2 350 - 47277 + 47267 @@ -12648,7 +12473,7 @@ 1 2 - 778557 + 778830 @@ -12662,13 +12487,13 @@ 12 - 20414 - 20415 + 20464 + 20465 11 - 2910446 - 2910447 + 2910469 + 2910470 11 @@ -12683,13 +12508,13 @@ 12 - 2123 - 2124 + 2128 + 2129 11 - 5418 - 5419 + 5423 + 5424 11 @@ -12704,13 +12529,13 @@ 12 - 6291 - 6292 + 6315 + 6316 11 - 61030 - 61031 + 61043 + 61044 11 @@ -12721,15 +12546,15 @@ macroparent - 30455592 + 30449647 id - 30455592 + 30449647 parent_id - 23698199 + 23693599 @@ -12743,7 +12568,7 @@ 1 2 - 30455592 + 30449647 @@ -12759,17 +12584,17 @@ 1 2 - 18307171 + 18303643 2 3 - 4540062 + 4539159 3 88 - 850965 + 850796 @@ -12779,15 +12604,15 @@ macrolocationbind - 3984640 + 3984515 id - 2778886 + 2778799 location - 1988454 + 1988392 @@ -12801,22 +12626,22 @@ 1 2 - 2183104 + 2183036 2 3 - 336443 + 336432 3 7 - 229815 + 229808 7 57 - 29523 + 29522 @@ -12832,22 +12657,22 @@ 1 2 - 1589588 + 1589539 2 3 - 169647 + 169641 3 8 - 154233 + 154228 8 723 - 74984 + 74982 @@ -12857,11 +12682,11 @@ macro_argument_unexpanded - 86176782 + 86159621 invocation - 26568343 + 26563044 argument_index @@ -12869,7 +12694,7 @@ text - 326094 + 326029 @@ -12883,22 +12708,22 @@ 1 2 - 7436793 + 7435302 2 3 - 10861692 + 10859530 3 4 - 6256808 + 6255563 4 67 - 2013048 + 2012648 @@ -12914,22 +12739,22 @@ 1 2 - 7508010 + 7506504 2 3 - 11011561 + 11009369 3 4 - 6087232 + 6086021 4 67 - 1961538 + 1961148 @@ -12954,7 +12779,7 @@ 715085 - 2297335 + 2297334 34 @@ -12997,57 +12822,57 @@ 1 2 - 40858 + 40850 2 3 - 65607 + 65594 3 4 - 15184 + 15181 4 5 - 45102 + 45093 5 8 - 25569 + 25576 8 12 - 16075 + 16060 12 16 - 22297 + 22292 16 23 - 26518 + 26512 23 43 - 24748 + 24743 43 164 - 24459 + 24454 164 521384 - 19671 + 19667 @@ -13063,17 +12888,17 @@ 1 2 - 235830 + 235783 2 3 - 79728 + 79712 3 9 - 10535 + 10533 @@ -13083,11 +12908,11 @@ macro_argument_expanded - 86176782 + 86159621 invocation - 26568343 + 26563044 argument_index @@ -13095,7 +12920,7 @@ text - 197597 + 197580 @@ -13109,22 +12934,22 @@ 1 2 - 7436793 + 7435302 2 3 - 10861692 + 10859530 3 4 - 6256808 + 6255563 4 67 - 2013048 + 2012648 @@ -13140,22 +12965,22 @@ 1 2 - 10747743 + 10745593 2 3 - 9374139 + 9372273 3 4 - 5306998 + 5305941 4 9 - 1139462 + 1139235 @@ -13180,7 +13005,7 @@ 715085 - 2297335 + 2297334 34 @@ -13206,7 +13031,7 @@ 870 - 13877 + 13879 46 @@ -13223,62 +13048,62 @@ 1 2 - 24552 + 24547 2 3 - 41147 + 41151 3 4 - 6927 + 6925 4 5 - 16364 + 16361 5 6 - 2995 + 2994 6 7 - 23291 + 23286 7 9 - 15982 + 15991 9 15 - 16699 + 16696 15 31 - 15589 + 15586 31 97 - 15080 + 15077 97 775 - 15485 + 15482 775 - 1052916 - 3481 + 1052906 + 3480 @@ -13294,17 +13119,17 @@ 1 2 - 99989 + 99992 2 3 - 82850 + 82834 3 66 - 14756 + 14753 @@ -13314,19 +13139,19 @@ functions - 4726273 + 4726519 id - 4726273 + 4726519 name - 1934352 + 1934453 kind - 3292 + 3293 @@ -13340,7 +13165,7 @@ 1 2 - 4726273 + 4726519 @@ -13356,7 +13181,7 @@ 1 2 - 4726273 + 4726519 @@ -13372,22 +13197,22 @@ 1 2 - 1516622 + 1516701 2 3 - 154296 + 154304 3 5 - 151003 + 151011 5 1724 - 112429 + 112435 @@ -13403,7 +13228,7 @@ 1 2 - 1933881 + 1933982 2 @@ -13510,15 +13335,15 @@ function_entry_point - 1176981 + 1177043 id - 1167103 + 1167163 entry_point - 1176981 + 1177043 @@ -13532,12 +13357,12 @@ 1 2 - 1157224 + 1157284 2 3 - 9878 + 9879 @@ -13553,7 +13378,7 @@ 1 2 - 1176981 + 1177043 @@ -13563,15 +13388,15 @@ function_return_type - 4734741 + 4734987 id - 4726273 + 4726519 return_type - 1016569 + 1016622 @@ -13585,7 +13410,7 @@ 1 2 - 4719217 + 4719463 2 @@ -13606,22 +13431,22 @@ 1 2 - 523103 + 523130 2 3 - 390445 + 390465 3 11 - 78559 + 78563 11 2516 - 24461 + 24462 @@ -13639,7 +13464,7 @@ traits - 1 + 2 handle @@ -13707,9 +13532,9 @@ 12 - 2 - 3 - 1 + 1 + 2 + 2 @@ -13723,9 +13548,9 @@ 12 - 2 - 3 - 1 + 1 + 2 + 2 @@ -13739,9 +13564,9 @@ 12 - 2 - 3 - 1 + 1 + 2 + 2 @@ -13943,48 +13768,48 @@ purefunctions - 99446 + 99447 id - 99446 + 99447 function_deleted - 140654 + 140661 id - 140654 + 140661 function_defaulted - 74325 + 74329 id - 74325 + 74329 member_function_this_type - 553641 + 553316 id - 553641 + 553316 this_type - 189690 + 189579 @@ -13998,7 +13823,7 @@ 1 2 - 553641 + 553316 @@ -14014,32 +13839,32 @@ 1 2 - 68526 + 68486 2 3 - 45414 + 45387 3 4 - 30475 + 30458 4 5 - 15537 + 15528 5 7 - 15607 + 15598 7 66 - 14128 + 14119 @@ -14049,27 +13874,27 @@ fun_decls - 5102136 + 5102402 id - 5096962 + 5097227 function - 4578563 + 4578801 type_id - 1013276 + 1013329 name - 1836035 + 1836130 location - 3461324 + 3461504 @@ -14083,7 +13908,7 @@ 1 2 - 5096962 + 5097227 @@ -14099,7 +13924,7 @@ 1 2 - 5091787 + 5092052 2 @@ -14120,7 +13945,7 @@ 1 2 - 5096962 + 5097227 @@ -14136,7 +13961,7 @@ 1 2 - 5096962 + 5097227 @@ -14152,17 +13977,17 @@ 1 2 - 4141075 + 4141291 2 3 - 363161 + 363180 3 7 - 74325 + 74329 @@ -14178,12 +14003,12 @@ 1 2 - 4536696 + 4536932 2 5 - 41867 + 41869 @@ -14199,7 +14024,7 @@ 1 2 - 4578563 + 4578801 @@ -14215,12 +14040,12 @@ 1 2 - 4197996 + 4198214 2 4 - 379155 + 379175 4 @@ -14241,22 +14066,22 @@ 1 2 - 445954 + 445977 2 3 - 453481 + 453505 3 9 - 79500 + 79504 9 2768 - 34340 + 34342 @@ -14272,22 +14097,22 @@ 1 2 - 530629 + 530657 2 3 - 381978 + 381998 3 11 - 77148 + 77152 11 2477 - 23520 + 23522 @@ -14303,17 +14128,17 @@ 1 2 - 883912 + 883958 2 5 - 90319 + 90324 5 822 - 39044 + 39046 @@ -14329,22 +14154,22 @@ 1 2 - 779480 + 779520 2 3 - 133127 + 133134 3 11 - 78089 + 78093 11 2030 - 22579 + 22581 @@ -14360,27 +14185,27 @@ 1 2 - 1245192 + 1245257 2 3 - 269548 + 269562 3 4 - 80441 + 80445 4 6 - 138772 + 138780 6 1758 - 102080 + 102085 @@ -14396,22 +14221,22 @@ 1 2 - 1425832 + 1425906 2 3 - 153355 + 153363 3 5 - 145358 + 145366 5 1708 - 111488 + 111494 @@ -14427,17 +14252,17 @@ 1 2 - 1615880 + 1615964 2 4 - 135009 + 135016 4 954 - 85145 + 85149 @@ -14453,27 +14278,27 @@ 1 2 - 1266831 + 1266897 2 3 - 296362 + 296377 3 4 - 79500 + 79504 4 8 - 139243 + 139250 8 664 - 54097 + 54100 @@ -14489,17 +14314,17 @@ 1 2 - 2995611 + 2995767 2 4 - 302007 + 302023 4 55 - 163704 + 163713 @@ -14515,17 +14340,17 @@ 1 2 - 3063351 + 3063511 2 6 - 268607 + 268621 6 55 - 129364 + 129371 @@ -14541,12 +14366,12 @@ 1 2 - 3245873 + 3246042 2 27 - 215450 + 215461 @@ -14562,12 +14387,12 @@ 1 2 - 3285388 + 3285559 2 13 - 175935 + 175944 @@ -14577,22 +14402,22 @@ fun_def - 1963988 + 1964090 id - 1963988 + 1964090 fun_specialized - 26343 + 26344 id - 26343 + 26344 @@ -14610,11 +14435,11 @@ fun_decl_specifiers - 2937280 + 2937433 id - 1710904 + 1710993 name @@ -14632,17 +14457,17 @@ 1 2 - 503345 + 503371 2 3 - 1188742 + 1188804 3 4 - 18816 + 18817 @@ -14814,26 +14639,26 @@ fun_decl_empty_throws - 1978101 + 1978204 fun_decl - 1978101 + 1978204 fun_decl_noexcept - 61239 + 61252 fun_decl - 61239 + 61252 constant - 61135 + 61148 @@ -14847,7 +14672,7 @@ 1 2 - 61239 + 61252 @@ -14863,7 +14688,7 @@ 1 2 - 61030 + 61043 2 @@ -14878,11 +14703,11 @@ fun_decl_empty_noexcept - 888146 + 888192 fun_decl - 888146 + 888192 @@ -14987,11 +14812,11 @@ param_decl_bind - 7472094 + 7472483 id - 7472094 + 7472483 index @@ -14999,7 +14824,7 @@ fun_decl - 4286434 + 4286657 @@ -15013,7 +14838,7 @@ 1 2 - 7472094 + 7472483 @@ -15029,7 +14854,7 @@ 1 2 - 7472094 + 7472483 @@ -15207,22 +15032,22 @@ 1 2 - 2409002 + 2409127 2 3 - 1071608 + 1071664 3 4 - 506638 + 506664 4 18 - 299184 + 299200 @@ -15238,22 +15063,22 @@ 1 2 - 2409002 + 2409127 2 3 - 1071608 + 1071664 3 4 - 506638 + 506664 4 18 - 299184 + 299200 @@ -15263,27 +15088,27 @@ var_decls - 8611913 + 8612362 id - 8543232 + 8543677 variable - 7520077 + 7520468 type_id - 2430641 + 2430768 name - 672695 + 672730 location - 5365099 + 5365378 @@ -15297,7 +15122,7 @@ 1 2 - 8543232 + 8543677 @@ -15313,12 +15138,12 @@ 1 2 - 8474552 + 8474993 2 3 - 68680 + 68684 @@ -15334,7 +15159,7 @@ 1 2 - 8543232 + 8543677 @@ -15350,7 +15175,7 @@ 1 2 - 8543232 + 8543677 @@ -15366,17 +15191,17 @@ 1 2 - 6658274 + 6658620 2 3 - 707035 + 707072 3 7 - 154767 + 154775 @@ -15392,12 +15217,12 @@ 1 2 - 7346963 + 7347346 2 4 - 173113 + 173122 @@ -15413,12 +15238,12 @@ 1 2 - 7402943 + 7403328 2 3 - 117133 + 117139 @@ -15434,12 +15259,12 @@ 1 2 - 6967337 + 6967700 2 4 - 552739 + 552768 @@ -15455,27 +15280,27 @@ 1 2 - 1505802 + 1505881 2 3 - 516046 + 516073 3 4 - 98787 + 98792 4 7 - 188636 + 188646 7 780 - 121367 + 121373 @@ -15491,22 +15316,22 @@ 1 2 - 1640342 + 1640427 2 3 - 491114 + 491140 3 7 - 188166 + 188176 7 742 - 111018 + 111024 @@ -15522,17 +15347,17 @@ 1 2 - 1918828 + 1918928 2 3 - 388563 + 388584 3 128 - 123249 + 123255 @@ -15548,22 +15373,22 @@ 1 2 - 1743833 + 1743924 2 3 - 406910 + 406931 3 8 - 190048 + 190058 8 595 - 89849 + 89854 @@ -15579,37 +15404,37 @@ 1 2 - 343874 + 343892 2 3 - 87497 + 87502 3 4 - 48923 + 48925 4 6 - 52216 + 52218 6 12 - 52686 + 52689 12 33 - 50804 + 50807 34 3281 - 36692 + 36694 @@ -15625,37 +15450,37 @@ 1 2 - 371628 + 371648 2 3 - 78559 + 78563 3 4 - 45630 + 45632 4 6 - 49864 + 49866 6 14 - 53627 + 53630 14 56 - 51275 + 51278 56 3198 - 22109 + 22110 @@ -15671,27 +15496,27 @@ 1 2 - 460537 + 460561 2 3 - 94553 + 94558 3 5 - 47041 + 47044 5 19 - 51275 + 51278 19 1979 - 19287 + 19288 @@ -15707,32 +15532,32 @@ 1 2 - 381978 + 381998 2 3 - 91260 + 91265 3 5 - 60213 + 60216 5 9 - 51745 + 51748 9 21 - 50804 + 50807 21 1020 - 36692 + 36694 @@ -15748,17 +15573,17 @@ 1 2 - 4535755 + 4535991 2 3 - 550387 + 550415 3 1783 - 278956 + 278971 @@ -15774,17 +15599,17 @@ 1 2 - 4939842 + 4940100 2 17 - 414436 + 414458 17 1779 - 10819 + 10820 @@ -15800,12 +15625,12 @@ 1 2 - 5016520 + 5016782 2 1561 - 348578 + 348596 @@ -15821,7 +15646,7 @@ 1 2 - 5360865 + 5361144 2 @@ -15836,22 +15661,22 @@ var_def - 4083685 + 4083897 id - 4083685 + 4083897 var_decl_specifiers - 334936 + 334953 id - 334936 + 334953 name @@ -15869,7 +15694,7 @@ 1 2 - 334936 + 334953 @@ -15916,19 +15741,19 @@ type_decls - 3283977 + 3284148 id - 3283977 + 3284148 type_id - 3233172 + 3233340 location - 3204006 + 3204173 @@ -15942,7 +15767,7 @@ 1 2 - 3283977 + 3284148 @@ -15958,7 +15783,7 @@ 1 2 - 3283977 + 3284148 @@ -15974,12 +15799,12 @@ 1 2 - 3191305 + 3191471 2 5 - 41867 + 41869 @@ -15995,12 +15820,12 @@ 1 2 - 3191305 + 3191471 2 5 - 41867 + 41869 @@ -16016,12 +15841,12 @@ 1 2 - 3163080 + 3163244 2 20 - 40926 + 40928 @@ -16037,12 +15862,12 @@ 1 2 - 3163080 + 3163244 2 20 - 40926 + 40928 @@ -16052,33 +15877,33 @@ type_def - 2660675 + 2660813 id - 2660675 + 2660813 type_decl_top - 755959 + 755998 type_decl - 755959 + 755998 namespace_decls - 306972 + 306973 id - 306972 + 306973 namespace_id @@ -16086,11 +15911,11 @@ location - 306972 + 306973 bodylocation - 306972 + 306973 @@ -16104,7 +15929,7 @@ 1 2 - 306972 + 306973 @@ -16120,7 +15945,7 @@ 1 2 - 306972 + 306973 @@ -16136,7 +15961,7 @@ 1 2 - 306972 + 306973 @@ -16350,7 +16175,7 @@ 1 2 - 306972 + 306973 @@ -16366,7 +16191,7 @@ 1 2 - 306972 + 306973 @@ -16382,7 +16207,7 @@ 1 2 - 306972 + 306973 @@ -16398,7 +16223,7 @@ 1 2 - 306972 + 306973 @@ -16414,7 +16239,7 @@ 1 2 - 306972 + 306973 @@ -16430,7 +16255,7 @@ 1 2 - 306972 + 306973 @@ -16440,19 +16265,19 @@ usings - 374921 + 374941 id - 374921 + 374941 element_id - 318471 + 318488 location - 249791 + 249804 @@ -16466,7 +16291,7 @@ 1 2 - 374921 + 374941 @@ -16482,7 +16307,7 @@ 1 2 - 374921 + 374941 @@ -16498,12 +16323,12 @@ 1 2 - 263903 + 263917 2 3 - 53157 + 53159 3 @@ -16524,12 +16349,12 @@ 1 2 - 263903 + 263917 2 3 - 53157 + 53159 3 @@ -16550,22 +16375,22 @@ 1 2 - 203690 + 203700 2 4 - 11289 + 11290 4 5 - 31517 + 31519 5 11 - 3292 + 3293 @@ -16581,22 +16406,22 @@ 1 2 - 203690 + 203700 2 4 - 11289 + 11290 4 5 - 31517 + 31519 5 11 - 3292 + 3293 @@ -16606,15 +16431,15 @@ using_container - 478195 + 478100 parent - 11298 + 11296 child - 303207 + 303147 @@ -16684,17 +16509,17 @@ 1 2 - 223629 + 223585 2 3 - 52990 + 52979 3 11 - 24401 + 24396 13 @@ -16709,15 +16534,15 @@ static_asserts - 130417 + 130418 id - 130417 + 130418 condition - 130417 + 130418 message @@ -16743,7 +16568,7 @@ 1 2 - 130417 + 130418 @@ -16759,7 +16584,7 @@ 1 2 - 130417 + 130418 @@ -16775,7 +16600,7 @@ 1 2 - 130417 + 130418 @@ -16791,7 +16616,7 @@ 1 2 - 130417 + 130418 @@ -16807,7 +16632,7 @@ 1 2 - 130417 + 130418 @@ -16823,7 +16648,7 @@ 1 2 - 130417 + 130418 @@ -16839,7 +16664,7 @@ 1 2 - 130417 + 130418 @@ -16855,7 +16680,7 @@ 1 2 - 130417 + 130418 @@ -17327,15 +17152,15 @@ params - 6825742 + 6826097 id - 6660155 + 6660502 function - 3940208 + 3940413 index @@ -17343,7 +17168,7 @@ type_id - 2234478 + 2234594 @@ -17357,7 +17182,7 @@ 1 2 - 6660155 + 6660502 @@ -17373,7 +17198,7 @@ 1 2 - 6660155 + 6660502 @@ -17389,12 +17214,12 @@ 1 2 - 6535025 + 6535365 2 4 - 125130 + 125137 @@ -17410,22 +17235,22 @@ 1 2 - 2303158 + 2303278 2 3 - 960590 + 960640 3 4 - 433253 + 433276 4 18 - 243205 + 243217 @@ -17441,22 +17266,22 @@ 1 2 - 2303158 + 2303278 2 3 - 960590 + 960640 3 4 - 433253 + 433276 4 18 - 243205 + 243217 @@ -17472,22 +17297,22 @@ 1 2 - 2605636 + 2605772 2 3 - 831225 + 831269 3 4 - 349519 + 349537 4 12 - 153826 + 153834 @@ -17741,22 +17566,22 @@ 1 2 - 1525560 + 1525639 2 3 - 446425 + 446448 3 8 - 171701 + 171710 8 522 - 90790 + 90795 @@ -17772,22 +17597,22 @@ 1 2 - 1749008 + 1749099 2 3 - 250731 + 250745 3 9 - 169820 + 169829 9 506 - 64917 + 64920 @@ -17803,17 +17628,17 @@ 1 2 - 1801694 + 1801788 2 3 - 353282 + 353301 3 13 - 79500 + 79504 @@ -17823,7 +17648,7 @@ overrides - 159823 + 159824 new @@ -17919,7 +17744,7 @@ type_id - 326293 + 326294 name @@ -17937,7 +17762,7 @@ 1 2 - 1048372 + 1048373 2 @@ -18087,19 +17912,19 @@ globalvariables - 300716 + 318724 id - 300708 + 318724 type_id - 1405 + 7852 name - 294738 + 86905 @@ -18113,12 +17938,7 @@ 1 2 - 300700 - - - 2 - 3 - 8 + 318724 @@ -18134,7 +17954,7 @@ 1 2 - 300708 + 318724 @@ -18150,27 +17970,32 @@ 1 2 - 977 + 5130 2 3 - 159 + 209 3 - 7 - 114 + 4 + 628 - 7 - 77 - 106 + 4 + 9 + 628 - 83 - 169397 - 49 + 18 + 31 + 628 + + + 35 + 1226 + 628 @@ -18186,27 +18011,32 @@ 1 2 - 1010 + 5130 2 3 - 135 + 209 3 - 7 - 112 + 4 + 628 - 7 - 105 - 106 + 4 + 9 + 628 - 106 - 168448 - 42 + 14 + 25 + 628 + + + 35 + 209 + 628 @@ -18222,12 +18052,17 @@ 1 2 - 290989 + 75911 2 - 33 - 3749 + 11 + 6596 + + + 11 + 449 + 4397 @@ -18243,12 +18078,12 @@ 1 2 - 294142 + 76644 2 - 12 - 596 + 3 + 10261 @@ -18266,7 +18101,7 @@ type_id - 37905 + 37909 name @@ -18326,7 +18161,7 @@ 3 4 - 2479 + 2483 4 @@ -18336,12 +18171,12 @@ 7 18 - 2878 + 2874 18 15847 - 2513 + 2517 @@ -18367,7 +18202,7 @@ 3 5 - 2946 + 2950 5 @@ -18449,11 +18284,11 @@ autoderivation - 149488 + 149519 var - 149488 + 149519 derivation_type @@ -18471,7 +18306,7 @@ 1 2 - 149488 + 149519 @@ -18537,7 +18372,7 @@ name - 240334 + 240335 location @@ -19272,7 +19107,7 @@ 1 2 - 240334 + 240335 @@ -19288,7 +19123,7 @@ 1 2 - 240334 + 240335 @@ -19414,23 +19249,23 @@ builtintypes - 22109 + 22110 id - 22109 + 22110 name - 22109 + 22110 kind - 22109 + 22110 size - 3292 + 3293 sign @@ -19452,7 +19287,7 @@ 1 2 - 22109 + 22110 @@ -19468,7 +19303,7 @@ 1 2 - 22109 + 22110 @@ -19484,7 +19319,7 @@ 1 2 - 22109 + 22110 @@ -19500,7 +19335,7 @@ 1 2 - 22109 + 22110 @@ -19516,7 +19351,7 @@ 1 2 - 22109 + 22110 @@ -19532,7 +19367,7 @@ 1 2 - 22109 + 22110 @@ -19548,7 +19383,7 @@ 1 2 - 22109 + 22110 @@ -19564,7 +19399,7 @@ 1 2 - 22109 + 22110 @@ -19580,7 +19415,7 @@ 1 2 - 22109 + 22110 @@ -19596,7 +19431,7 @@ 1 2 - 22109 + 22110 @@ -19612,7 +19447,7 @@ 1 2 - 22109 + 22110 @@ -19628,7 +19463,7 @@ 1 2 - 22109 + 22110 @@ -19644,7 +19479,7 @@ 1 2 - 22109 + 22110 @@ -19660,7 +19495,7 @@ 1 2 - 22109 + 22110 @@ -19676,7 +19511,7 @@ 1 2 - 22109 + 22110 @@ -20126,15 +19961,15 @@ derivedtypes - 4413446 + 4413676 id - 4413446 + 4413676 name - 2205312 + 2205427 kind @@ -20142,7 +19977,7 @@ type_id - 2729356 + 2729498 @@ -20156,7 +19991,7 @@ 1 2 - 4413446 + 4413676 @@ -20172,7 +20007,7 @@ 1 2 - 4413446 + 4413676 @@ -20188,7 +20023,7 @@ 1 2 - 4413446 + 4413676 @@ -20204,17 +20039,17 @@ 1 2 - 1935763 + 1935864 2 5 - 171231 + 171240 5 1173 - 98317 + 98322 @@ -20230,7 +20065,7 @@ 1 2 - 2204371 + 2204486 2 @@ -20251,17 +20086,17 @@ 1 2 - 1935763 + 1935864 2 5 - 171231 + 171240 5 1155 - 98317 + 98322 @@ -20400,22 +20235,22 @@ 1 2 - 1685972 + 1686060 2 3 - 568733 + 568763 3 4 - 367395 + 367414 4 54 - 107254 + 107260 @@ -20431,22 +20266,22 @@ 1 2 - 1697262 + 1697350 2 3 - 561206 + 561236 3 4 - 364572 + 364591 4 54 - 106314 + 106319 @@ -20462,22 +20297,22 @@ 1 2 - 1690206 + 1690294 2 3 - 572496 + 572526 3 4 - 366454 + 366473 4 6 - 100198 + 100203 @@ -20487,11 +20322,11 @@ pointerishsize - 3314342 + 3312399 id - 3314342 + 3312399 size @@ -20513,7 +20348,7 @@ 1 2 - 3314342 + 3312399 @@ -20529,7 +20364,7 @@ 1 2 - 3314342 + 3312399 @@ -20603,19 +20438,19 @@ arraysizes - 71503 + 71507 id - 71503 + 71507 num_elements - 23520 + 23522 bytesize - 26343 + 26344 alignment @@ -20633,7 +20468,7 @@ 1 2 - 71503 + 71507 @@ -20649,7 +20484,7 @@ 1 2 - 71503 + 71507 @@ -20665,7 +20500,7 @@ 1 2 - 71503 + 71507 @@ -20686,7 +20521,7 @@ 2 3 - 15053 + 15054 3 @@ -20722,7 +20557,7 @@ 1 2 - 18346 + 18347 2 @@ -20753,7 +20588,7 @@ 1 2 - 18346 + 18347 2 @@ -20789,12 +20624,12 @@ 2 3 - 16934 + 16935 3 4 - 3292 + 3293 4 @@ -20820,12 +20655,12 @@ 1 2 - 21639 + 21640 2 3 - 3292 + 3293 3 @@ -20846,12 +20681,12 @@ 1 2 - 22109 + 22110 2 3 - 3292 + 3293 4 @@ -20954,15 +20789,15 @@ typedefbase - 1724181 + 1736730 id - 1724181 + 1736730 type_id - 803746 + 810523 @@ -20976,7 +20811,7 @@ 1 2 - 1724181 + 1736730 @@ -20992,22 +20827,22 @@ 1 2 - 623380 + 629130 2 3 - 84307 + 85019 3 6 - 64497 + 64576 6 5443 - 31560 + 31797 @@ -21017,19 +20852,19 @@ decltypes - 355640 + 355894 id - 23953 + 23951 expr - 355640 + 355894 base_type - 17181 + 17180 parentheses_would_change_meaning @@ -21047,12 +20882,12 @@ 1 2 - 5961 + 5960 2 3 - 7492 + 7491 3 @@ -21067,12 +20902,12 @@ 7 18 - 1999 + 1980 18 42 - 2017 + 2035 42 @@ -21093,7 +20928,7 @@ 1 2 - 23953 + 23951 @@ -21109,7 +20944,7 @@ 1 2 - 23953 + 23951 @@ -21125,7 +20960,7 @@ 1 2 - 355640 + 355894 @@ -21141,7 +20976,7 @@ 1 2 - 355640 + 355894 @@ -21157,7 +20992,7 @@ 1 2 - 355640 + 355894 @@ -21204,7 +21039,7 @@ 2 3 - 7348 + 7347 3 @@ -21245,7 +21080,7 @@ 1 2 - 17181 + 17180 @@ -21275,8 +21110,8 @@ 12 - 19747 - 19748 + 19762 + 19763 18 @@ -21303,15 +21138,15 @@ usertypes - 5342989 + 5343268 id - 5342989 + 5343268 name - 1383024 + 1383096 kind @@ -21329,7 +21164,7 @@ 1 2 - 5342989 + 5343268 @@ -21345,7 +21180,7 @@ 1 2 - 5342989 + 5343268 @@ -21361,27 +21196,27 @@ 1 2 - 1001986 + 1002039 2 3 - 161352 + 161361 3 7 - 107725 + 107730 7 80 - 104432 + 104437 80 885 - 7526 + 7527 @@ -21397,17 +21232,17 @@ 1 2 - 1240488 + 1240552 2 3 - 127012 + 127019 3 7 - 15523 + 15524 @@ -21549,11 +21384,11 @@ usertypesize - 1755594 + 1755685 id - 1755594 + 1755685 size @@ -21575,7 +21410,7 @@ 1 2 - 1755594 + 1755685 @@ -21591,7 +21426,7 @@ 1 2 - 1755594 + 1755685 @@ -21607,7 +21442,7 @@ 1 2 - 3292 + 3293 2 @@ -21755,11 +21590,11 @@ usertype_final - 9526 + 9528 id - 9526 + 9528 @@ -21819,15 +21654,15 @@ mangled_name - 5264430 + 5301398 id - 5264430 + 5301398 mangled_name - 1235313 + 1272072 @@ -21841,7 +21676,7 @@ 1 2 - 5264430 + 5301398 @@ -21857,32 +21692,32 @@ 1 2 - 731027 + 767759 2 3 - 178287 + 178297 3 4 - 84674 + 84679 4 - 6 - 86086 + 7 + 114787 - 6 - 13 - 93142 + 7 + 25 + 95499 - 13 + 25 885 - 62094 + 31049 @@ -21892,59 +21727,59 @@ is_pod_class - 554326 + 554216 id - 554326 + 554216 is_standard_layout_class - 1295997 + 1296064 id - 1295997 + 1296064 is_complete - 1694439 + 1694528 id - 1694439 + 1694528 is_class_template - 405028 + 405049 id - 405028 + 405049 class_instantiation - 1121943 + 1122001 to - 1121943 + 1122001 from - 170761 + 170770 @@ -21958,7 +21793,7 @@ 1 2 - 1121943 + 1122001 @@ -21974,42 +21809,42 @@ 1 2 - 58802 + 58805 2 3 - 30106 + 30108 3 4 - 16464 + 16465 4 5 - 14582 + 14583 5 7 - 15523 + 15524 7 13 - 13171 + 13172 13 29 - 13171 + 13172 30 84 - 8937 + 8938 @@ -22019,11 +21854,11 @@ class_template_argument - 2978113 + 2977520 type_id - 1355713 + 1355443 index @@ -22031,7 +21866,7 @@ arg_type - 863386 + 863214 @@ -22045,27 +21880,27 @@ 1 2 - 551562 + 551453 2 3 - 411593 + 411511 3 4 - 246019 + 245970 4 7 - 122356 + 122331 7 113 - 24182 + 24177 @@ -22081,22 +21916,22 @@ 1 2 - 577421 + 577306 2 3 - 424939 + 424854 3 4 - 257884 + 257833 4 113 - 95467 + 95448 @@ -22117,7 +21952,7 @@ 2 3 - 821 + 820 3 @@ -22163,7 +21998,7 @@ 2 3 - 821 + 820 3 @@ -22204,27 +22039,27 @@ 1 2 - 535649 + 535542 2 3 - 181070 + 181034 3 4 - 52573 + 52563 4 10 - 65688 + 65675 10 11334 - 28403 + 28397 @@ -22240,17 +22075,17 @@ 1 2 - 755682 + 755532 2 3 - 85741 + 85724 3 22 - 21961 + 21957 @@ -22260,11 +22095,11 @@ class_template_argument_value - 508520 + 508546 type_id - 316590 + 316606 index @@ -22272,7 +22107,7 @@ arg_value - 508520 + 508546 @@ -22286,12 +22121,12 @@ 1 2 - 261081 + 261094 2 3 - 53627 + 53630 3 @@ -22312,17 +22147,17 @@ 1 2 - 200397 + 200407 2 3 - 81852 + 81856 3 5 - 29165 + 29167 5 @@ -22405,7 +22240,7 @@ 1 2 - 508520 + 508546 @@ -22421,7 +22256,7 @@ 1 2 - 508520 + 508546 @@ -22431,15 +22266,15 @@ is_proxy_class_for - 65387 + 65391 id - 65387 + 65391 templ_param_id - 65387 + 65391 @@ -22453,7 +22288,7 @@ 1 2 - 65387 + 65391 @@ -22469,7 +22304,7 @@ 1 2 - 65387 + 65391 @@ -22479,11 +22314,11 @@ type_mentions - 4011508 + 4011511 id - 4011508 + 4011511 type_id @@ -22491,7 +22326,7 @@ location - 3978135 + 3978138 kind @@ -22509,7 +22344,7 @@ 1 2 - 4011508 + 4011511 @@ -22525,7 +22360,7 @@ 1 2 - 4011508 + 4011511 @@ -22541,7 +22376,7 @@ 1 2 - 4011508 + 4011511 @@ -22675,7 +22510,7 @@ 1 2 - 3944762 + 3944765 2 @@ -22696,7 +22531,7 @@ 1 2 - 3944762 + 3944765 2 @@ -22717,7 +22552,7 @@ 1 2 - 3978135 + 3978138 @@ -22775,26 +22610,26 @@ is_function_template - 1413601 + 1413674 id - 1413601 + 1413674 function_instantiation - 906422 + 905891 to - 906422 + 905891 from - 146002 + 145917 @@ -22808,7 +22643,7 @@ 1 2 - 906422 + 905891 @@ -22824,27 +22659,27 @@ 1 2 - 101152 + 101092 2 3 - 14480 + 14472 3 6 - 12014 + 12007 6 21 - 12049 + 12042 22 869 - 6306 + 6302 @@ -22854,11 +22689,11 @@ function_template_argument - 2339815 + 2338443 function_id - 1318394 + 1317621 index @@ -22866,7 +22701,7 @@ arg_type - 305041 + 304862 @@ -22880,22 +22715,22 @@ 1 2 - 679667 + 679268 2 3 - 388084 + 387856 3 4 - 179966 + 179861 4 15 - 70676 + 70634 @@ -22911,22 +22746,22 @@ 1 2 - 694852 + 694445 2 3 - 393404 + 393173 3 4 - 150970 + 150882 4 9 - 79167 + 79120 @@ -23074,32 +22909,32 @@ 1 2 - 186978 + 186868 2 3 - 44850 + 44824 3 5 - 23218 + 23204 5 16 - 23535 + 23521 16 107 - 23006 + 22993 108 955 - 3452 + 3450 @@ -23115,17 +22950,17 @@ 1 2 - 274918 + 274756 2 4 - 26001 + 25986 4 17 - 4122 + 4119 @@ -23135,11 +22970,11 @@ function_template_argument_value - 362998 + 362786 function_id - 181340 + 181234 index @@ -23147,7 +22982,7 @@ arg_value - 360356 + 360145 @@ -23161,12 +22996,12 @@ 1 2 - 171969 + 171868 2 8 - 9371 + 9366 @@ -23182,17 +23017,17 @@ 1 2 - 151428 + 151339 2 3 - 20681 + 20669 3 97 - 9230 + 9225 @@ -23330,12 +23165,12 @@ 1 2 - 357714 + 357504 2 3 - 2642 + 2640 @@ -23351,7 +23186,7 @@ 1 2 - 360356 + 360145 @@ -23361,26 +23196,26 @@ is_variable_template - 42082 + 47326 id - 42082 + 47326 variable_instantiation - 49201 + 258309 to - 49201 + 258309 from - 25019 + 26281 @@ -23394,7 +23229,7 @@ 1 2 - 49201 + 258309 @@ -23410,22 +23245,42 @@ 1 2 - 14236 + 11203 2 3 - 7746 + 3559 3 + 4 + 1675 + + + 4 + 6 + 1884 + + + 6 8 - 1988 + 1884 8 14 - 1046 + 2408 + + + 15 + 26 + 1989 + + + 32 + 371 + 1675 @@ -23435,11 +23290,11 @@ variable_template_argument - 329648 + 448035 variable_id - 26380 + 247943 index @@ -23447,7 +23302,7 @@ arg_type - 217532 + 217578 @@ -23461,22 +23316,22 @@ 1 2 - 16121 + 119469 2 3 - 5652 + 99889 3 4 - 3873 + 18218 4 17 - 732 + 10365 @@ -23492,52 +23347,22 @@ 1 2 - 5757 + 129206 2 3 - 5234 + 91408 3 - 4 - 2093 - - - 4 5 - 1256 + 22825 5 - 6 - 2407 - - - 6 - 8 - 2303 - - - 8 - 11 - 2198 - - - 11 - 18 - 2303 - - - 18 - 50 - 1988 - - - 66 - 516 - 837 + 17 + 4502 @@ -23551,43 +23376,53 @@ 12 - 1 - 2 + 11 + 12 104 - 2 - 3 + 22 + 23 628 - 3 - 4 - 418 - - - 5 - 6 - 209 - - - 27 - 28 + 29 + 30 104 - 42 - 43 + 30 + 31 + 314 + + + 44 + 45 104 - 79 - 80 + 93 + 94 104 - 248 - 249 + 222 + 223 + 104 + + + 588 + 589 + 104 + + + 1090 + 1091 + 104 + + + 1974 + 1975 104 @@ -23665,17 +23500,22 @@ 1 2 - 180579 + 171403 2 3 - 21878 + 25024 3 - 38 - 15074 + 8 + 17067 + + + 8 + 94 + 4083 @@ -23691,12 +23531,12 @@ 1 2 - 200259 + 200302 2 5 - 16854 + 16857 5 @@ -23711,11 +23551,11 @@ variable_template_argument_value - 15597 + 15810 variable_id - 2826 + 6596 index @@ -23723,7 +23563,7 @@ arg_value - 12038 + 12041 @@ -23737,12 +23577,12 @@ 1 2 - 2617 + 5968 2 3 - 209 + 628 @@ -23756,45 +23596,25 @@ 12 - 2 - 3 - 418 + 1 + 2 + 314 - 3 - 4 - 104 + 2 + 3 + 5235 4 5 - 1360 - - - 5 - 6 - 209 - - - 6 - 7 - 209 + 837 8 9 209 - - 12 - 17 - 209 - - - 20 - 21 - 104 - @@ -23806,24 +23626,24 @@ 12 - - 2 - 3 - 104 - 6 7 104 - 8 - 9 + 19 + 20 104 - 13 - 14 + 20 + 21 + 104 + + + 24 + 25 104 @@ -23871,12 +23691,12 @@ 1 2 - 8479 + 8271 2 3 - 3559 + 3769 @@ -23892,7 +23712,7 @@ 1 2 - 12038 + 12041 @@ -23902,15 +23722,15 @@ routinetypes - 546982 + 546661 id - 546982 + 546661 return_type - 285945 + 285778 @@ -23924,7 +23744,7 @@ 1 2 - 546982 + 546661 @@ -23940,17 +23760,17 @@ 1 2 - 249233 + 249087 2 3 - 21315 + 21303 3 3594 - 15396 + 15387 @@ -23960,11 +23780,11 @@ routinetypeargs - 993519 + 993571 routine - 429019 + 429042 index @@ -23972,7 +23792,7 @@ type_id - 229563 + 229575 @@ -23986,27 +23806,27 @@ 1 2 - 155707 + 155715 2 3 - 135479 + 135486 3 4 - 63976 + 63979 4 5 - 46100 + 46103 5 18 - 27754 + 27756 @@ -24022,27 +23842,27 @@ 1 2 - 185814 + 185824 2 3 - 135009 + 135016 3 4 - 59272 + 59275 4 5 - 33869 + 33871 5 11 - 15053 + 15054 @@ -24200,27 +24020,27 @@ 1 2 - 148651 + 148659 2 3 - 31047 + 31049 3 5 - 16934 + 16935 5 12 - 18346 + 18347 12 113 - 14582 + 14583 @@ -24236,17 +24056,17 @@ 1 2 - 174994 + 175004 2 3 - 31047 + 31049 3 6 - 18816 + 18817 6 @@ -24261,19 +24081,19 @@ ptrtomembers - 38103 + 38105 id - 38103 + 38105 type_id - 38103 + 38105 class_id - 15523 + 15524 @@ -24287,7 +24107,7 @@ 1 2 - 38103 + 38105 @@ -24303,7 +24123,7 @@ 1 2 - 38103 + 38105 @@ -24319,7 +24139,7 @@ 1 2 - 38103 + 38105 @@ -24335,7 +24155,7 @@ 1 2 - 38103 + 38105 @@ -24397,15 +24217,15 @@ specifiers - 24932 + 24933 id - 24932 + 24933 str - 24932 + 24933 @@ -24419,7 +24239,7 @@ 1 2 - 24932 + 24933 @@ -24435,7 +24255,7 @@ 1 2 - 24932 + 24933 @@ -24445,11 +24265,11 @@ typespecifiers - 1317166 + 1317234 type_id - 1298819 + 1298887 spec_id @@ -24467,12 +24287,12 @@ 1 2 - 1280473 + 1280540 2 3 - 18346 + 18347 @@ -24533,11 +24353,11 @@ funspecifiers - 13049498 + 13041848 func_id - 3975160 + 3972829 spec_id @@ -24555,27 +24375,27 @@ 1 2 - 314977 + 314792 2 3 - 544551 + 544231 3 4 - 1145438 + 1144767 4 5 - 1732127 + 1731112 5 8 - 238064 + 237925 @@ -24691,11 +24511,11 @@ varspecifiers - 2347848 + 2347970 var_id - 1255071 + 1255136 spec_id @@ -24713,22 +24533,22 @@ 1 2 - 735731 + 735769 2 3 - 203219 + 203230 3 4 - 58802 + 58805 4 5 - 257317 + 257331 @@ -24789,11 +24609,11 @@ attributes - 696354 + 696502 id - 696354 + 696502 kind @@ -24801,7 +24621,7 @@ name - 1674 + 1675 name_space @@ -24809,7 +24629,7 @@ location - 483847 + 483949 @@ -24823,7 +24643,7 @@ 1 2 - 696354 + 696502 @@ -24839,7 +24659,7 @@ 1 2 - 696354 + 696502 @@ -24855,7 +24675,7 @@ 1 2 - 696354 + 696502 @@ -24871,7 +24691,7 @@ 1 2 - 696354 + 696502 @@ -25088,7 +24908,7 @@ 1 2 - 1674 + 1675 @@ -25264,17 +25084,17 @@ 1 2 - 442497 + 442591 2 9 - 36848 + 36856 9 201 - 4501 + 4502 @@ -25290,7 +25110,7 @@ 1 2 - 483847 + 483949 @@ -25306,7 +25126,7 @@ 1 2 - 479555 + 479656 2 @@ -25327,7 +25147,7 @@ 1 2 - 483847 + 483949 @@ -25337,11 +25157,11 @@ attribute_args - 352341 + 352360 id - 352341 + 352360 kind @@ -25349,7 +25169,7 @@ attribute - 270489 + 270503 index @@ -25357,7 +25177,7 @@ location - 329291 + 329308 @@ -25371,7 +25191,7 @@ 1 2 - 352341 + 352360 @@ -25387,7 +25207,7 @@ 1 2 - 352341 + 352360 @@ -25403,7 +25223,7 @@ 1 2 - 352341 + 352360 @@ -25419,7 +25239,7 @@ 1 2 - 352341 + 352360 @@ -25534,12 +25354,12 @@ 1 2 - 204631 + 204641 2 3 - 49864 + 49866 3 @@ -25560,7 +25380,7 @@ 1 2 - 260140 + 260153 2 @@ -25581,12 +25401,12 @@ 1 2 - 204631 + 204641 2 3 - 49864 + 49866 3 @@ -25607,12 +25427,12 @@ 1 2 - 204631 + 204641 2 3 - 49864 + 49866 3 @@ -25732,12 +25552,12 @@ 1 2 - 315179 + 315195 2 16 - 14112 + 14113 @@ -25753,7 +25573,7 @@ 1 2 - 316590 + 316606 2 @@ -25774,12 +25594,12 @@ 1 2 - 315179 + 315195 2 16 - 14112 + 14113 @@ -25795,7 +25615,7 @@ 1 2 - 329291 + 329308 @@ -25805,15 +25625,15 @@ attribute_arg_value - 351871 + 351889 arg - 351871 + 351889 value - 34810 + 34812 @@ -25827,7 +25647,7 @@ 1 2 - 351871 + 351889 @@ -25843,12 +25663,12 @@ 1 2 - 16934 + 16935 2 3 - 12230 + 12231 3 @@ -25969,15 +25789,15 @@ typeattributes - 62496 + 62509 type_id - 62077 + 62090 spec_id - 62496 + 62509 @@ -25991,7 +25811,7 @@ 1 2 - 61658 + 61671 2 @@ -26012,7 +25832,7 @@ 1 2 - 62496 + 62509 @@ -26022,15 +25842,15 @@ funcattributes - 635532 + 635565 func_id - 447366 + 447389 spec_id - 635532 + 635565 @@ -26044,17 +25864,17 @@ 1 2 - 341522 + 341540 2 3 - 64917 + 64920 3 6 - 39985 + 39987 6 @@ -26075,7 +25895,7 @@ 1 2 - 635532 + 635565 @@ -26143,15 +25963,15 @@ stmtattributes - 1006 + 1005 stmt_id - 1006 + 1005 spec_id - 1006 + 1005 @@ -26165,7 +25985,7 @@ 1 2 - 1006 + 1005 @@ -26181,7 +26001,7 @@ 1 2 - 1006 + 1005 @@ -26191,15 +26011,15 @@ unspecifiedtype - 10352924 + 10353463 type_id - 10352924 + 10353463 unspecified_type_id - 6956047 + 6956409 @@ -26213,7 +26033,7 @@ 1 2 - 10352924 + 10353463 @@ -26229,17 +26049,17 @@ 1 2 - 4675939 + 4676182 2 3 - 2037843 + 2037950 3 147 - 242264 + 242277 @@ -26249,19 +26069,19 @@ member - 5134480 + 5131470 parent - 689567 + 689163 index - 8808 + 8802 child - 5070710 + 5067737 @@ -26275,42 +26095,42 @@ 1 3 - 18884 + 18873 3 4 - 390691 + 390462 4 5 - 39072 + 39049 5 7 - 53059 + 53028 7 10 - 52848 + 52817 10 16 - 57569 + 57535 16 30 - 52954 + 52923 30 251 - 24486 + 24472 @@ -26326,42 +26146,42 @@ 1 3 - 18884 + 18873 3 4 - 390656 + 390427 4 5 - 39107 + 39084 5 7 - 53165 + 53134 7 10 - 53165 + 53134 10 16 - 57323 + 57289 16 29 - 52742 + 52711 29 253 - 24521 + 24507 @@ -26377,17 +26197,17 @@ 1 2 - 1409 + 1408 2 3 - 810 + 809 3 4 - 951 + 950 5 @@ -26448,7 +26268,7 @@ 1 2 - 810 + 809 2 @@ -26458,7 +26278,7 @@ 3 4 - 1162 + 1161 4 @@ -26503,7 +26323,7 @@ 2770 19253 - 458 + 457 @@ -26519,7 +26339,7 @@ 1 2 - 5070710 + 5067737 @@ -26535,12 +26355,12 @@ 1 2 - 5008419 + 5005483 2 8 - 62290 + 62254 @@ -26550,15 +26370,15 @@ enclosingfunction - 121743 + 121719 child - 121743 + 121719 parent - 69504 + 69490 @@ -26572,7 +26392,7 @@ 1 2 - 121743 + 121719 @@ -26588,22 +26408,22 @@ 1 2 - 36695 + 36687 2 3 - 21591 + 21587 3 4 - 6106 + 6105 4 45 - 5111 + 5110 @@ -26613,15 +26433,15 @@ derivations - 402388 + 402152 derivation - 402388 + 402152 sub - 381883 + 381659 index @@ -26629,11 +26449,11 @@ super - 206461 + 206340 location - 38156 + 38134 @@ -26647,7 +26467,7 @@ 1 2 - 402388 + 402152 @@ -26663,7 +26483,7 @@ 1 2 - 402388 + 402152 @@ -26679,7 +26499,7 @@ 1 2 - 402388 + 402152 @@ -26695,7 +26515,7 @@ 1 2 - 402388 + 402152 @@ -26711,12 +26531,12 @@ 1 2 - 366733 + 366518 2 7 - 15149 + 15141 @@ -26732,12 +26552,12 @@ 1 2 - 366733 + 366518 2 7 - 15149 + 15141 @@ -26753,12 +26573,12 @@ 1 2 - 366733 + 366518 2 7 - 15149 + 15141 @@ -26774,12 +26594,12 @@ 1 2 - 366733 + 366518 2 7 - 15149 + 15141 @@ -26924,12 +26744,12 @@ 1 2 - 199133 + 199016 2 1225 - 7328 + 7324 @@ -26945,12 +26765,12 @@ 1 2 - 199133 + 199016 2 1225 - 7328 + 7324 @@ -26966,12 +26786,12 @@ 1 2 - 206003 + 205882 2 4 - 458 + 457 @@ -26987,12 +26807,12 @@ 1 2 - 202867 + 202748 2 108 - 3593 + 3591 @@ -27008,22 +26828,22 @@ 1 2 - 28326 + 28310 2 5 - 3135 + 3133 5 16 - 2994 + 2992 17 133 - 2994 + 2992 142 @@ -27044,22 +26864,22 @@ 1 2 - 28326 + 28310 2 5 - 3135 + 3133 5 16 - 2994 + 2992 17 133 - 2994 + 2992 142 @@ -27080,7 +26900,7 @@ 1 2 - 38156 + 38134 @@ -27096,22 +26916,22 @@ 1 2 - 30757 + 30739 2 5 - 3417 + 3415 5 55 - 2889 + 2887 60 420 - 1092 + 1091 @@ -27121,11 +26941,11 @@ derspecifiers - 404291 + 404054 der_id - 402001 + 401765 spec_id @@ -27143,12 +26963,12 @@ 1 2 - 399710 + 399476 2 3 - 2290 + 2288 @@ -27189,11 +27009,11 @@ direct_base_offsets - 373110 + 372891 der_id - 373110 + 372891 offset @@ -27211,7 +27031,7 @@ 1 2 - 373110 + 372891 @@ -27262,11 +27082,11 @@ virtual_base_offsets - 6661 + 6660 sub - 3677 + 3676 super @@ -27288,7 +27108,7 @@ 1 2 - 2891 + 2890 2 @@ -27319,7 +27139,7 @@ 1 2 - 3099 + 3098 2 @@ -27553,23 +27373,23 @@ frienddecls - 715075 + 714656 id - 715075 + 714656 type_id - 42384 + 42359 decl_id - 70182 + 70141 location - 6341 + 6338 @@ -27583,7 +27403,7 @@ 1 2 - 715075 + 714656 @@ -27599,7 +27419,7 @@ 1 2 - 715075 + 714656 @@ -27615,7 +27435,7 @@ 1 2 - 715075 + 714656 @@ -27631,47 +27451,47 @@ 1 2 - 6200 + 6197 2 3 - 13212 + 13204 3 6 - 2959 + 2957 6 10 - 3206 + 3204 10 17 - 3276 + 3274 17 24 - 3347 + 3345 25 36 - 3311 + 3309 37 55 - 3241 + 3239 55 103 - 3628 + 3626 @@ -27687,47 +27507,47 @@ 1 2 - 6200 + 6197 2 3 - 13212 + 13204 3 6 - 2959 + 2957 6 10 - 3206 + 3204 10 17 - 3276 + 3274 17 24 - 3347 + 3345 25 36 - 3311 + 3309 37 55 - 3241 + 3239 55 103 - 3628 + 3626 @@ -27743,12 +27563,12 @@ 1 2 - 40939 + 40915 2 13 - 1444 + 1443 @@ -27764,37 +27584,37 @@ 1 2 - 40481 + 40458 2 3 - 5883 + 5880 3 8 - 6024 + 6021 8 15 - 5425 + 5422 15 32 - 5284 + 5281 32 71 - 5284 + 5281 72 160 - 1796 + 1795 @@ -27810,37 +27630,37 @@ 1 2 - 40481 + 40458 2 3 - 5883 + 5880 3 8 - 6024 + 6021 8 15 - 5425 + 5422 15 32 - 5284 + 5281 32 71 - 5284 + 5281 72 160 - 1796 + 1795 @@ -27856,7 +27676,7 @@ 1 2 - 69513 + 69472 2 @@ -27877,7 +27697,7 @@ 1 2 - 5954 + 5950 2 @@ -27898,7 +27718,7 @@ 1 2 - 6200 + 6197 2 @@ -27919,7 +27739,7 @@ 1 2 - 5989 + 5985 2 @@ -27934,19 +27754,19 @@ comments - 8781270 + 8783134 id - 8781270 + 8783134 contents - 3342962 + 3343672 location - 8781270 + 8783134 @@ -27960,7 +27780,7 @@ 1 2 - 8781270 + 8783134 @@ -27976,7 +27796,7 @@ 1 2 - 8781270 + 8783134 @@ -27992,17 +27812,17 @@ 1 2 - 3058223 + 3058872 2 7 - 251135 + 251189 7 32784 - 33603 + 33610 @@ -28018,17 +27838,17 @@ 1 2 - 3058223 + 3058872 2 7 - 251135 + 251189 7 32784 - 33603 + 33610 @@ -28044,7 +27864,7 @@ 1 2 - 8781270 + 8783134 @@ -28060,7 +27880,7 @@ 1 2 - 8781270 + 8783134 @@ -28070,15 +27890,15 @@ commentbinding - 3145674 + 3145838 id - 2490384 + 2490514 element - 3068526 + 3068686 @@ -28092,12 +27912,12 @@ 1 2 - 2408061 + 2408187 2 97 - 82322 + 82327 @@ -28113,12 +27933,12 @@ 1 2 - 2991378 + 2991533 2 3 - 77148 + 77152 @@ -28128,15 +27948,15 @@ exprconv - 7003750 + 7003755 converted - 7003750 + 7003755 conversion - 7003750 + 7003755 @@ -28150,7 +27970,7 @@ 1 2 - 7003750 + 7003755 @@ -28166,7 +27986,7 @@ 1 2 - 7003750 + 7003755 @@ -28176,22 +27996,22 @@ compgenerated - 8494343 + 8493976 id - 8494343 + 8493976 synthetic_destructor_call - 133110 + 133104 element - 103484 + 103479 i @@ -28199,7 +28019,7 @@ destructor_call - 117766 + 117760 @@ -28213,12 +28033,12 @@ 1 2 - 85546 + 85542 2 3 - 11832 + 11831 3 @@ -28239,12 +28059,12 @@ 1 2 - 85546 + 85542 2 3 - 11832 + 11831 3 @@ -28417,7 +28237,7 @@ 1 2 - 115749 + 115743 2 @@ -28438,7 +28258,7 @@ 1 2 - 117766 + 117760 @@ -28486,7 +28306,7 @@ 1 2 - 8937 + 8938 2 @@ -28517,15 +28337,15 @@ namespacembrs - 2463100 + 2463228 parentid - 10819 + 10820 memberid - 2463100 + 2463228 @@ -28605,7 +28425,7 @@ 1 2 - 2463100 + 2463228 @@ -28615,11 +28435,11 @@ exprparents - 14152882 + 14152891 expr_id - 14152882 + 14152891 child_index @@ -28627,7 +28447,7 @@ parent_id - 9417999 + 9418005 @@ -28641,7 +28461,7 @@ 1 2 - 14152882 + 14152891 @@ -28657,7 +28477,7 @@ 1 2 - 14152882 + 14152891 @@ -28775,12 +28595,12 @@ 1 2 - 5388939 + 5388942 2 3 - 3692597 + 3692599 3 @@ -28801,12 +28621,12 @@ 1 2 - 5388939 + 5388942 2 3 - 3692597 + 3692599 3 @@ -28821,22 +28641,22 @@ expr_isload - 4981779 + 4981688 expr_id - 4981779 + 4981688 conversionkinds - 4220621 + 4220624 expr_id - 4220621 + 4220624 kind @@ -28854,7 +28674,7 @@ 1 2 - 4220621 + 4220624 @@ -28883,8 +28703,8 @@ 1 - 26289 - 26290 + 26287 + 26288 1 @@ -28893,8 +28713,8 @@ 1 - 4131029 - 4131030 + 4131034 + 4131035 1 @@ -28905,11 +28725,11 @@ iscall - 3078157 + 3078281 caller - 3078157 + 3078281 kind @@ -28927,7 +28747,7 @@ 1 2 - 3078157 + 3078281 @@ -28951,8 +28771,8 @@ 18 - 167025 - 167026 + 167040 + 167041 18 @@ -28963,11 +28783,11 @@ numtemplatearguments - 543303 + 543548 expr_id - 543303 + 543548 num @@ -28985,7 +28805,7 @@ 1 2 - 543303 + 543548 @@ -29014,8 +28834,8 @@ 18 - 29893 - 29894 + 29908 + 29909 18 @@ -29074,23 +28894,23 @@ namequalifiers - 1618961 + 1618866 id - 1618961 + 1618866 qualifiableelement - 1618961 + 1618866 qualifyingelement - 79675 + 79653 location - 282719 + 282705 @@ -29104,7 +28924,7 @@ 1 2 - 1618961 + 1618866 @@ -29120,7 +28940,7 @@ 1 2 - 1618961 + 1618866 @@ -29136,7 +28956,7 @@ 1 2 - 1618961 + 1618866 @@ -29152,7 +28972,7 @@ 1 2 - 1618961 + 1618866 @@ -29168,7 +28988,7 @@ 1 2 - 1618961 + 1618866 @@ -29184,7 +29004,7 @@ 1 2 - 1618961 + 1618866 @@ -29200,12 +29020,12 @@ 1 2 - 45546 + 45526 2 3 - 17163 + 17162 3 @@ -29236,12 +29056,12 @@ 1 2 - 45546 + 45526 2 3 - 17163 + 17162 3 @@ -29272,7 +29092,7 @@ 1 2 - 49725 + 49704 2 @@ -29308,32 +29128,32 @@ 1 2 - 91742 + 91737 2 3 - 25646 + 25644 3 4 - 42179 + 42177 4 6 - 12895 + 12894 6 7 - 89869 + 89865 7 2135 - 20387 + 20386 @@ -29349,32 +29169,32 @@ 1 2 - 91742 + 91737 2 3 - 25646 + 25644 3 4 - 42179 + 42177 4 6 - 12895 + 12894 6 7 - 89869 + 89865 7 2135 - 20387 + 20386 @@ -29390,17 +29210,17 @@ 1 2 - 125168 + 125162 2 3 - 52354 + 52352 3 4 - 96622 + 96618 4 @@ -29415,11 +29235,11 @@ varbind - 6006364 + 6006368 expr - 6006364 + 6006368 var @@ -29437,7 +29257,7 @@ 1 2 - 6006364 + 6006368 @@ -29508,15 +29328,15 @@ funbind - 3080553 + 3080676 expr - 3076933 + 3077056 fun - 514055 + 514013 @@ -29530,7 +29350,7 @@ 1 2 - 3073313 + 3073437 2 @@ -29551,32 +29371,32 @@ 1 2 - 306582 + 306531 2 3 - 78775 + 78789 3 4 - 37226 + 37224 4 7 - 43475 + 43473 7 38 - 38703 + 38701 38 4943 - 9293 + 9292 @@ -29586,11 +29406,11 @@ expr_allocator - 46541 + 46514 expr - 46541 + 46514 func @@ -29612,7 +29432,7 @@ 1 2 - 46541 + 46514 @@ -29628,7 +29448,7 @@ 1 2 - 46541 + 46514 @@ -29712,11 +29532,11 @@ expr_deallocator - 55314 + 55282 expr - 55314 + 55282 func @@ -29738,7 +29558,7 @@ 1 2 - 55314 + 55282 @@ -29754,7 +29574,7 @@ 1 2 - 55314 + 55282 @@ -29907,15 +29727,15 @@ expr_cond_true - 654499 + 654500 cond - 654499 + 654500 true - 654499 + 654500 @@ -29929,7 +29749,7 @@ 1 2 - 654499 + 654500 @@ -29945,7 +29765,7 @@ 1 2 - 654499 + 654500 @@ -30003,11 +29823,11 @@ values - 10646146 + 10646153 id - 10646146 + 10646153 str @@ -30025,7 +29845,7 @@ 1 2 - 10646146 + 10646153 @@ -30071,15 +29891,15 @@ valuetext - 4756729 + 4756702 id - 4756729 + 4756702 text - 703924 + 703921 @@ -30093,7 +29913,7 @@ 1 2 - 4756729 + 4756702 @@ -30114,17 +29934,17 @@ 2 3 - 102489 + 102490 3 7 - 56759 + 56757 7 425881 - 17147 + 17145 @@ -30134,15 +29954,15 @@ valuebind - 11083050 + 11083057 val - 10646146 + 10646153 expr - 11083050 + 11083057 @@ -30156,7 +29976,7 @@ 1 2 - 10232022 + 10232029 2 @@ -30177,7 +29997,7 @@ 1 2 - 11083050 + 11083057 @@ -30388,11 +30208,11 @@ bitfield - 20936 + 20941 id - 20936 + 20941 bits @@ -30414,7 +30234,7 @@ 1 2 - 20936 + 20941 @@ -30430,7 +30250,7 @@ 1 2 - 20936 + 20941 @@ -30574,23 +30394,23 @@ initialisers - 1731824 + 1732353 init - 1731824 + 1732353 var - 717748 + 721222 expr - 1731824 + 1732353 location - 390436 + 390438 @@ -30604,7 +30424,7 @@ 1 2 - 1731824 + 1732353 @@ -30620,7 +30440,7 @@ 1 2 - 1731824 + 1732353 @@ -30636,7 +30456,7 @@ 1 2 - 1731824 + 1732353 @@ -30652,22 +30472,17 @@ 1 2 - 629392 + 632463 2 16 - 31625 + 32109 16 25 - 56686 - - - 25 - 112 - 44 + 56649 @@ -30683,22 +30498,17 @@ 1 2 - 629392 + 632463 2 16 - 31625 + 32109 16 25 - 56686 - - - 25 - 112 - 44 + 56649 @@ -30714,12 +30524,12 @@ 1 2 - 717666 + 721215 2 - 4 - 81 + 3 + 6 @@ -30735,7 +30545,7 @@ 1 2 - 1731824 + 1732353 @@ -30751,7 +30561,7 @@ 1 2 - 1731824 + 1732353 @@ -30767,7 +30577,7 @@ 1 2 - 1731824 + 1732353 @@ -30783,7 +30593,7 @@ 1 2 - 317956 + 317957 2 @@ -30798,7 +30608,7 @@ 15 111459 - 17855 + 17856 @@ -30814,17 +30624,17 @@ 1 2 - 340955 + 340698 2 4 - 35579 + 35642 4 12738 - 13901 + 14096 @@ -30840,7 +30650,7 @@ 1 2 - 317956 + 317957 2 @@ -30855,7 +30665,7 @@ 15 111459 - 17855 + 17856 @@ -30876,15 +30686,15 @@ expr_ancestor - 121674 + 121668 exp - 121674 + 121668 ancestor - 84880 + 84876 @@ -30898,7 +30708,7 @@ 1 2 - 121674 + 121668 @@ -30914,12 +30724,12 @@ 1 2 - 61377 + 61374 2 3 - 16785 + 16784 3 @@ -30939,19 +30749,19 @@ exprs - 18300140 + 18300152 id - 18300140 + 18300152 kind - 3382 + 3380 location - 3561673 + 3559831 @@ -30965,7 +30775,7 @@ 1 2 - 18300140 + 18300152 @@ -30981,7 +30791,7 @@ 1 2 - 18300140 + 18300152 @@ -31050,13 +30860,13 @@ 281 - 6591 - 63491 + 6528 + 63599 281 - 78915 - 109590 + 79044 + 109592 70 @@ -31127,11 +30937,11 @@ 1051 - 14609 + 14618 281 - 16974 + 16981 32757 140 @@ -31149,32 +30959,32 @@ 1 2 - 1936933 + 1935551 2 3 - 816932 + 816946 3 4 - 247260 + 247397 4 8 - 280872 + 280461 8 - 136 - 267131 + 137 + 267010 - 136 + 137 54140 - 12542 + 12464 @@ -31190,22 +31000,22 @@ 1 2 - 2363808 + 2362352 2 3 - 873691 + 873426 3 6 - 307261 + 307151 6 25 - 16911 + 16901 @@ -31215,15 +31025,15 @@ expr_types - 18357789 + 18357798 id - 18300140 + 18300152 typeid - 829282 + 829243 value_category @@ -31241,12 +31051,12 @@ 1 2 - 18242562 + 18242577 2 5 - 57577 + 57574 @@ -31262,7 +31072,7 @@ 1 2 - 18300140 + 18300152 @@ -31278,42 +31088,42 @@ 1 2 - 293470 + 292376 2 3 - 160720 + 161054 3 4 - 69824 + 70343 4 5 - 60801 + 60978 5 7 - 66996 + 66993 7 12 - 65321 + 65336 12 35 - 62638 + 62653 35 - 78674 - 49509 + 78689 + 49506 @@ -31329,12 +31139,12 @@ 1 2 - 716180 + 715462 2 3 - 102314 + 102993 3 @@ -31353,18 +31163,18 @@ 12 - 11828 - 11829 + 11826 + 11827 18 - 253738 - 253739 + 253755 + 253756 18 - 750551 - 750552 + 750585 + 750586 18 @@ -31379,18 +31189,18 @@ 12 - 1446 - 1447 + 1484 + 1485 18 - 11978 - 11979 + 11980 + 11981 18 - 39501 - 39502 + 39499 + 39500 18 @@ -31401,15 +31211,15 @@ new_allocated_type - 47598 + 47571 expr - 47598 + 47571 type_id - 28150 + 28134 @@ -31423,7 +31233,7 @@ 1 2 - 47598 + 47571 @@ -31439,17 +31249,17 @@ 1 2 - 11767 + 11760 2 3 - 14903 + 14894 3 19 - 1479 + 1478 @@ -32069,15 +31879,15 @@ condition_decl_bind - 38595 + 38593 expr - 38595 + 38593 decl - 38595 + 38593 @@ -32091,7 +31901,7 @@ 1 2 - 38595 + 38593 @@ -32107,7 +31917,7 @@ 1 2 - 38595 + 38593 @@ -32117,15 +31927,15 @@ typeid_bind - 36430 + 36408 expr - 36430 + 36408 type_id - 16383 + 16373 @@ -32139,7 +31949,7 @@ 1 2 - 36430 + 36408 @@ -32155,7 +31965,7 @@ 1 2 - 15960 + 15950 3 @@ -32354,11 +32164,11 @@ lambdas - 21639 + 21640 expr - 21639 + 21640 default_capture @@ -32380,7 +32190,7 @@ 1 2 - 21639 + 21640 @@ -32396,7 +32206,7 @@ 1 2 - 21639 + 21640 @@ -32470,15 +32280,15 @@ lambda_capture - 28224 + 28226 id - 28224 + 28226 lambda - 20698 + 20699 index @@ -32486,7 +32296,7 @@ field - 28224 + 28226 captured_by_reference @@ -32512,7 +32322,7 @@ 1 2 - 28224 + 28226 @@ -32528,7 +32338,7 @@ 1 2 - 28224 + 28226 @@ -32544,7 +32354,7 @@ 1 2 - 28224 + 28226 @@ -32560,7 +32370,7 @@ 1 2 - 28224 + 28226 @@ -32576,7 +32386,7 @@ 1 2 - 28224 + 28226 @@ -32592,7 +32402,7 @@ 1 2 - 28224 + 28226 @@ -32608,12 +32418,12 @@ 1 2 - 13171 + 13172 2 3 - 7526 + 7527 @@ -32629,12 +32439,12 @@ 1 2 - 13171 + 13172 2 3 - 7526 + 7527 @@ -32650,12 +32460,12 @@ 1 2 - 13171 + 13172 2 3 - 7526 + 7527 @@ -32671,7 +32481,7 @@ 1 2 - 20698 + 20699 @@ -32687,7 +32497,7 @@ 1 2 - 20698 + 20699 @@ -32703,12 +32513,12 @@ 1 2 - 13171 + 13172 2 3 - 7526 + 7527 @@ -32840,7 +32650,7 @@ 1 2 - 28224 + 28226 @@ -32856,7 +32666,7 @@ 1 2 - 28224 + 28226 @@ -32872,7 +32682,7 @@ 1 2 - 28224 + 28226 @@ -32888,7 +32698,7 @@ 1 2 - 28224 + 28226 @@ -32904,7 +32714,7 @@ 1 2 - 28224 + 28226 @@ -32920,7 +32730,7 @@ 1 2 - 28224 + 28226 @@ -33349,19 +33159,19 @@ stmts - 4660299 + 4661289 id - 4660299 + 4661289 kind - 1988 + 1989 location - 2286915 + 2287401 @@ -33375,7 +33185,7 @@ 1 2 - 4660299 + 4661289 @@ -33391,7 +33201,7 @@ 1 2 - 4660299 + 4661289 @@ -33619,22 +33429,22 @@ 1 2 - 1892154 + 1892555 2 4 - 175972 + 176010 4 12 - 176182 + 176219 12 699 - 42606 + 42615 @@ -33650,12 +33460,12 @@ 1 2 - 2229653 + 2230127 2 8 - 57261 + 57274 @@ -33953,15 +33763,15 @@ constexpr_if_then - 52551 + 52562 constexpr_if_stmt - 52551 + 52562 then_id - 52551 + 52562 @@ -33975,7 +33785,7 @@ 1 2 - 52551 + 52562 @@ -33991,7 +33801,7 @@ 1 2 - 52551 + 52562 @@ -34001,15 +33811,15 @@ constexpr_if_else - 30881 + 30888 constexpr_if_stmt - 30881 + 30888 else_id - 30881 + 30888 @@ -34023,7 +33833,7 @@ 1 2 - 30881 + 30888 @@ -34039,7 +33849,7 @@ 1 2 - 30881 + 30888 @@ -34049,15 +33859,15 @@ while_body - 30207 + 30201 while_stmt - 30207 + 30201 body_id - 30207 + 30201 @@ -34071,7 +33881,7 @@ 1 2 - 30207 + 30201 @@ -34087,7 +33897,7 @@ 1 2 - 30207 + 30201 @@ -34097,15 +33907,15 @@ do_body - 148604 + 148599 do_stmt - 148604 + 148599 body_id - 148604 + 148599 @@ -34119,7 +33929,7 @@ 1 2 - 148604 + 148599 @@ -34135,7 +33945,7 @@ 1 2 - 148604 + 148599 @@ -34193,7 +34003,7 @@ switch_case - 191408 + 191399 switch_stmt @@ -34205,7 +34015,7 @@ case_id - 191408 + 191399 @@ -34361,7 +34171,7 @@ 32 33 - 1909 + 1908 33 @@ -34402,7 +34212,7 @@ 32 33 - 1909 + 1908 33 @@ -34433,7 +34243,7 @@ 1 2 - 191408 + 191399 @@ -34449,7 +34259,7 @@ 1 2 - 191408 + 191399 @@ -34699,19 +34509,19 @@ stmtparents - 4052305 + 4052323 id - 4052305 + 4052323 index - 12209 + 12210 parent - 1719463 + 1719470 @@ -34725,7 +34535,7 @@ 1 2 - 4052305 + 4052323 @@ -34741,7 +34551,7 @@ 1 2 - 4052305 + 4052323 @@ -34879,12 +34689,12 @@ 1 2 - 987317 + 987321 2 3 - 372963 + 372965 3 @@ -34894,7 +34704,7 @@ 4 6 - 111241 + 111242 6 @@ -34920,12 +34730,12 @@ 1 2 - 987317 + 987321 2 3 - 372963 + 372965 3 @@ -34935,7 +34745,7 @@ 4 6 - 111241 + 111242 6 @@ -34955,11 +34765,11 @@ ishandler - 59432 + 59429 block - 59432 + 59429 @@ -35528,15 +35338,15 @@ blockscope - 1438063 + 1438137 block - 1438063 + 1438137 enclosing - 1321870 + 1321939 @@ -35550,7 +35360,7 @@ 1 2 - 1438063 + 1438137 @@ -35566,12 +35376,12 @@ 1 2 - 1256011 + 1256077 2 13 - 65858 + 65861 @@ -35581,19 +35391,19 @@ jumpinfo - 253995 + 253987 id - 253995 + 253987 str - 21152 + 21151 target - 53046 + 53044 @@ -35607,7 +35417,7 @@ 1 2 - 253995 + 253987 @@ -35623,7 +35433,7 @@ 1 2 - 253995 + 253987 @@ -35685,7 +35495,7 @@ 1 2 - 16717 + 16716 2 @@ -35721,7 +35531,7 @@ 2 3 - 26428 + 26427 3 @@ -35736,7 +35546,7 @@ 5 8 - 4691 + 4690 8 @@ -35757,7 +35567,7 @@ 1 2 - 53046 + 53044 @@ -35767,19 +35577,19 @@ preprocdirects - 4431252 + 4432193 id - 4431252 + 4432193 kind - 1046 + 1047 location - 4428739 + 4429680 @@ -35793,7 +35603,7 @@ 1 2 - 4431252 + 4432193 @@ -35809,7 +35619,7 @@ 1 2 - 4431252 + 4432193 @@ -35947,7 +35757,7 @@ 1 2 - 4428635 + 4429575 25 @@ -35968,7 +35778,7 @@ 1 2 - 4428739 + 4429680 @@ -35978,15 +35788,15 @@ preprocpair - 1442296 + 1442371 begin - 1206147 + 1206210 elseelifend - 1442296 + 1442371 @@ -36000,12 +35810,12 @@ 1 2 - 985992 + 986044 2 3 - 209805 + 209816 3 @@ -36026,7 +35836,7 @@ 1 2 - 1442296 + 1442371 @@ -36036,41 +35846,41 @@ preproctrue - 782302 + 783284 branch - 782302 + 783284 preprocfalse - 327409 + 326956 branch - 327409 + 326956 preproctext - 3572638 + 3573396 id - 3572638 + 3573396 head - 2591544 + 2592094 body - 1515816 + 1516138 @@ -36084,7 +35894,7 @@ 1 2 - 3572638 + 3573396 @@ -36100,7 +35910,7 @@ 1 2 - 3572638 + 3573396 @@ -36116,12 +35926,12 @@ 1 2 - 2444464 + 2444983 2 740 - 147080 + 147111 @@ -36137,12 +35947,12 @@ 1 2 - 2529362 + 2529899 2 5 - 62181 + 62195 @@ -36158,17 +35968,17 @@ 1 2 - 1372191 + 1372482 2 6 - 113686 + 113710 6 11572 - 29939 + 29945 @@ -36184,17 +35994,17 @@ 1 2 - 1375227 + 1375519 2 7 - 114000 + 114024 7 2959 - 26589 + 26595 @@ -36204,15 +36014,15 @@ includes - 315649 + 315665 id - 315649 + 315665 included - 118074 + 118080 @@ -36226,7 +36036,7 @@ 1 2 - 315649 + 315665 @@ -36242,12 +36052,12 @@ 1 2 - 61624 + 61627 2 3 - 22109 + 22110 3 @@ -36262,7 +36072,7 @@ 6 14 - 8937 + 8938 14 @@ -36325,11 +36135,11 @@ link_parent - 40143068 + 40119536 element - 5115983 + 5112984 link_target @@ -36347,17 +36157,17 @@ 1 2 - 701934 + 701522 2 9 - 44146 + 44120 9 10 - 4369903 + 4367341 diff --git a/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/old.dbscheme b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/old.dbscheme new file mode 100644 index 00000000000..19e31bf071f --- /dev/null +++ b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/old.dbscheme @@ -0,0 +1,2115 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * 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: + * + * gcc -c f1.c f2.c f3.c + */ + 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 + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#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 + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_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( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int 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 +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: 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 +); + +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 +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target 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; diff --git a/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..23f7cbb88a4 --- /dev/null +++ b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/semmlecode.cpp.dbscheme @@ -0,0 +1,2125 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * 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: + * + * gcc -c f1.c f2.c f3.c + */ + 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 + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#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 + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_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( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int 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 +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: 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 +); + +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 +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target 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; diff --git a/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/upgrade.properties b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/upgrade.properties new file mode 100644 index 00000000000..db0e7e92d0e --- /dev/null +++ b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/upgrade.properties @@ -0,0 +1,2 @@ +description: Add new builtin operations +compatibility: backwards diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 449af46b6b8..e87fc5dce39 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package. + +## 0.2.0 + ## 0.1.4 ## 0.1.3 diff --git a/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql b/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql index dee723e2686..3cbcffe0ce3 100644 --- a/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql +++ b/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql @@ -44,7 +44,7 @@ predicate whiteListWrapped(FunctionCall fc) { from FunctionCall c, FloatingPointType t1, IntegralType t2 where - t1 = c.getTarget().getType().getUnderlyingType() and + pragma[only_bind_into](t1) = c.getTarget().getType().getUnderlyingType() and t2 = c.getActualType() and c.hasImplicitConversion() and not whiteListWrapped(c) diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.ql b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.ql index 30664869adc..9c0230d7514 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.ql @@ -10,7 +10,6 @@ * @precision medium * @tags security * external/cwe/cwe-480 - * external/microsoft/c6317 */ import cpp diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql b/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql index 074c82bc03b..8770d249497 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql @@ -7,8 +7,7 @@ * @problem.severity error * @precision high * @id cpp/string-copy-return-value-as-boolean - * @tags external/microsoft/C6324 - * correctness + * @tags correctness */ import cpp diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql index 5e3af347821..9646d8b3adf 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql @@ -7,7 +7,6 @@ * @id cpp/inconsistent-loop-direction * @tags correctness * external/cwe/cwe-835 - * external/microsoft/6293 * @msrc.severity important */ diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql index c72e25f61df..7eab1bd03c8 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql @@ -18,7 +18,7 @@ import semmle.code.cpp.ir.IR import semmle.code.cpp.ir.dataflow.MustFlow import PathGraph -/** Holds if `f` has a name that we intrepret as evidence of intentionally returning the value of the stack pointer. */ +/** Holds if `f` has a name that we interpret as evidence of intentionally returning the value of the stack pointer. */ predicate intentionallyReturnsStackPointer(Function f) { f.getName().toLowerCase().matches(["%stack%", "%sp%"]) } @@ -74,13 +74,12 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { from MustFlowPathNode source, MustFlowPathNode sink, VariableAddressInstruction var, - ReturnStackAllocatedMemoryConfig conf, Function f + ReturnStackAllocatedMemoryConfig conf where - conf.hasFlowPath(source, sink) and + conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and source.getNode().asInstruction() = var and // Only raise an alert if we're returning from the _same_ callable as the on that // declared the stack variable. - var.getEnclosingFunction() = pragma[only_bind_into](f) and - sink.getNode().getEnclosingCallable() = pragma[only_bind_into](f) + var.getEnclosingFunction() = sink.getNode().getEnclosingCallable() select sink.getNode(), source, sink, "May return stack-allocated memory from $@.", var.getAst(), var.getAst().toString() diff --git a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql index 27aeabbaf49..3f3997315d4 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql @@ -133,7 +133,9 @@ TGlobalAddress globalAddress(Instruction instr) { ) or exists(FieldAddressInstruction fai | instr = fai | - result = TFieldAddress(globalAddress(fai.getObjectAddress()), fai.getField()) + result = + TFieldAddress(globalAddress(pragma[only_bind_into](fai.getObjectAddress())), + pragma[only_bind_out](fai.getField())) ) or result = globalAddress(instr.(PointerOffsetInstruction).getLeft()) diff --git a/cpp/ql/src/Likely Bugs/UseInOwnInitializer.ql b/cpp/ql/src/Likely Bugs/UseInOwnInitializer.ql index 6bb411b7844..054fdccbb99 100644 --- a/cpp/ql/src/Likely Bugs/UseInOwnInitializer.ql +++ b/cpp/ql/src/Likely Bugs/UseInOwnInitializer.ql @@ -15,6 +15,7 @@ class VariableAccessInInitializer extends VariableAccess { Variable var; Initializer init; + pragma[nomagic] VariableAccessInInitializer() { init.getDeclaration() = var and init.getExpr().getAChild*() = this diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql index 73fcf034096..7a3877f638c 100644 --- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql @@ -77,7 +77,7 @@ class ExecState extends DataFlow::FlowState { ExecState() { this = "ExecState (" + fst.getLocation() + " | " + fst + ", " + snd.getLocation() + " | " + snd + ")" and - interestingConcatenation(fst, snd) + interestingConcatenation(pragma[only_bind_into](fst), pragma[only_bind_into](snd)) } DataFlow::Node getFstNode() { result = fst } diff --git a/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql index 67ba5b0c45b..eb746e2d1d2 100644 --- a/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql @@ -8,11 +8,6 @@ * @precision high * @tags security * external/cwe/cwe-253 - * external/microsoft/C6214 - * external/microsoft/C6215 - * external/microsoft/C6216 - * external/microsoft/C6217 - * external/microsoft/C6230 */ import cpp diff --git a/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql b/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql index 7c540e9d313..ff8e85cecec 100644 --- a/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql +++ b/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql @@ -9,7 +9,6 @@ * @msrc.severity important * @tags security * external/cwe/cwe-428 - * external/microsoft/C6277 */ import cpp diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index 65551a1f138..aee4f3c8405 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -10,7 +10,6 @@ * @precision high * @tags security * external/cwe/cwe-704 - * external/microsoft/c/c6276 */ import cpp diff --git a/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql b/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql index 81998bda450..482b5daf992 100644 --- a/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql +++ b/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql @@ -11,7 +11,6 @@ * @precision high * @tags security * external/cwe/cwe-732 - * external/microsoft/C6248 */ import cpp diff --git a/cpp/ql/src/change-notes/released/0.2.0.md b/cpp/ql/src/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..79a5f33514f --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.2.0.md @@ -0,0 +1 @@ +## 0.2.0 diff --git a/cpp/ql/src/change-notes/released/0.3.0.md b/cpp/ql/src/change-notes/released/0.3.0.md new file mode 100644 index 00000000000..75d99f333c9 --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.3.0.md @@ -0,0 +1,5 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index e8ee3af8ef9..95f6e3a0ba6 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.3.0 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index a373e4717d8..2735b4d5289 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.2.0-dev +version: 0.3.1-dev groups: - cpp - queries diff --git a/cpp/ql/test/library-tests/builtins/edg/edg.c b/cpp/ql/test/library-tests/builtins/edg/edg.c index d1a78435317..f1f0f0f1375 100644 --- a/cpp/ql/test/library-tests/builtins/edg/edg.c +++ b/cpp/ql/test/library-tests/builtins/edg/edg.c @@ -1,4 +1,4 @@ - +// semmle-extractor-options: --clang struct mystruct { int f1; int f2; @@ -13,3 +13,6 @@ void f(void) { int i2 = edg_offsetof(struct mystruct,f2); } +void g(void) { + double f = __builtin_bit_cast(double,42l); +} diff --git a/cpp/ql/test/library-tests/builtins/edg/expr.expected b/cpp/ql/test/library-tests/builtins/edg/expr.expected index 0969dc1e217..5ab0747ecc7 100644 --- a/cpp/ql/test/library-tests/builtins/edg/expr.expected +++ b/cpp/ql/test/library-tests/builtins/edg/expr.expected @@ -13,3 +13,6 @@ | edg.c:13:14:13:45 | (size_t)... | 0 | 0 | | edg.c:13:14:13:45 | __INTADDR__ | 1 | 1 | | edg.c:13:43:13:44 | f2 | 0 | 0 | +| edg.c:17:16:17:45 | __builtin_bit_cast | 1 | 1 | +| edg.c:17:16:17:45 | double | 0 | 0 | +| edg.c:17:42:17:44 | 42 | 1 | 1 | diff --git a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected index 47918496198..a19d917aaac 100644 --- a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected +++ b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected @@ -296,3 +296,20 @@ | ms.cpp:255:24:255:43 | a_struct | | | | ms.cpp:256:24:256:49 | __is_final | a_final_struct | 1 | | ms.cpp:256:24:256:49 | a_final_struct | | | +| ms.cpp:258:29:258:62 | __is_assignable | a_struct,a_struct | 1 | +| ms.cpp:258:29:258:62 | a_struct | | | +| ms.cpp:258:29:258:62 | a_struct | | | +| ms.cpp:259:29:259:59 | __is_assignable | a_struct,empty | 0 | +| ms.cpp:259:29:259:59 | a_struct | | | +| ms.cpp:259:29:259:59 | empty | | | +| ms.cpp:260:29:260:57 | __is_assignable | a_struct,int | 0 | +| ms.cpp:260:29:260:57 | a_struct | | | +| ms.cpp:260:29:260:57 | int | | | +| ms.cpp:262:28:262:51 | __is_aggregate | a_struct | 1 | +| ms.cpp:262:28:262:51 | a_struct | | | +| ms.cpp:263:28:263:46 | __is_aggregate | int | 0 | +| ms.cpp:263:28:263:46 | int | | | +| ms.cpp:265:49:265:88 | __has_unique_object_representations | int | 1 | +| ms.cpp:265:49:265:88 | int | | | +| ms.cpp:266:49:266:90 | __has_unique_object_representations | float | 0 | +| ms.cpp:266:49:266:90 | float | | | diff --git a/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp b/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp index 742f95faf07..91d6245cc35 100644 --- a/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp +++ b/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp @@ -254,5 +254,14 @@ void f(void) { bool b_is_final1 = __is_final(a_struct); bool b_is_final2 = __is_final(a_final_struct); -} + bool b_is_assignable1 = __is_assignable(a_struct,a_struct); + bool b_is_assignable2 = __is_assignable(a_struct,empty); + bool b_is_assignable3 = __is_assignable(a_struct,int); + + bool b_is_aggregate1 = __is_aggregate(a_struct); + bool b_is_aggregate2 = __is_aggregate(int); + + bool b_has_unique_object_representations1 = __has_unique_object_representations(int); + bool b_has_unique_object_representations2 = __has_unique_object_representations(float); +} diff --git a/cpp/ql/test/library-tests/controlflow/nullness/nullness.expected b/cpp/ql/test/library-tests/controlflow/nullness/nullness.expected new file mode 100644 index 00000000000..bcf301ba47b --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/nullness/nullness.expected @@ -0,0 +1,20 @@ +| test.cpp:9:9:9:9 | v | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:10:9:10:10 | ! ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:11:9:11:14 | ... == ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:12:9:12:17 | ... == ... | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:13:9:13:14 | ... != ... | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:14:9:14:17 | ... != ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:15:8:15:23 | call to __builtin_expect | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:16:8:16:23 | call to __builtin_expect | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:17:9:17:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:18:9:18:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:19:9:19:18 | ... && ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:20:9:20:18 | ... && ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:21:9:21:14 | ... = ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:21:9:21:14 | ... = ... | test.cpp:7:10:7:10 | b | is not null | is valid | +| test.cpp:22:9:22:14 | ... = ... | test.cpp:5:13:5:13 | v | is not null | is not valid | +| test.cpp:22:9:22:14 | ... = ... | test.cpp:7:13:7:13 | c | is not null | is not valid | +| test.cpp:22:17:22:17 | c | test.cpp:7:13:7:13 | c | is not null | is valid | +| test.cpp:23:21:23:21 | x | test.cpp:23:14:23:14 | x | is not null | is valid | +| test.cpp:24:9:24:18 | (condition decl) | test.cpp:5:13:5:13 | v | is not null | is not valid | +| test.cpp:24:9:24:18 | (condition decl) | test.cpp:24:14:24:14 | y | is not null | is valid | diff --git a/cpp/ql/test/library-tests/controlflow/nullness/nullness.ql b/cpp/ql/test/library-tests/controlflow/nullness/nullness.ql new file mode 100644 index 00000000000..864fd04f920 --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/nullness/nullness.ql @@ -0,0 +1,8 @@ +import cpp + +from AnalysedExpr a, LocalScopeVariable v, string isNullCheck, string isValidCheck +where + v.getAnAccess().getEnclosingStmt() = a.getParent() and + (if a.isNullCheck(v) then isNullCheck = "is null" else isNullCheck = "is not null") and + (if a.isValidCheck(v) then isValidCheck = "is valid" else isValidCheck = "is not valid") +select a, v, isNullCheck, isValidCheck diff --git a/cpp/ql/test/library-tests/controlflow/nullness/test.cpp b/cpp/ql/test/library-tests/controlflow/nullness/test.cpp new file mode 100644 index 00000000000..407753be17a --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/nullness/test.cpp @@ -0,0 +1,25 @@ +// semmle-extractor-options: -std=c++17 + +long __builtin_expect(long); + +void f(int *v) { + int *w; + bool b, c; + + if (v) {} + if (!v) {} + if (v == 0) {} + if ((!v) == 0) {} + if (v != 0) {} + if ((!v) != 0) {} + if(__builtin_expect((long)v)) {} + if(__builtin_expect((long)!v)) {} + if (true && v) {} + if (v && true) {} + if (true && !v) {} + if (!v && true) {} + if (b = !v) {} + if (c = !v; c) {} + if (int *x = v; x) {} + if (int *y = v) {} +} diff --git a/cpp/ql/test/library-tests/variables/global/variables.expected b/cpp/ql/test/library-tests/variables/global/variables.expected index d66899e62fa..9d022a98264 100644 --- a/cpp/ql/test/library-tests/variables/global/variables.expected +++ b/cpp/ql/test/library-tests/variables/global/variables.expected @@ -4,11 +4,7 @@ | c.c:6:5:6:6 | ls | array of 4 {int} | 1 | | c.c:8:5:8:7 | iss | array of 4 {array of 2 {int}} | 1 | | c.c:12:11:12:11 | i | typedef {int} as "int_alias" | 1 | -| c.h:4:12:4:13 | ks | array of {int} | 1 | -| c.h:8:12:8:14 | iss | array of {array of 2 {int}} | 1 | -| c.h:10:12:10:12 | i | int | 1 | | d.cpp:3:7:3:8 | xs | array of {int} | 1 | -| d.h:3:14:3:15 | xs | array of 2 {int} | 1 | | file://:0:0:0:0 | (unnamed parameter 0) | reference to {const {struct __va_list_tag}} | 1 | | file://:0:0:0:0 | (unnamed parameter 0) | rvalue reference to {struct __va_list_tag} | 1 | | file://:0:0:0:0 | fp_offset | unsigned int | 1 | diff --git a/cpp/ql/test/library-tests/vector_types/builtin_ops.expected b/cpp/ql/test/library-tests/vector_types/builtin_ops.expected index 2c0dd9d0017..756ca2f1c17 100644 --- a/cpp/ql/test/library-tests/vector_types/builtin_ops.expected +++ b/cpp/ql/test/library-tests/vector_types/builtin_ops.expected @@ -1,2 +1,4 @@ +| vector_types2.cpp:10:15:10:42 | __builtin_shuffle | +| vector_types2.cpp:11:15:11:45 | __builtin_shuffle | | vector_types.cpp:31:13:31:49 | __builtin_shufflevector | | vector_types.cpp:58:10:58:52 | __builtin_convertvector | diff --git a/cpp/ql/test/library-tests/vector_types/variables.expected b/cpp/ql/test/library-tests/vector_types/variables.expected index 2494f192e9a..52fa98dd3f0 100644 --- a/cpp/ql/test/library-tests/vector_types/variables.expected +++ b/cpp/ql/test/library-tests/vector_types/variables.expected @@ -13,6 +13,12 @@ | file://:0:0:0:0 | gp_offset | gp_offset | file://:0:0:0:0 | unsigned int | 4 | | file://:0:0:0:0 | overflow_arg_area | overflow_arg_area | file://:0:0:0:0 | void * | 8 | | file://:0:0:0:0 | reg_save_area | reg_save_area | file://:0:0:0:0 | void * | 8 | +| vector_types2.cpp:5:7:5:7 | a | a | vector_types2.cpp:2:13:2:15 | v4i | 16 | +| vector_types2.cpp:6:7:6:7 | b | b | vector_types2.cpp:2:13:2:15 | v4i | 16 | +| vector_types2.cpp:7:7:7:12 | mask_1 | mask_1 | vector_types2.cpp:2:13:2:15 | v4i | 16 | +| vector_types2.cpp:8:7:8:12 | mask_2 | mask_2 | vector_types2.cpp:2:13:2:15 | v4i | 16 | +| vector_types2.cpp:10:7:10:11 | res_1 | res_1 | vector_types2.cpp:2:13:2:15 | v4i | 16 | +| vector_types2.cpp:11:7:11:11 | res_2 | res_2 | vector_types2.cpp:2:13:2:15 | v4i | 16 | | vector_types.cpp:9:21:9:21 | x | x | vector_types.cpp:6:15:6:17 | v4f | 16 | | vector_types.cpp:14:18:14:20 | lhs | lhs | vector_types.cpp:6:15:6:17 | v4f | 16 | | vector_types.cpp:14:27:14:29 | rhs | rhs | vector_types.cpp:6:15:6:17 | v4f | 16 | diff --git a/cpp/ql/test/library-tests/vector_types/vector_types2.cpp b/cpp/ql/test/library-tests/vector_types/vector_types2.cpp new file mode 100644 index 00000000000..d4233b28890 --- /dev/null +++ b/cpp/ql/test/library-tests/vector_types/vector_types2.cpp @@ -0,0 +1,12 @@ +// semmle-extractor-options: --gnu --gnu_version 80000 +typedef int v4i __attribute__((vector_size (16))); + +void f() { + v4i a = {1,2,3,4}; + v4i b = {5,6,7,8}; + v4i mask_1 = {3,0,1,2}; + v4i mask_2 = {3,5,4,2}; + + v4i res_1 = __builtin_shuffle(a, mask_1); + v4i res_2 = __builtin_shuffle(a, b, mask_2); +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/ImplicitDowncastFromBitfield.expected b/cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/LossyFunctionResultCast.expected similarity index 100% rename from cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/ImplicitDowncastFromBitfield.expected rename to cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/LossyFunctionResultCast.expected diff --git a/cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/ImplicitDowncastFromBitfield.qlref b/cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/LossyFunctionResultCast.qlref similarity index 100% rename from cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/ImplicitDowncastFromBitfield.qlref rename to cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/LossyFunctionResultCast.qlref diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 0bb47844d19..de0a7eeae4b 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.1 + +## 1.2.0 + ## 1.1.4 ## 1.1.3 diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.0.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.0.md new file mode 100644 index 00000000000..0ff42339575 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.0.md @@ -0,0 +1 @@ +## 1.2.0 diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.1.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.1.md new file mode 100644 index 00000000000..ddf8866b672 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.1.md @@ -0,0 +1 @@ +## 1.2.1 diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 26cbcd3f123..73dd403938c 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.1.4 +lastReleaseVersion: 1.2.1 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 9cb7bec181f..fc22389c2a8 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.2.0-dev +version: 1.2.2-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 0bb47844d19..de0a7eeae4b 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.1 + +## 1.2.0 + ## 1.1.4 ## 1.1.3 diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.0.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.0.md new file mode 100644 index 00000000000..0ff42339575 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.0.md @@ -0,0 +1 @@ +## 1.2.0 diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.1.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.1.md new file mode 100644 index 00000000000..ddf8866b672 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.1.md @@ -0,0 +1 @@ +## 1.2.1 diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 26cbcd3f123..73dd403938c 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.1.4 +lastReleaseVersion: 1.2.1 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 07419f1b469..a2ef81cc0e4 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.2.0-dev +version: 1.2.2-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 3df8b95eeb6..d1c89626798 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.3.1 + +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + ## 0.2.3 ## 0.2.2 diff --git a/csharp/ql/src/IDEContextual.qll b/csharp/ql/lib/IDEContextual.qll similarity index 100% rename from csharp/ql/src/IDEContextual.qll rename to csharp/ql/lib/IDEContextual.qll diff --git a/go/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/csharp/ql/lib/change-notes/released/0.3.0.md similarity index 83% rename from go/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md rename to csharp/ql/lib/change-notes/released/0.3.0.md index 2bd95798f89..54af6e00ac0 100644 --- a/go/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ b/csharp/ql/lib/change-notes/released/0.3.0.md @@ -1,4 +1,5 @@ ---- -category: deprecated ---- +## 0.3.0 + +### Deprecated APIs + * The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/csharp/ql/lib/change-notes/released/0.3.1.md b/csharp/ql/lib/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..2b0719929a1 --- /dev/null +++ b/csharp/ql/lib/change-notes/released/0.3.1.md @@ -0,0 +1 @@ +## 0.3.1 diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 0b605901b42..bb106b1cb63 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.3 +lastReleaseVersion: 0.3.1 diff --git a/csharp/ql/src/definitions.qll b/csharp/ql/lib/definitions.qll similarity index 100% rename from csharp/ql/src/definitions.qll rename to csharp/ql/lib/definitions.qll diff --git a/csharp/ql/src/localDefinitions.ql b/csharp/ql/lib/localDefinitions.ql similarity index 100% rename from csharp/ql/src/localDefinitions.ql rename to csharp/ql/lib/localDefinitions.ql diff --git a/csharp/ql/src/localReferences.ql b/csharp/ql/lib/localReferences.ql similarity index 100% rename from csharp/ql/src/localReferences.ql rename to csharp/ql/lib/localReferences.ql diff --git a/csharp/ql/src/printAst.ql b/csharp/ql/lib/printAst.ql similarity index 100% rename from csharp/ql/src/printAst.ql rename to csharp/ql/lib/printAst.ql diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 2e2d17e36fa..0d72cfc0c65 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.3.0-dev +version: 0.3.2-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp 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 47fcd24883c..7d0dd10c084 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll @@ -881,7 +881,12 @@ import Cached * graph is restricted to nodes from `RelevantNode`. */ module TestOutput { - abstract class RelevantNode extends Node { } + abstract class RelevantNode extends Node { + /** + * Gets a string used to resolve ties in node and edge ordering. + */ + string getOrderDisambuigation() { result = "" } + } query predicate nodes(RelevantNode n, string attr, string val) { attr = "semmle.order" and @@ -894,7 +899,8 @@ module TestOutput { p order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString(), + p.getOrderDisambuigation() ) ).toString() } @@ -916,7 +922,8 @@ module TestOutput { s order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString(), + s.getOrderDisambuigation() ) ).toString() } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll index b3f247ede94..f4c5596c973 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll @@ -1,11 +1,23 @@ /** * THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. - * Definitions of taint steps in the dotnetruntime framework. + * Definitions of taint steps in the Runtime framework. */ import csharp private import semmle.code.csharp.dataflow.ExternalFlow +private class RuntimeSinksCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + "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", + "System.Net.Http;StringContent;false;StringContent;(System.String);;Argument[0];xss;generated", + "System.Net.Http;StringContent;false;StringContent;(System.String,System.Text.Encoding);;Argument[0];xss;generated" + ] + } +} + private class RuntimeSummaryCsv extends SummaryModelCsv { override predicate row(string row) { row = @@ -529,11 +541,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.CodeDom.Compiler;GeneratedCodeAttribute;false;GeneratedCodeAttribute;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated", "System.CodeDom.Compiler;GeneratedCodeAttribute;false;get_Tool;();;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom.Compiler;GeneratedCodeAttribute;false;get_Version;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.CodeDom.Compiler;IndentedTextWriter;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom.Compiler;IndentedTextWriter;false;IndentedTextWriter;(System.IO.TextWriter,System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.CodeDom.Compiler;IndentedTextWriter;false;IndentedTextWriter;(System.IO.TextWriter,System.String);;Argument[1];Argument[Qualifier];taint;generated", - "System.CodeDom.Compiler;IndentedTextWriter;false;WriteLineNoTabsAsync;(System.String);;Argument[0];ReturnValue;taint;generated", - "System.CodeDom.Compiler;IndentedTextWriter;false;WriteLineNoTabsAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom.Compiler;IndentedTextWriter;false;get_Encoding;();;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom.Compiler;IndentedTextWriter;false;get_InnerWriter;();;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom.Compiler;IndentedTextWriter;false;get_NewLine;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -746,7 +755,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.CodeDom;CodeNamespaceImport;false;set_Namespace;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.CodeDom;CodeNamespaceImportCollection;false;Add;(System.CodeDom.CodeNamespaceImport);;Argument[0];Argument[Qualifier];taint;generated", "System.CodeDom;CodeNamespaceImportCollection;false;AddRange;(System.CodeDom.CodeNamespaceImport[]);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.CodeDom;CodeNamespaceImportCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom;CodeNamespaceImportCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom;CodeNamespaceImportCollection;false;set_Item;(System.Int32,System.CodeDom.CodeNamespaceImport);;Argument[1];Argument[Qualifier];taint;generated", "System.CodeDom;CodeObject;false;get_UserData;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -919,7 +927,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Concurrent;ConcurrentBag<>;false;TryAdd;(T);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.Concurrent;ConcurrentBag<>;false;TryPeek;(T);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Concurrent;ConcurrentBag<>;false;TryTake;(T);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetOrAdd;(TKey,TValue);;Argument[1];ReturnValue;taint;generated", "System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Concurrent;ConcurrentStack<>;false;ConcurrentStack;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", @@ -933,7 +940,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Concurrent;Partitioner;false;Create<>;(System.Collections.Generic.IEnumerable,System.Collections.Concurrent.EnumerablePartitionerOptions);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Concurrent;Partitioner;false;Create<>;(System.Collections.Generic.IList,System.Boolean);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Concurrent;Partitioner;false;Create<>;(TSource[],System.Boolean);;Argument[0].Element;ReturnValue;taint;generated", - "System.Collections.Generic;CollectionExtensions;false;AsReadOnly<,>;(System.Collections.Generic.IDictionary);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Generic;CollectionExtensions;false;AsReadOnly<>;(System.Collections.Generic.IList);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Generic;CollectionExtensions;false;GetDefaultAssets;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Generic;CollectionExtensions;false;GetDefaultGroup;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", @@ -945,9 +951,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[1];ReturnValue;taint;generated", "System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated", "System.Collections.Generic;CollectionExtensions;false;Remove<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;ReturnValue;taint;generated", - "System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;Argument[2];taint;generated", - "System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[1];Argument[0].Element;taint;generated", - "System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[2];Argument[0].Element;taint;generated", "System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Entry;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Key;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -967,8 +970,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Generic;HashSet<>;false;HashSet;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.Generic;HashSet<>;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Generic;HashSet<>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[1];ReturnValue;taint;generated", "System.Collections.Generic;KeyValuePair<,>;false;Deconstruct;(TKey,TValue);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Generic;KeyValuePair<,>;false;get_Key;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Generic;KeyValuePair<,>;false;get_Value;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -1120,12 +1121,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary;false;GetValueOrDefault<,>;(System.Collections.Immutable.IImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;taint;generated", @@ -1142,7 +1137,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableDictionary<,>+Builder;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>+Builder;false;set_KeyComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>+Builder;false;set_ValueComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated", - "System.Collections.Immutable;ImmutableDictionary<,>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>;false;Remove;(TKey);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>;false;RemoveRange;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>;false;SetItem;(TKey,TValue);;Argument[Qualifier];ReturnValue;taint;generated", @@ -1155,8 +1149,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableDictionary<,>;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Collections.Immutable;ImmutableDictionary<,>;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableHashSet;false;Create<>;(System.Collections.Generic.IEqualityComparer,T);;Argument[1];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableHashSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet;false;ToImmutableHashSet<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", @@ -1166,7 +1158,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableHashSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>+Builder;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>+Builder;false;set_KeyComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated", - "System.Collections.Immutable;ImmutableHashSet<>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>;false;Except;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>;false;Intersect;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>;false;Remove;(T);;Argument[Qualifier];ReturnValue;taint;generated", @@ -1179,9 +1170,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableHashSet<>;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Collections.Immutable;ImmutableInterlocked;false;GetOrAdd<,>;(System.Collections.Immutable.ImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableList;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableList;false;Create<>;(T[]);;Argument[0].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableList;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableList;false;Remove<>;(System.Collections.Immutable.IImmutableList,T);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableList;false;RemoveRange<>;(System.Collections.Immutable.IImmutableList,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableList;false;Replace<>;(System.Collections.Immutable.IImmutableList,T,T);;Argument[0].Element;ReturnValue;taint;generated", @@ -1240,12 +1228,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[1];ReturnValue;taint;generated", @@ -1262,8 +1244,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_KeyComparer;(System.Collections.Generic.IComparer);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_ValueComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Remove;(TKey);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;RemoveRange;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;SetItem;(TKey,TValue);;Argument[0];ReturnValue;taint;generated", @@ -1281,10 +1261,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[1];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T[]);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;CreateBuilder<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated", @@ -1294,7 +1271,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableSortedSet;false;ToImmutableSortedSet<>;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IComparer);;Argument[1];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;ToImmutableSortedSet<>;(System.Collections.Immutable.ImmutableSortedSet+Builder);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated", @@ -1305,13 +1281,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;set_KeyComparer;(System.Collections.Generic.IComparer);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>;false;Except;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>;false;ToBuilder;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated", @@ -1335,23 +1306,17 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableStack<>;false;Push;(T);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;Collection<>;false;Collection;(System.Collections.Generic.IList);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;Collection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;Collection<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;KeyedCollection;(System.Collections.Generic.IEqualityComparer,System.Int32);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;TryGetValue;(TKey,TItem);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;get_Dictionary;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;ReadOnlyCollection<>;false;ReadOnlyCollection;(System.Collections.Generic.IList);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Collections.ObjectModel;ReadOnlyCollection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;ReadOnlyCollection<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -1430,7 +1395,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections;BitArray;false;Xor;(System.Collections.BitArray);;Argument[Qualifier];ReturnValue;value;generated", "System.Collections;BitArray;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[0];Argument[Qualifier];taint;generated", - "System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[Qualifier];Argument[0];taint;generated", "System.Collections;CollectionBase;false;get_InnerList;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections;CollectionBase;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections;CollectionBase;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -1480,7 +1444,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections;Stack;false;Synchronized;(System.Collections.Stack);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections;Stack;false;ToArray;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections;Stack;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", - "System.ComponentModel.Composition.Hosting;AggregateCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AggregateCatalog;false;get_Catalogs;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AggregateExportProvider;false;AggregateExportProvider;(System.ComponentModel.Composition.Hosting.ExportProvider[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;AggregateExportProvider;false;GetExportsCore;(System.ComponentModel.Composition.Primitives.ImportDefinition,System.ComponentModel.Composition.Hosting.AtomicComposition);;Argument[Qualifier];ReturnValue;taint;generated", @@ -1489,7 +1452,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;ApplicationCatalog;(System.Reflection.ReflectionContext);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;ApplicationCatalog;(System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;ApplicationCatalog;(System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated", - "System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.Reflection.Assembly);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.Reflection.Assembly,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.Reflection.Assembly,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated", @@ -1502,7 +1464,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.String,System.Reflection.ReflectionContext);;Argument[1];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[2];Argument[Qualifier];taint;generated", - "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;get_Assembly;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;get_DisplayName;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -1539,7 +1500,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;CompositionScopeDefinition;(System.ComponentModel.Composition.Primitives.ComposablePartCatalog,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;CompositionScopeDefinition;(System.ComponentModel.Composition.Primitives.ComposablePartCatalog,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[1].Element;Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;CompositionScopeDefinition;(System.ComponentModel.Composition.Primitives.ComposablePartCatalog,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[2].Element;Argument[Qualifier];taint;generated", - "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;get_Children;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;get_PublicSurface;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated", @@ -1554,7 +1514,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[2];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[3];Argument[Qualifier];taint;generated", - "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;get_DisplayName;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;get_FullPath;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -1573,14 +1532,12 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel.Composition.Hosting;ExportsChangeEventArgs;false;get_AddedExports;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;ExportsChangeEventArgs;false;get_ChangedContractNames;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;ExportsChangeEventArgs;false;get_RemovedExports;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.ComponentModel.Composition.Hosting;FilteredCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;FilteredCatalog;false;get_Complement;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;ImportEngine;false;ImportEngine;(System.ComponentModel.Composition.Hosting.ExportProvider,System.ComponentModel.Composition.Hosting.CompositionOptions);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[2];Argument[Qualifier];taint;generated", - "System.ComponentModel.Composition.Primitives;ComposablePartCatalog;true;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Primitives;ComposablePartCatalog;true;get_Parts;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Primitives;ComposablePartException;false;ComposablePartException;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Primitives;ComposablePartException;false;ComposablePartException;(System.String,System.ComponentModel.Composition.Primitives.ICompositionElement,System.Exception);;Argument[1];Argument[Qualifier];taint;generated", @@ -1781,9 +1738,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[1];ReturnValue;taint;generated", "System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated", "System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.ComponentModel;CategoryAttribute;false;CategoryAttribute;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel;CategoryAttribute;false;get_Category;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel;CharConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated", @@ -1917,7 +1872,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel;ToolboxItemAttribute;false;get_ToolboxItemTypeName;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel;ToolboxItemFilterAttribute;false;get_TypeId;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel;TypeConverter+StandardValuesCollection;false;CopyTo;(System.Array,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated", - "System.ComponentModel;TypeConverter+StandardValuesCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel;TypeConverter+StandardValuesCollection;false;StandardValuesCollection;(System.Collections.ICollection);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.ComponentModel;TypeConverter+StandardValuesCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel;TypeConverter;false;ConvertFrom;(System.Object);;Argument[0];ReturnValue;taint;generated", @@ -2380,10 +2334,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Common;DataTableMappingCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Data.Common;DbCommand;false;ExecuteReader;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommand;false;ExecuteReader;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data.Common;DbCommand;false;ExecuteReaderAsync;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommand;false;get_Connection;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommand;false;get_Parameters;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommand;false;get_Transaction;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -2391,7 +2341,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Common;DbCommand;false;set_Connection;(System.Data.IDbConnection);;Argument[0];Argument[Qualifier];taint;generated", "System.Data.Common;DbCommand;false;set_Transaction;(System.Data.Common.DbTransaction);;Argument[0];Argument[Qualifier];taint;generated", "System.Data.Common;DbCommand;false;set_Transaction;(System.Data.IDbTransaction);;Argument[0];Argument[Qualifier];taint;generated", - "System.Data.Common;DbCommand;true;ExecuteDbDataReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommand;true;PrepareAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated", @@ -2418,7 +2367,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String);;Argument[2];Argument[0];taint;generated", "System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[1];Argument[0];taint;generated", "System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[2];Argument[0];taint;generated", - "System.Data.Common;DbConnectionStringBuilder;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbConnectionStringBuilder;false;GetProperties;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbConnectionStringBuilder;false;GetProperties;(System.Attribute[]);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbConnectionStringBuilder;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated", @@ -2445,12 +2393,9 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[0];ReturnValue;taint;generated", "System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[1];ReturnValue;taint;generated", "System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[3];ReturnValue;taint;generated", - "System.Data.Common;DbDataReader;false;GetFieldValueAsync<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbDataReader;true;GetFieldValue<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data.Common;DbDataReader;true;GetFieldValueAsync<>;(System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbDataReader;true;GetProviderSpecificValue;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbDataReader;true;GetProviderSpecificValues;(System.Object[]);;Argument[Qualifier];Argument[0].Element;taint;generated", - "System.Data.Common;DbDataReader;true;GetSchemaTableAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbDataReader;true;GetTextReader;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbDataRecord;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated", "System.Data.Common;DbEnumerator;false;DbEnumerator;(System.Data.IDataReader);;Argument[0];Argument[Qualifier];taint;generated", @@ -2595,7 +2540,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Odbc;OdbcParameter;false;set_Value;(System.Object);;Argument[0];Argument[Qualifier];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.Data.Odbc.OdbcParameter);;Argument[0];Argument[Qualifier];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.Data.Odbc.OdbcParameter);;Argument[0];ReturnValue;taint;generated", - "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.Data.Odbc.OdbcParameter);;Argument[Qualifier];Argument[0];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.String,System.Data.Odbc.OdbcType);;Argument[0];Argument[Qualifier];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.String,System.Data.Odbc.OdbcType);;Argument[0];ReturnValue;taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.String,System.Data.Odbc.OdbcType,System.Int32);;Argument[0];Argument[Qualifier];taint;generated", @@ -2617,7 +2561,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Odbc;OdbcParameterCollection;false;GetParameter;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;GetParameter;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Insert;(System.Int32,System.Data.Odbc.OdbcParameter);;Argument[1];Argument[Qualifier];taint;generated", - "System.Data.Odbc;OdbcParameterCollection;false;Insert;(System.Int32,System.Data.Odbc.OdbcParameter);;Argument[Qualifier];Argument[1];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;SetParameter;(System.Int32,System.Data.Common.DbParameter);;Argument[Qualifier];Argument[1];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;SetParameter;(System.String,System.Data.Common.DbParameter);;Argument[Qualifier];Argument[1];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", @@ -2729,15 +2672,11 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data;DataColumn;false;set_Prefix;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataColumnChangeEventArgs;false;DataColumnChangeEventArgs;(System.Data.DataRow,System.Data.DataColumn,System.Object);;Argument[1];Argument[Qualifier];taint;generated", "System.Data;DataColumnChangeEventArgs;false;get_Column;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataColumnCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataColumnCollection;false;Add;(System.String,System.Type);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataColumnCollection;false;Add;(System.String,System.Type,System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataColumnCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataColumnCollection;false;get_Item;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataColumnCollection;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataReaderExtensions;false;GetDateTime;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated", "System.Data;DataReaderExtensions;false;GetFieldValue<>;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated", - "System.Data;DataReaderExtensions;false;GetFieldValueAsync<>;(System.Data.Common.DbDataReader,System.String,System.Threading.CancellationToken);;Argument[0].Element;ReturnValue;taint;generated", "System.Data;DataReaderExtensions;false;GetGuid;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated", "System.Data;DataReaderExtensions;false;GetProviderSpecificValue;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated", "System.Data;DataReaderExtensions;false;GetString;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated", @@ -2767,16 +2706,10 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data;DataRelation;false;get_RelationName;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataRelation;false;set_RelationName;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataRelationCollection;false;Remove;(System.Data.DataRelation);;Argument[0];Argument[Qualifier];taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];ReturnValue;taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];ReturnValue;taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataRow;false;DataRow;(System.Data.DataRowBuilder);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataRow;false;GetChildRows;(System.Data.DataRelation);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataRow;false;GetChildRows;(System.Data.DataRelation,System.Data.DataRowVersion);;Argument[Qualifier];ReturnValue;taint;generated", @@ -2874,10 +2807,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data;DataTable;false;set_PrimaryKey;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Data;DataTable;false;set_Site;(System.ComponentModel.ISite);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataTable;false;set_TableName;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.Data;DataTableCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated", "System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];ReturnValue;taint;generated", - "System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataTableCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataTableCollection;false;get_Item;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataTableCollection;false;get_Item;(System.String,System.String);;Argument[Qualifier];ReturnValue;taint;generated", @@ -3180,29 +3111,20 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.DirectoryServices.Protocols;DirSyncRequestControl;false;DirSyncRequestControl;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirSyncRequestControl;false;set_Cookie;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Byte[]);;Argument[Qualifier];Argument[0].Element;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.String);;Argument[Qualifier];Argument[0];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Uri);;Argument[0];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Uri);;Argument[Qualifier];Argument[0];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;AddRange;(System.Object[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;CopyTo;(System.Object[],System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;DirectoryAttribute;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;DirectoryAttribute;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;DirectoryAttribute;(System.String,System.Object[]);;Argument[Qualifier];Argument[1].Element;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;GetValues;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Byte[]);;Argument[1].Element;Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Byte[]);;Argument[Qualifier];Argument[1].Element;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.String);;Argument[1];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.String);;Argument[Qualifier];Argument[1];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Uri);;Argument[1];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Uri);;Argument[Qualifier];Argument[1];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Remove;(System.Object);;Argument[0];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Remove;(System.Object);;Argument[Qualifier];Argument[0];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;get_Name;();;Argument[Qualifier];ReturnValue;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;set_Item;(System.Int32,System.Object);;Argument[Qualifier];Argument[1];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;set_Name;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttributeCollection;false;Add;(System.DirectoryServices.Protocols.DirectoryAttribute);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttributeCollection;false;AddRange;(System.DirectoryServices.Protocols.DirectoryAttributeCollection);;Argument[0].Element;Argument[Qualifier];taint;generated", @@ -3391,22 +3313,18 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Drawing.Printing;PrintPageEventArgs;false;get_PageBounds;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrintPageEventArgs;false;get_PageSettings;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;Add;(System.Drawing.Printing.PaperSize);;Argument[0];Argument[Qualifier];taint;generated", - "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;PaperSizeCollection;(System.Drawing.Printing.PaperSize[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;Add;(System.Drawing.Printing.PaperSource);;Argument[0];Argument[Qualifier];taint;generated", - "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;PaperSourceCollection;(System.Drawing.Printing.PaperSource[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;Add;(System.Drawing.Printing.PrinterResolution);;Argument[0];Argument[Qualifier];taint;generated", - "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;PrinterResolutionCollection;(System.Drawing.Printing.PrinterResolution[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Drawing.Printing;PrinterSettings+StringCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.Drawing.Printing;PrinterSettings+StringCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+StringCollection;false;StringCollection;(System.String[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Drawing.Printing;PrinterSettings+StringCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+StringCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", @@ -3663,14 +3581,10 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO.Compression;BrotliStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO.Compression;BrotliStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.Compression;DeflateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.IO.Compression;DeflateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO.Compression;DeflateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.Compression;DeflateStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.Compression;GZipStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO.Compression;GZipStream;false;GZipStream;(System.IO.Stream,System.IO.Compression.CompressionLevel,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.IO.Compression;GZipStream;false;GZipStream;(System.IO.Stream,System.IO.Compression.CompressionMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", - "System.IO.Compression;GZipStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO.Compression;GZipStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.Compression;GZipStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.Compression;ZLibException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated", "System.IO.Compression;ZLibException;false;ZLibException;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[Qualifier];taint;generated", @@ -3709,7 +3623,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO.IsolatedStorage;IsolatedStorage;false;get_AssemblyIdentity;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.IsolatedStorage;IsolatedStorage;false;get_DomainIdentity;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", @@ -3830,7 +3743,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;BinaryReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated", - "System.IO;BinaryWriter;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;BinaryWriter;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;BinaryWriter;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;BinaryWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -3899,7 +3811,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;FileNotFoundException;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;FileNotFoundException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;FileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", @@ -3956,26 +3867,14 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;RenamedEventArgs;false;RenamedEventArgs;(System.IO.WatcherChangeTypes,System.String,System.String,System.String);;Argument[3];Argument[Qualifier];taint;generated", "System.IO;RenamedEventArgs;false;get_OldFullPath;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;RenamedEventArgs;false;get_OldName;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;Stream;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;Stream;false;Synchronized;(System.IO.Stream);;Argument[0];ReturnValue;taint;generated", - "System.IO;Stream;true;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;Stream;true;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;Stream;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated", "System.IO;StreamReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamReader;false;get_CurrentEncoding;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamWriter;false;StreamWriter;(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StreamWriter;false;StreamWriter;(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated", "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object,System.Object);;Argument[0];Argument[Qualifier];taint;generated", @@ -3987,15 +3886,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated", "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamWriter;false;get_Encoding;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StringWriter;false;GetStringBuilder;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -4003,29 +3894,19 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;StringWriter;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StringWriter;false;Write;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;Write;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.IO;StringWriter;false;Write;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;StringWriter;false;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextReader;false;Synchronized;(System.IO.TextReader);;Argument[0];ReturnValue;taint;generated", "System.IO;TextWriter;false;Synchronized;(System.IO.TextWriter);;Argument[0];ReturnValue;taint;generated", "System.IO;TextWriter;false;TextWriter;(System.IFormatProvider);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;Write;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;Write;(System.Object);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;Write;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated", @@ -4039,14 +3920,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;TextWriter;true;Write;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.IO;TextWriter;true;WriteLine;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;WriteLine;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", @@ -4063,18 +3937,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;TextWriter;true;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated", - "System.IO;TextWriter;true;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;get_FormatProvider;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;get_NewLine;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;set_NewLine;(System.String);;Argument[0];Argument[Qualifier];taint;generated", @@ -4673,7 +4537,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Http.Headers;HeaderStringValues;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http.Headers;HttpHeaders;false;get_NonValidated;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http.Headers;HttpHeadersNonValidated+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http.Headers;HttpHeadersNonValidated;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http.Headers;HttpHeadersNonValidated;false;TryGetValue;(System.String,System.Net.Http.Headers.HeaderStringValues);;Argument[0];ReturnValue;taint;generated", "System.Net.Http.Headers;HttpHeadersNonValidated;false;TryGetValues;(System.String,System.Net.Http.Headers.HeaderStringValues);;Argument[0];ReturnValue;taint;generated", "System.Net.Http.Headers;HttpHeadersNonValidated;false;get_Item;(System.String);;Argument[0];ReturnValue;taint;generated", @@ -4774,23 +4637,14 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Net.Http;ByteArrayContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;ByteArrayContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;ByteArrayContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated", "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;DelegatingHandler;false;DelegatingHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Http;DelegatingHandler;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Http;DelegatingHandler;false;get_InnerHandler;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;DelegatingHandler;false;set_InnerHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated", - "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage);;Argument[Qualifier];Argument[0];taint;generated", "System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption);;Argument[Qualifier];Argument[0];taint;generated", "System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", @@ -4817,10 +4671,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Http;HttpContent;false;ReadAsStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;HttpContent;false;get_Headers;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;HttpContent;true;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;HttpContent;true;CreateContentReadStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;HttpMessageInvoker;false;HttpMessageInvoker;(System.Net.Http.HttpMessageHandler,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Http;HttpMessageInvoker;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Http;HttpMethod;false;HttpMethod;(System.String);;Argument[0];Argument[Qualifier];taint;generated", @@ -4855,7 +4706,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Http;MultipartFormDataContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", "System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;ReadOnlyMemoryContent;false;ReadOnlyMemoryContent;(System.ReadOnlyMemory);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Http;SocketsHttpConnectionContext;false;get_DnsEndPoint;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;SocketsHttpConnectionContext;false;get_InitialRequestMessage;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -4894,19 +4744,11 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_NegotiatedHttpVersion;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_PlaintextStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;StreamContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated", "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream,System.Int32);;Argument[0];Argument[Qualifier];taint;generated", - "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String);;Argument[0];ReturnValue;taint;generated", "System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[0];ReturnValue;taint;generated", "System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[1];ReturnValue;taint;generated", @@ -5039,7 +4881,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Quic;QuicListener;false;QuicListener;(System.Net.Quic.Implementations.QuicImplementationProvider,System.Net.Quic.QuicListenerOptions);;Argument[1];Argument[Qualifier];taint;generated", "System.Net.Quic;QuicListener;false;get_ListenEndPoint;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;AuthenticatedStream;false;AuthenticatedStream;(System.IO.Stream,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", - "System.Net.Security;AuthenticatedStream;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;AuthenticatedStream;false;get_InnerStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[1];Argument[Qualifier];taint;generated", "System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[2];Argument[Qualifier];taint;generated", @@ -5058,7 +4899,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Security;NegotiateStream;false;AuthenticateAsServerAsync;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy,System.Net.Security.ProtectionLevel,System.Security.Principal.TokenImpersonationLevel);;Argument[1];Argument[Qualifier];taint;generated", "System.Net.Security;NegotiateStream;false;AuthenticateAsServerAsync;(System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", @@ -5071,7 +4911,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Security;SslCertificateTrust;false;CreateForX509Collection;(System.Security.Cryptography.X509Certificates.X509Certificate2Collection,System.Boolean);;Argument[0].Element;ReturnValue;taint;generated", "System.Net.Security;SslCertificateTrust;false;CreateForX509Store;(System.Security.Cryptography.X509Certificates.X509Store,System.Boolean);;Argument[0];ReturnValue;taint;generated", "System.Net.Security;SslStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Security;SslStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;SslStream;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Net.Security;SslStream;false;get_LocalCertificate;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;SslStream;false;get_NegotiatedApplicationProtocol;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -5102,7 +4941,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;NetworkStream;false;get_Socket;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Sockets;SafeSocketHandle;false;SafeSocketHandle;(System.IntPtr,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Sockets;Socket;false;Accept;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", @@ -5126,7 +4964,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;Socket;false;DisconnectAsync;(System.Boolean,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;DisconnectAsync;(System.Boolean,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;DisconnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Sockets;Socket;false;EndAccept;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveAsync;(System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveAsync;(System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveAsync;(System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", @@ -5146,8 +4983,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;Socket;false;ReceiveFrom;(System.Span,System.Net.EndPoint);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];Argument[Qualifier];taint;generated", "System.Net.Sockets;Socket;false;ReceiveFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];ReturnValue;taint;generated", - "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.ArraySegment,System.Net.EndPoint);;Argument[1];ReturnValue;taint;generated", - "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", @@ -5161,8 +4996,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;Socket;false;ReceiveMessageFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint,System.Net.Sockets.IPPacketInformation);;Argument[4];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveMessageFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint,System.Net.Sockets.IPPacketInformation);;Argument[2];Argument[Qualifier];taint;generated", "System.Net.Sockets;Socket;false;ReceiveMessageFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint,System.Net.Sockets.IPPacketInformation);;Argument[2];ReturnValue;taint;generated", - "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.ArraySegment,System.Net.EndPoint);;Argument[1];ReturnValue;taint;generated", - "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", @@ -5221,7 +5054,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;SocketAsyncEventArgs;false;set_SendPacketsElements;(System.Net.Sockets.SendPacketsElement[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Net.Sockets;SocketAsyncEventArgs;false;set_UserToken;(System.Object);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Sockets;SocketException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Sockets;SocketTaskExtensions;false;AcceptAsync;(System.Net.Sockets.Socket,System.Net.Sockets.Socket);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint);;Argument[1];Argument[0];taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated", @@ -5233,8 +5065,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated", - "System.Net.Sockets;SocketTaskExtensions;false;ReceiveFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated", - "System.Net.Sockets;SocketTaskExtensions;false;ReceiveMessageFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;SendToAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];Argument[0];taint;generated", @@ -5249,8 +5079,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;TcpListener;false;AcceptSocketAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;TcpListener;false;AcceptSocketAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Sockets;TcpListener;false;AcceptTcpClient;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Sockets;TcpListener;false;EndAcceptSocket;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net.Sockets;TcpListener;false;EndAcceptTcpClient;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPAddress,System.Int32);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPEndPoint);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Sockets;TcpListener;false;get_LocalEndpoint;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -5335,17 +5163,11 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net;CookieCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Net;CookieException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated", "System.Net;CredentialCache;false;GetCredential;(System.Uri,System.String);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net;Dns;false;EndGetHostAddresses;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;Dns;false;EndGetHostByName;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;Dns;false;EndGetHostEntry;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;Dns;false;EndResolve;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", "System.Net;DnsEndPoint;false;DnsEndPoint;(System.String,System.Int32,System.Net.Sockets.AddressFamily);;Argument[0];Argument[Qualifier];taint;generated", "System.Net;DnsEndPoint;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;DnsEndPoint;false;get_Host;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;DownloadDataCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;DownloadStringCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net;FileWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;FileWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", "System.Net;FileWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;FileWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;FileWebRequest;false;get_ContentType;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -5419,9 +5241,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net;HttpListenerTimeoutManager;false;get_IdleConnection;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;HttpListenerTimeoutManager;false;set_DrainEntityBody;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated", "System.Net;HttpListenerTimeoutManager;false;set_IdleConnection;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated", - "System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated", - "System.Net;HttpWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", "System.Net;HttpWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;HttpWebRequest;false;GetRequestStream;(System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;HttpWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -5478,7 +5297,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net;OpenWriteCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;PathList;false;get_Item;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;PathList;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net;PathList;false;get_Values;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;ProtocolViolationException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated", "System.Net;UploadDataCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;UploadFileCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -5508,8 +5326,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest);;Argument[0];ReturnValue;taint;generated", "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];Argument[Qualifier];taint;generated", "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];Argument[Qualifier];taint;generated", - "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];ReturnValue;taint;generated", "System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];ReturnValue;taint;generated", "System.Net;WebClient;false;OpenRead;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", @@ -6425,7 +6241,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Resources;ResourceReader;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Resources;ResourceReader;false;GetResourceData;(System.String,System.String,System.Byte[]);;Argument[Qualifier];ReturnValue;taint;generated", "System.Resources;ResourceReader;false;ResourceReader;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated", - "System.Resources;ResourceSet;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Resources;ResourceSet;false;ResourceSet;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated", "System.Resources;ResourceSet;false;ResourceSet;(System.Resources.IResourceReader);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Resources;ResourceWriter;false;ResourceWriter;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated", @@ -6836,7 +6651,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Security.Cryptography.Pkcs;Pkcs12SafeBag;false;set_Attributes;(System.Security.Cryptography.CryptographicAttributeObjectCollection);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Security.Cryptography.Pkcs;Pkcs12SafeContents;false;AddSafeBag;(System.Security.Cryptography.Pkcs.Pkcs12SafeBag);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography.Pkcs;Pkcs12SafeContents;false;AddSecret;(System.Security.Cryptography.Oid,System.ReadOnlyMemory);;Argument[0];ReturnValue;taint;generated", - "System.Security.Cryptography.Pkcs;Pkcs12SafeContents;false;GetBags;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Pkcs;Pkcs12SecretBag;false;GetSecretType;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Pkcs;Pkcs12SecretBag;false;get_SecretValue;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Pkcs;Pkcs9AttributeObject;false;CopyFrom;(System.Security.Cryptography.AsnEncodedData);;Argument[0];Argument[Qualifier];taint;generated", @@ -6923,7 +6737,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Security.Cryptography.X509Certificates;X509Certificate;false;ToString;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Issuer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Subject;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;X509CertificateEnumerator;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;Remove;(System.Security.Cryptography.X509Certificates.X509Certificate);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;X509CertificateCollection;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier];taint;generated", @@ -7044,7 +6857,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Security.Cryptography.Xml;EncryptionPropertyCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Xml;EncryptionPropertyCollection;false;set_ItemOf;(System.Int32,System.Security.Cryptography.Xml.EncryptionProperty);;Argument[1];Argument[Qualifier];taint;generated", "System.Security.Cryptography.Xml;KeyInfo;false;AddClause;(System.Security.Cryptography.Xml.KeyInfoClause);;Argument[0];Argument[Qualifier];taint;generated", - "System.Security.Cryptography.Xml;KeyInfo;false;GetEnumerator;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Xml;KeyInfo;false;LoadXml;(System.Xml.XmlElement);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Security.Cryptography.Xml;KeyInfo;false;get_Id;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Xml;KeyInfo;false;set_Id;(System.String);;Argument[0];Argument[Qualifier];taint;generated", @@ -7157,7 +6969,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Security.Cryptography.Xml;Transform;false;set_Context;(System.Xml.XmlElement);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Security.Cryptography.Xml;Transform;false;set_Resolver;(System.Xml.XmlResolver);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography.Xml;TransformChain;false;Add;(System.Security.Cryptography.Xml.Transform);;Argument[0];Argument[Qualifier];taint;generated", - "System.Security.Cryptography.Xml;TransformChain;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Xml;TransformChain;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Xml;XmlDecryptionTransform;false;AddExceptUri;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography.Xml;XmlDecryptionTransform;false;GetOutput;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -7223,7 +7034,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Security.Cryptography;CryptoStream;false;CryptoStream;(System.IO.Stream,System.Security.Cryptography.ICryptoTransform,System.Security.Cryptography.CryptoStreamMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography;CryptoStream;false;CryptoStream;(System.IO.Stream,System.Security.Cryptography.ICryptoTransform,System.Security.Cryptography.CryptoStreamMode,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated", "System.Security.Cryptography;CryptoStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Security.Cryptography;CryptoStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography;CryptographicAttributeObject;false;CryptographicAttributeObject;(System.Security.Cryptography.Oid,System.Security.Cryptography.AsnEncodedDataCollection);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography;CryptographicAttributeObject;false;get_Oid;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography;CryptographicAttributeObjectCollection;false;Add;(System.Security.Cryptography.CryptographicAttributeObject);;Argument[0];Argument[Qualifier];taint;generated", @@ -7488,7 +7298,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Text.Encodings.Web;TextEncoder;true;Encode;(System.IO.TextWriter,System.String,System.Int32,System.Int32);;Argument[1];Argument[0];taint;generated", "System.Text.Encodings.Web;TextEncoder;true;Encode;(System.String);;Argument[0];ReturnValue;taint;generated", "System.Text.Json.Nodes;JsonArray;false;Add<>;(T);;Argument[0];Argument[Qualifier];taint;generated", - "System.Text.Json.Nodes;JsonArray;false;Add<>;(T);;Argument[Qualifier];Argument[0];taint;generated", "System.Text.Json.Nodes;JsonArray;false;Create;(System.Text.Json.JsonElement,System.Nullable);;Argument[0];ReturnValue;taint;generated", "System.Text.Json.Nodes;JsonArray;false;JsonArray;(System.Text.Json.Nodes.JsonNodeOptions,System.Text.Json.Nodes.JsonNode[]);;Argument[Qualifier];Argument[1].Element;taint;generated", "System.Text.Json.Nodes;JsonArray;false;JsonArray;(System.Text.Json.Nodes.JsonNode[]);;Argument[Qualifier];Argument[0].Element;taint;generated", @@ -7508,7 +7317,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Text.Json.Serialization;JsonSerializerContext;false;JsonSerializerContext;(System.Text.Json.JsonSerializerOptions);;Argument[Qualifier];Argument[0];taint;generated", "System.Text.Json.Serialization;JsonSerializerContext;false;get_Options;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Text.Json.Serialization;JsonStringEnumConverter;false;JsonStringEnumConverter;(System.Text.Json.JsonNamingPolicy,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", - "System.Text.Json.SourceGeneration;JsonSourceGenerator;false;GetSerializableTypes;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Text.Json;JsonDocument;false;Parse;(System.Buffers.ReadOnlySequence,System.Text.Json.JsonDocumentOptions);;Argument[0];ReturnValue;taint;generated", "System.Text.Json;JsonDocument;false;Parse;(System.IO.Stream,System.Text.Json.JsonDocumentOptions);;Argument[0];ReturnValue;taint;generated", "System.Text.Json;JsonDocument;false;Parse;(System.ReadOnlyMemory,System.Text.Json.JsonDocumentOptions);;Argument[0];ReturnValue;taint;generated", @@ -7733,7 +7541,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Threading.RateLimiting;MetadataName<>;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Threading.RateLimiting;MetadataName<>;false;get_Name;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Threading.RateLimiting;RateLimitLease;false;TryGetMetadata<>;(System.Threading.RateLimiting.MetadataName,T);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Threading.RateLimiting;RateLimitLease;true;GetAllMetadata;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Threading.RateLimiting;RateLimiter;false;Acquire;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Threading.RateLimiting;RateLimiter;false;WaitAsync;(System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Threading.RateLimiting;TokenBucketRateLimiter;false;TokenBucketRateLimiter;(System.Threading.RateLimiting.TokenBucketRateLimiterOptions);;Argument[0];Argument[Qualifier];taint;generated", @@ -7775,10 +7582,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated", "System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock);;Argument[0];ReturnValue;taint;generated", - "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated", - "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Threading.Tasks.Dataflow;DataflowBlock;false;SendAsync<>;(System.Threading.Tasks.Dataflow.ITargetBlock,TInput,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated", "System.Threading.Tasks.Dataflow;DataflowBlock;false;TryReceive<>;(System.Threading.Tasks.Dataflow.IReceivableSourceBlock,TOutput);;Argument[0];ReturnValue;taint;generated", "System.Threading.Tasks.Dataflow;DataflowBlockOptions;false;get_CancellationToken;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -8374,12 +8177,9 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Xml.Schema;XmlSchemaSet;false;Add;(System.String,System.Xml.XmlReader);;Argument[Qualifier];ReturnValue;taint;generated", "System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated", "System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated", - "System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchemaSet);;Argument[0];Argument[Qualifier];taint;generated", - "System.Xml.Schema;XmlSchemaSet;false;CopyTo;(System.Xml.Schema.XmlSchema[],System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated", "System.Xml.Schema;XmlSchemaSet;false;Remove;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated", "System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated", "System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated", - "System.Xml.Schema;XmlSchemaSet;false;Schemas;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Xml.Schema;XmlSchemaSet;false;XmlSchemaSet;(System.Xml.XmlNameTable);;Argument[0];Argument[Qualifier];taint;generated", "System.Xml.Schema;XmlSchemaSet;false;get_CompilationSettings;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Xml.Schema;XmlSchemaSet;false;get_GlobalAttributes;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -8466,10 +8266,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Xml.Schema;XmlSchemaXPath;false;get_XPath;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Xml.Schema;XmlSchemaXPath;false;set_XPath;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated", "System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[0];ReturnValue;taint;generated", "System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated", "System.Xml.Serialization;CodeIdentifiers;false;MakeUnique;(System.String);;Argument[0];ReturnValue;taint;generated", "System.Xml.Serialization;CodeIdentifiers;false;ToArray;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated", "System.Xml.Serialization;ImportContext;false;ImportContext;(System.Xml.Serialization.CodeIdentifiers,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", @@ -8752,7 +8550,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.Xml.XmlQualifiedName);;Argument[1];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WriteId;(System.Object);;Argument[Qualifier];Argument[0];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncoded;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.Byte[],System.Xml.XmlQualifiedName);;Argument[2].Element;Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated", @@ -8760,15 +8557,9 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.Byte[]);;Argument[2].Element;Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[2];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[2];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[Qualifier];Argument[2];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteSerializable;(System.Xml.Serialization.IXmlSerializable,System.String,System.String,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", @@ -9945,27 +9736,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System;Tuple<,>;false;get_Item2;();;Argument[Qualifier];ReturnValue;taint;generated", "System;Tuple<>;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System;Tuple<>;false;get_Item1;();;Argument[Qualifier];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", "System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated", "System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated", "System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated", diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index bc553b74fe4..bf9e8f9c41f 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,20 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package. + +## 0.2.0 + +### Query Metadata Changes + +* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`. + +### Minor Analysis Improvements + +* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`). +* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted. + ## 0.1.4 ## 0.1.3 diff --git a/csharp/ql/src/change-notes/2022-06-02-aspnetcoretaintedmembers.md b/csharp/ql/src/change-notes/2022-06-02-aspnetcoretaintedmembers.md deleted file mode 100644 index b80e90e0434..00000000000 --- a/csharp/ql/src/change-notes/2022-06-02-aspnetcoretaintedmembers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted. \ No newline at end of file diff --git a/csharp/ql/src/change-notes/2022-06-14-madformatchange.md b/csharp/ql/src/change-notes/2022-06-14-madformatchange.md deleted file mode 100644 index 1dd215a89c7..00000000000 --- a/csharp/ql/src/change-notes/2022-06-14-madformatchange.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`). \ No newline at end of file diff --git a/csharp/ql/src/change-notes/2022-06-15-diagnostic-query-metadata.md b/csharp/ql/src/change-notes/2022-06-15-diagnostic-query-metadata.md deleted file mode 100644 index d5cfc4d35e1..00000000000 --- a/csharp/ql/src/change-notes/2022-06-15-diagnostic-query-metadata.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: queryMetadata ---- -* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`. diff --git a/csharp/ql/src/change-notes/released/0.2.0.md b/csharp/ql/src/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..1b7d3928c1c --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.2.0.md @@ -0,0 +1,10 @@ +## 0.2.0 + +### Query Metadata Changes + +* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`. + +### Minor Analysis Improvements + +* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`). +* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted. diff --git a/csharp/ql/src/change-notes/released/0.3.0.md b/csharp/ql/src/change-notes/released/0.3.0.md new file mode 100644 index 00000000000..001d034c251 --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.3.0.md @@ -0,0 +1,5 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index e8ee3af8ef9..95f6e3a0ba6 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.3.0 diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs new file mode 100644 index 00000000000..bee97118ea8 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs @@ -0,0 +1,44 @@ + +{ + SymmetricKey aesKey = new SymmetricKey(kid: "symencryptionkey"); + + // BAD: Using the outdated client side encryption version V1_0 + BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(key: aesKey, keyResolver: null); + BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy }; + + MemoryStream stream = new MemoryStream(buffer); + blob.UploadFromStream(stream, length: size, accessCondition: null, options: uploadOptions); +} + +var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions() +{ + // BAD: Using an outdated SDK that does not support client side encryption version V2_0 + ClientSideEncryption = new ClientSideEncryptionOptions() + { + KeyEncryptionKey = myKey, + KeyResolver = myKeyResolver, + KeyWrapAlgorihm = myKeyWrapAlgorithm + } +}); + +var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions() +{ + // BAD: Using the outdated client side encryption version V1_0 + ClientSideEncryption = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0) + { + KeyEncryptionKey = myKey, + KeyResolver = myKeyResolver, + KeyWrapAlgorihm = myKeyWrapAlgorithm + } +}); + +var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions() +{ + // GOOD: Using client side encryption version V2_0 + ClientSideEncryption = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V2_0) + { + KeyEncryptionKey = myKey, + KeyResolver = myKeyResolver, + KeyWrapAlgorihm = myKeyWrapAlgorithm + } +}); \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp new file mode 100644 index 00000000000..54c9a4998b4 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -0,0 +1,29 @@ + + + + + +

Azure Storage .NET, Java, and Python SDKs support encryption on the client with a customer-managed key that is maintained in Azure Key Vault or another key store.

+

Current release versions of the Azure Storage SDKs use cipher block chaining (CBC mode) for client-side encryption (referred to as v1).

+ +
+ + +

Consider switching to v2 client-side encryption.

+ +
+ + + + + + +
  • + Azure Storage Client Encryption Blog. +
  • +
  • + CVE-2022-30187 +
  • + +
    +
    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 new file mode 100644 index 00000000000..eb1cb673ed2 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -0,0 +1,81 @@ +/** + * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-30187). + * @description Unsafe usage of v1 version of Azure Storage client-side encryption, please refer to http://aka.ms/azstorageclientencryptionblog + * @kind problem + * @tags security + * cryptography + * external/cwe/cwe-327 + * @id cs/azure-storage/unsafe-usage-of-client-side-encryption-version + * @problem.severity error + * @precision high + */ + +import csharp + +/** + * Holds if `oc` is creating an object of type `c` = `Azure.Storage.ClientSideEncryptionOptions` + * and `e` is the `version` argument to the constructor + */ +predicate isCreatingAzureClientSideEncryptionObject(ObjectCreation oc, Class c, Expr e) { + exists(Parameter p | p.hasName("version") | + c.hasQualifiedName("Azure.Storage.ClientSideEncryptionOptions") and + oc.getTarget() = c.getAConstructor() and + e = oc.getArgumentForParameter(p) + ) +} + +/** + * 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 + oc.getTarget() = c.getAConstructor() +} + +/** + * Holds if the Azure.Storage assembly for `c` is a version known to support + * version 2+ for client-side encryption + */ +predicate doesAzureStorageAssemblySupportSafeClientSideEncryption(Assembly asm) { + exists(int versionCompare | + versionCompare = asm.getVersion().compareTo("12.12.0.0") and + versionCompare >= 0 + ) and + asm.getName() = "Azure.Storage.Common" +} + +/** + * Holds if the Azure.Storage assembly for `c` is a version known to support + * version 2+ for client-side encryption and if the argument for the constructor `version` + * is set to a secure value. + */ +predicate isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(Expr versionExpr, Assembly asm) { + // Check if the Azure.Storage assembly version has the fix + doesAzureStorageAssemblySupportSafeClientSideEncryption(asm) and + // and that the version argument for the constructor is guaranteed to be Version2 + isExprAnAccessToSafeClientSideEncryptionVersionValue(versionExpr) +} + +/** + * Holds if the expression `e` is an access to a safe version of the enum `ClientSideEncryptionVersion` + * or an equivalent numeric value + */ +predicate isExprAnAccessToSafeClientSideEncryptionVersionValue(Expr e) { + exists(EnumConstant ec | + ec.hasQualifiedName("Azure.Storage.ClientSideEncryptionVersion.V2_0") and + ec.getAnAccess() = e + ) +} + +from Expr e, Class c, Assembly asm +where + asm = c.getLocation() and + ( + exists(Expr e2 | + isCreatingAzureClientSideEncryptionObject(e, c, e2) and + not isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(e2, asm) + ) + or + isCreatingOutdatedAzureClientSideEncryptionObject(e, c) + ) +select e, "Unsafe usage of v1 version of Azure Storage client-side encryption." diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index a9d6dcf0e69..d3ceb328420 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.2.0-dev +version: 0.3.1-dev groups: - csharp - queries diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index b6d827ca880..2d9fce246fb 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -336,7 +336,6 @@ | System.Collections.Concurrent;ConcurrentDictionary<,>;false;CopyTo;(System.Collections.Generic.KeyValuePair[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetOrAdd;(TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Item;(System.Object);;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue;value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Item;(TKey);;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue;value;manual | @@ -370,9 +369,6 @@ | System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | | System.Collections.Generic;CollectionExtensions;false;Remove<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;Argument[2];taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[1];Argument[0].Element;taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[2];Argument[0].Element;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Entry;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Key;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -451,8 +447,6 @@ | System.Collections.Generic;IList<>;true;get_Item;(System.Int32);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.Generic;IList<>;true;set_Item;(System.Int32,T);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.Generic;ISet<>;true;Add;(T);;Argument[0];Argument[Qualifier].Element;value;manual | -| System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Generic;KeyValuePair<,>;false;Deconstruct;(TKey,TValue);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;KeyValuePair<,>;false;KeyValuePair;(TKey,TValue);;Argument[0];ReturnValue.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Generic;KeyValuePair<,>;false;KeyValuePair;(TKey,TValue);;Argument[1];ReturnValue.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | @@ -726,12 +720,6 @@ | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;GetValueOrDefault<,>;(System.Collections.Immutable.IImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;taint;generated | @@ -802,8 +790,6 @@ | System.Collections.Immutable;ImmutableDictionary<,>;false;set_Item;(System.Object,System.Object);;Argument[1];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Immutable;ImmutableDictionary<,>;false;set_Item;(TKey,TValue);;Argument[0];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Immutable;ImmutableDictionary<,>;false;set_Item;(TKey,TValue);;Argument[1];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | -| System.Collections.Immutable;ImmutableHashSet;false;Create<>;(System.Collections.Generic.IEqualityComparer,T);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableHashSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;ToImmutableHashSet<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | @@ -836,9 +822,6 @@ | System.Collections.Immutable;ImmutableHashSet<>;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated | | System.Collections.Immutable;ImmutableInterlocked;false;GetOrAdd<,>;(System.Collections.Immutable.ImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;Create<>;(T[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;Remove<>;(System.Collections.Immutable.IImmutableList,T);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;RemoveRange<>;(System.Collections.Immutable.IImmutableList,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;Replace<>;(System.Collections.Immutable.IImmutableList,T,T);;Argument[0].Element;ReturnValue;taint;generated | @@ -945,12 +928,6 @@ | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[1];ReturnValue;taint;generated | @@ -988,7 +965,6 @@ | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_Item;(TKey,TValue);;Argument[1];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_KeyComparer;(System.Collections.Generic.IComparer);;Argument[0];Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_ValueComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(System.Collections.Generic.KeyValuePair);;Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(System.Collections.Generic.KeyValuePair);;Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(System.Collections.Generic.KeyValuePair);;Argument[0];Argument[Qualifier].Element;value;manual | @@ -1027,10 +1003,7 @@ | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;set_Item;(TKey,TValue);;Argument[0];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;set_Item;(TKey,TValue);;Argument[1];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[1];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T[]);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateBuilder<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated | @@ -1047,7 +1020,6 @@ | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1068,12 +1040,8 @@ | System.Collections.Immutable;ImmutableSortedSet<>;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | | System.Collections.Immutable;ImmutableSortedSet<>;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet<>;false;Insert;(System.Int32,T);;Argument[1];Argument[Qualifier].Element;value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;ToBuilder;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1111,27 +1079,21 @@ | System.Collections.ObjectModel;Collection<>;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;Collection<>;false;Insert;(System.Int32,T);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;Collection<>;false;get_Item;(System.Int32);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.ObjectModel;Collection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;Collection<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;Collection<>;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;Collection<>;false;set_Item;(System.Int32,T);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;KeyedCollection;(System.Collections.Generic.IEqualityComparer,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;TryGetValue;(TKey,TItem);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Dictionary;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Item;(TKey);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;Add;(System.Object);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;Add;(T);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;CopyTo;(System.Array,System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | @@ -1328,7 +1290,6 @@ | System.Collections;CollectionBase;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Collections;CollectionBase;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | -| System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[Qualifier];Argument[0];taint;generated | | System.Collections;CollectionBase;false;get_InnerList;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections;CollectionBase;false;get_Item;(System.Int32);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections;CollectionBase;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -1559,9 +1520,7 @@ | System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated | | System.ComponentModel;BindingList<>;false;Find;(System.ComponentModel.PropertyDescriptor,System.Object);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.ComponentModel;CategoryAttribute;false;CategoryAttribute;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.ComponentModel;CategoryAttribute;false;get_Category;();;Argument[Qualifier];ReturnValue;taint;generated | | System.ComponentModel;CharConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated | @@ -1882,10 +1841,6 @@ | System.Data.Common;DataTableMappingCollection;false;set_Item;(System.String,System.Object);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Data.Common;DbCommand;false;ExecuteReader;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;ExecuteReader;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Connection;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Parameters;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Transaction;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -1893,7 +1848,6 @@ | System.Data.Common;DbCommand;false;set_Connection;(System.Data.IDbConnection);;Argument[0];Argument[Qualifier];taint;generated | | System.Data.Common;DbCommand;false;set_Transaction;(System.Data.Common.DbTransaction);;Argument[0];Argument[Qualifier];taint;generated | | System.Data.Common;DbCommand;false;set_Transaction;(System.Data.IDbTransaction);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data.Common;DbCommand;true;ExecuteDbDataReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;true;PrepareAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1926,7 +1880,6 @@ | System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[2];Argument[0];taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;CopyTo;(System.Array,System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data.Common;DbConnectionStringBuilder;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Data.Common;DbConnectionStringBuilder;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetProperties;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetProperties;(System.Attribute[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated | @@ -1961,13 +1914,10 @@ | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[0];ReturnValue;taint;generated | | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[1];ReturnValue;taint;generated | | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[3];ReturnValue;taint;generated | -| System.Data.Common;DbDataReader;false;GetFieldValueAsync<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Data.Common;DbDataReader;true;GetFieldValue<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbDataReader;true;GetFieldValueAsync<>;(System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetProviderSpecificValue;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetProviderSpecificValues;(System.Object[]);;Argument[Qualifier];Argument[0].Element;taint;generated | -| System.Data.Common;DbDataReader;true;GetSchemaTableAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetTextReader;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataRecord;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated | | System.Data.Common;DbEnumerator;false;DbEnumerator;(System.Data.IDataReader);;Argument[0];Argument[Qualifier];taint;generated | @@ -2108,11 +2058,8 @@ | System.Data;DataColumn;false;set_Prefix;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataColumnChangeEventArgs;false;DataColumnChangeEventArgs;(System.Data.DataRow,System.Data.DataColumn,System.Object);;Argument[1];Argument[Qualifier];taint;generated | | System.Data;DataColumnChangeEventArgs;false;get_Column;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataColumnCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataColumnCollection;false;Add;(System.Data.DataColumn);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataColumnCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier].Element;value;manual | -| System.Data;DataColumnCollection;false;Add;(System.String,System.Type);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataColumnCollection;false;Add;(System.String,System.Type,System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataColumnCollection;false;AddRange;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataColumnCollection;false;CopyTo;(System.Data.DataColumn[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataColumnCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | @@ -2120,7 +2067,6 @@ | System.Data;DataColumnCollection;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetDateTime;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetFieldValue<>;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | -| System.Data;DataReaderExtensions;false;GetFieldValueAsync<>;(System.Data.Common.DbDataReader,System.String,System.Threading.CancellationToken);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetGuid;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetProviderSpecificValue;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetString;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | @@ -2152,16 +2098,10 @@ | System.Data;DataRelationCollection;false;Add;(System.Data.DataRelation);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataRelationCollection;false;CopyTo;(System.Data.DataRelation[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataRelationCollection;false;Remove;(System.Data.DataRelation);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;AddRange;(System.Data.DataRelation[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataRow;false;DataRow;(System.Data.DataRowBuilder);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRow;false;GetChildRows;(System.Data.DataRelation);;Argument[Qualifier];ReturnValue;taint;generated | @@ -2267,12 +2207,10 @@ | System.Data;DataTable;false;set_PrimaryKey;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Data;DataTable;false;set_Site;(System.ComponentModel.ISite);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataTable;false;set_TableName;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data;DataTableCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataTableCollection;false;Add;(System.Data.DataTable);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];ReturnValue;taint;generated | -| System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataTableCollection;false;AddRange;(System.Data.DataTable[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;CopyTo;(System.Data.DataTable[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataTableCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | @@ -2867,13 +2805,10 @@ | System.IO.Compression;BrotliStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Compression;BrotliStream;false;BrotliStream;(System.IO.Stream,System.IO.Compression.CompressionMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO.Compression;BrotliStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO.Compression;BrotliStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;BrotliStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Compression;BrotliStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO.Compression;BrotliStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;BrotliStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Compression;BrotliStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO.Compression;BrotliStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;BrotliStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;DeflateStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Compression;DeflateStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | @@ -2884,28 +2819,22 @@ | System.IO.Compression;DeflateStream;false;DeflateStream;(System.IO.Stream,System.IO.Compression.CompressionMode);;Argument[0];ReturnValue;taint;manual | | System.IO.Compression;DeflateStream;false;DeflateStream;(System.IO.Stream,System.IO.Compression.CompressionMode,System.Boolean);;Argument[0];ReturnValue;taint;manual | | System.IO.Compression;DeflateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO.Compression;DeflateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;DeflateStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Compression;DeflateStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO.Compression;DeflateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;DeflateStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Compression;DeflateStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO.Compression;DeflateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;DeflateStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;GZipStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Compression;GZipStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Compression;GZipStream;false;CopyTo;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO.Compression;GZipStream;false;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | | System.IO.Compression;GZipStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO.Compression;GZipStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;GZipStream;false;GZipStream;(System.IO.Stream,System.IO.Compression.CompressionLevel,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO.Compression;GZipStream;false;GZipStream;(System.IO.Stream,System.IO.Compression.CompressionMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO.Compression;GZipStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Compression;GZipStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO.Compression;GZipStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;GZipStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Compression;GZipStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO.Compression;GZipStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;GZipStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;ZipArchive;false;CreateEntry;(System.String);;Argument[0];ReturnValue;taint;generated | | System.IO.Compression;ZipArchive;false;CreateEntry;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | @@ -2939,7 +2868,6 @@ | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | @@ -2965,14 +2893,11 @@ | System.IO.Pipes;NamedPipeServerStream;false;WaitForConnectionAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO.Pipes;PipeStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Pipes;PipeStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO.Pipes;PipeStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Pipes;PipeStream;false;InitializeHandle;(Microsoft.Win32.SafeHandles.SafePipeHandle,System.Boolean,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO.Pipes;PipeStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Pipes;PipeStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO.Pipes;PipeStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Pipes;PipeStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Pipes;PipeStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO.Pipes;PipeStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Pipes;PipeStream;false;get_SafePipeHandle;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BinaryReader;false;BinaryReader;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;BinaryReader;false;BinaryReader;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | @@ -2982,7 +2907,6 @@ | System.IO;BinaryReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | -| System.IO;BinaryWriter;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BinaryWriter;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -2991,13 +2915,10 @@ | System.IO;BufferedStream;false;BufferedStream;(System.IO.Stream,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;BufferedStream;false;CopyTo;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;BufferedStream;false;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | -| System.IO;BufferedStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BufferedStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;BufferedStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO;BufferedStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BufferedStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;BufferedStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO;BufferedStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BufferedStream;false;get_UnderlyingStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Directory;false;CreateDirectory;(System.String);;Argument[0];ReturnValue;taint;generated | | System.IO;Directory;false;GetParent;(System.String);;Argument[0];ReturnValue;taint;generated | @@ -3057,7 +2978,6 @@ | System.IO;FileStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;FileStream;false;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;FileStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;FileStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | @@ -3091,7 +3011,6 @@ | System.IO;MemoryStream;false;CopyTo;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;MemoryStream;false;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;MemoryStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO;MemoryStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;MemoryStream;false;GetBuffer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;MemoryStream;false;MemoryStream;(System.Byte[]);;Argument[0];ReturnValue;taint;manual | | System.IO;MemoryStream;false;MemoryStream;(System.Byte[],System.Boolean);;Argument[0].Element;ReturnValue;taint;manual | @@ -3100,12 +3019,10 @@ | System.IO;MemoryStream;false;MemoryStream;(System.Byte[],System.Int32,System.Int32,System.Boolean,System.Boolean);;Argument[0].Element;ReturnValue;taint;manual | | System.IO;MemoryStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;MemoryStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO;MemoryStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;MemoryStream;false;ToArray;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;MemoryStream;false;TryGetBuffer;(System.ArraySegment);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;MemoryStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;MemoryStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO;MemoryStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;MemoryStream;false;WriteTo;(System.IO.Stream);;Argument[Qualifier];Argument[0];taint;generated | | System.IO;Path;false;ChangeExtension;(System.String,System.String);;Argument[0];ReturnValue;taint;generated | | System.IO;Path;false;Combine;(System.String,System.String);;Argument[0];ReturnValue;taint;manual | @@ -3150,7 +3067,6 @@ | System.IO;Stream;false;CopyToAsync;(System.IO.Stream);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;false;CopyToAsync;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;false;CopyToAsync;(System.IO.Stream,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | -| System.IO;Stream;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;Stream;false;Synchronized;(System.IO.Stream);;Argument[0];ReturnValue;taint;generated | | System.IO;Stream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | @@ -3158,13 +3074,10 @@ | System.IO;Stream;true;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;Stream;true;CopyTo;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;true;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | -| System.IO;Stream;true;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;true;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;Stream;true;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO;Stream;true;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;true;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;Stream;true;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO;Stream;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamReader;false;Read;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;StreamReader;false;Read;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;StreamReader;false;Read;(System.Span);;Argument[Qualifier];ReturnValue;taint;manual | @@ -3182,7 +3095,6 @@ | System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | | System.IO;StreamReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamReader;false;get_CurrentEncoding;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamWriter;false;StreamWriter;(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;StreamWriter;(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;Write;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | @@ -3197,14 +3109,7 @@ | System.IO;StreamWriter;false;Write;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;Write;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;Write;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamWriter;false;WriteLine;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;WriteLine;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;WriteLine;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated | @@ -3217,15 +3122,7 @@ | System.IO;StreamWriter;false;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamWriter;false;get_Encoding;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringReader;false;Read;();;Argument[Qualifier];ReturnValue;taint;manual | @@ -3241,39 +3138,19 @@ | System.IO;StringReader;false;ReadToEnd;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;StringReader;false;ReadToEndAsync;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;StringReader;false;StringReader;(System.String);;Argument[0];ReturnValue;taint;manual | -| System.IO;StringWriter;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;GetStringBuilder;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;StringWriter;(System.Text.StringBuilder,System.IFormatProvider);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;Write;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;Write;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;Write;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextReader;false;Synchronized;(System.IO.TextReader);;Argument[0];ReturnValue;taint;generated | | System.IO;TextReader;true;Read;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;TextReader;true;Read;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;manual | @@ -3291,12 +3168,7 @@ | System.IO;TextWriter;false;Synchronized;(System.IO.TextWriter);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;false;TextWriter;(System.IFormatProvider);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;Write;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated | @@ -3310,14 +3182,7 @@ | System.IO;TextWriter;true;Write;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLine;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | @@ -3334,18 +3199,8 @@ | System.IO;TextWriter;true;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;get_FormatProvider;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;get_NewLine;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;set_NewLine;(System.String);;Argument[0];Argument[Qualifier];taint;generated | @@ -3353,19 +3208,16 @@ | System.IO;UnmanagedMemoryAccessor;false;UnmanagedMemoryAccessor;(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryAccessor;false;UnmanagedMemoryAccessor;(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64,System.IO.FileAccess);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO;UnmanagedMemoryStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;UnmanagedMemoryStream;false;Initialize;(System.Byte*,System.Int64,System.Int64,System.IO.FileAccess);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;Initialize;(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64,System.IO.FileAccess);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;UnmanagedMemoryStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO;UnmanagedMemoryStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;UnmanagedMemoryStream;false;UnmanagedMemoryStream;(System.Byte*,System.Int64);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;UnmanagedMemoryStream;(System.Byte*,System.Int64,System.Int64,System.IO.FileAccess);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;UnmanagedMemoryStream;(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;UnmanagedMemoryStream;(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64,System.IO.FileAccess);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;UnmanagedMemoryStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO;UnmanagedMemoryStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;UnmanagedMemoryStream;false;get_PositionPointer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Linq.Expressions;BinaryExpression;false;Accept;(System.Linq.Expressions.ExpressionVisitor);;Argument[Qualifier];Argument[0];taint;generated | | System.Linq.Expressions;BinaryExpression;false;Accept;(System.Linq.Expressions.ExpressionVisitor);;Argument[Qualifier];ReturnValue;taint;generated | @@ -4687,29 +4539,18 @@ | System.Net.Http.Headers;WarningHeaderValue;false;get_Text;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http.Json;JsonContent;false;Create;(System.Object,System.Type,System.Net.Http.Headers.MediaTypeHeaderValue,System.Text.Json.JsonSerializerOptions);;Argument[3];ReturnValue;taint;generated | | System.Net.Http.Json;JsonContent;false;Create<>;(T,System.Net.Http.Headers.MediaTypeHeaderValue,System.Text.Json.JsonSerializerOptions);;Argument[2];ReturnValue;taint;generated | -| System.Net.Http.Json;JsonContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http.Json;JsonContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http.Json;JsonContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Http;ByteArrayContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;ByteArrayContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;DelegatingHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;DelegatingHandler;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;get_InnerHandler;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;set_InnerHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | @@ -4736,10 +4577,7 @@ | System.Net.Http;HttpContent;false;ReadAsStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpContent;false;get_Headers;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpContent;true;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;HttpContent;true;CreateContentReadStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpMessageInvoker;false;HttpMessageInvoker;(System.Net.Http.HttpMessageHandler,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;HttpMessageInvoker;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Http;HttpMethod;false;HttpMethod;(System.String);;Argument[0];Argument[Qualifier];taint;generated | @@ -4781,27 +4619,19 @@ | System.Net.Http;MessageProcessingHandler;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Http;MultipartContent;false;Add;(System.Net.Http.HttpContent);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Net.Http;MultipartContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;MultipartContent;false;CreateContentReadStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;MultipartContent;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | | System.Net.Http;MultipartContent;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Net.Http;MultipartContent;false;MultipartContent;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Net.Http;MultipartContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Http;MultipartContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;MultipartContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;MultipartContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;MultipartContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;MultipartFormDataContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;MultipartFormDataContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;MultipartFormDataContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ReadOnlyMemoryContent;false;ReadOnlyMemoryContent;(System.ReadOnlyMemory);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;ReadOnlyMemoryContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;ReadOnlyMemoryContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ReadOnlyMemoryContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;SocketsHttpConnectionContext;false;get_DnsEndPoint;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;SocketsHttpConnectionContext;false;get_InitialRequestMessage;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;SocketsHttpHandler;false;get_ConnectCallback;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4838,19 +4668,11 @@ | System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_PlaintextStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[0];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[1];ReturnValue;taint;generated | @@ -4996,7 +4818,6 @@ | System.Net.NetworkInformation;UnicastIPAddressInformationCollection;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Net.NetworkInformation;UnicastIPAddressInformationCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;AuthenticatedStream;false;AuthenticatedStream;(System.IO.Stream,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Security;AuthenticatedStream;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;AuthenticatedStream;false;get_InnerStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[2];Argument[Qualifier];taint;generated | @@ -5017,7 +4838,6 @@ | System.Net.Security;NegotiateStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Security;NegotiateStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Security;NegotiateStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | @@ -5034,14 +4854,11 @@ | System.Net.Security;SslStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Security;SslStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.Net.Security;SslStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Security;SslStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Security;SslStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.Net.Security;SslStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslStream;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Security;SslStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.Net.Security;SslStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.Net.Security;SslStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslStream;false;get_LocalCertificate;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslStream;false;get_NegotiatedApplicationProtocol;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslStream;false;get_RemoteCertificate;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -5062,7 +4879,6 @@ | System.Net.Sockets;MulticastOption;false;set_LocalAddress;(System.Net.IPAddress);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;NetworkStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Sockets;NetworkStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.Net.Sockets;NetworkStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;NetworkStream;false;NetworkStream;(System.Net.Sockets.Socket,System.IO.FileAccess,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;NetworkStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Sockets;NetworkStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | @@ -5084,7 +4900,6 @@ | System.Net.Sockets;Socket;false;ConnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;Socket;false;ConnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Sockets;Socket;false;DisconnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Sockets;Socket;false;EndAccept;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;Socket;false;ReceiveAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Sockets;Socket;false;ReceiveFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[4];Argument[Qualifier];taint;generated | | System.Net.Sockets;Socket;false;ReceiveFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[4];ReturnValue;taint;generated | @@ -5127,7 +4942,6 @@ | System.Net.Sockets;SocketAsyncEventArgs;false;set_SendPacketsElements;(System.Net.Sockets.SendPacketsElement[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Sockets;SocketAsyncEventArgs;false;set_UserToken;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;SocketException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;AcceptAsync;(System.Net.Sockets.Socket,System.Net.Sockets.Socket);;Argument[1];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint);;Argument[1];Argument[0];taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated | @@ -5139,8 +4953,6 @@ | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;ReceiveFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;ReceiveMessageFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendToAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];Argument[0];taint;generated | @@ -5151,8 +4963,6 @@ | System.Net.Sockets;TcpClient;false;set_Client;(System.Net.Sockets.Socket);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;AcceptSocket;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;TcpListener;false;AcceptTcpClient;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Sockets;TcpListener;false;EndAcceptSocket;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net.Sockets;TcpListener;false;EndAcceptTcpClient;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPAddress,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPEndPoint);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;get_LocalEndpoint;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -5230,17 +5040,11 @@ | System.Net;CookieException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated | | System.Net;CredentialCache;false;GetCredential;(System.Uri,System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;CredentialCache;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Net;Dns;false;EndGetHostAddresses;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndGetHostByName;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndGetHostEntry;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndResolve;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;DnsEndPoint;false;DnsEndPoint;(System.String,System.Int32,System.Net.Sockets.AddressFamily);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;DnsEndPoint;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DnsEndPoint;false;get_Host;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DownloadDataCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DownloadStringCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net;FileWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;FileWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;get_ContentType;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -5319,9 +5123,6 @@ | System.Net;HttpListenerTimeoutManager;false;get_IdleConnection;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpListenerTimeoutManager;false;set_DrainEntityBody;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;HttpListenerTimeoutManager;false;set_IdleConnection;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | -| System.Net;HttpWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetRequestStream;(System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -5407,8 +5208,6 @@ | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest);;Argument[0];ReturnValue;taint;generated | | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];Argument[Qualifier];taint;generated | -| System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];ReturnValue;taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | @@ -6342,7 +6141,6 @@ | System.Resources;ResourceReader;false;GetResourceData;(System.String,System.String,System.Byte[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Resources;ResourceReader;false;ResourceReader;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | | System.Resources;ResourceSet;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Resources;ResourceSet;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Resources;ResourceSet;false;ResourceSet;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | | System.Resources;ResourceSet;false;ResourceSet;(System.Resources.IResourceReader);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Resources;ResourceWriter;false;ResourceWriter;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | @@ -6725,7 +6523,6 @@ | System.Security.Cryptography.X509Certificates;X509Certificate;false;ToString;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Issuer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Subject;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;X509CertificateEnumerator;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;Add;(System.Security.Cryptography.X509Certificates.X509Certificate);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;AddRange;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier].Element;value;manual | @@ -6794,7 +6591,6 @@ | System.Security.Cryptography;CryptoStream;false;CryptoStream;(System.IO.Stream,System.Security.Cryptography.ICryptoTransform,System.Security.Cryptography.CryptoStreamMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Security.Cryptography;CryptoStream;false;CryptoStream;(System.IO.Stream,System.Security.Cryptography.ICryptoTransform,System.Security.Cryptography.CryptoStreamMode,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | | System.Security.Cryptography;CryptoStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Security.Cryptography;CryptoStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography;CryptoStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Security.Cryptography;CryptoStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Security.Cryptography;CryptoStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | @@ -7313,10 +7109,6 @@ | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;SendAsync<>;(System.Threading.Tasks.Dataflow.ITargetBlock,TInput,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;TryReceive<>;(System.Threading.Tasks.Dataflow.IReceivableSourceBlock,TOutput);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlockOptions;false;get_CancellationToken;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -8103,12 +7895,9 @@ | System.Xml.Schema;XmlSchemaSet;false;Add;(System.String,System.Xml.XmlReader);;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchemaSet);;Argument[0];Argument[Qualifier];taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;CopyTo;(System.Xml.Schema.XmlSchema[],System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Remove;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;Schemas;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;XmlSchemaSet;(System.Xml.XmlNameTable);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;get_CompilationSettings;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;get_GlobalAttributes;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -8195,10 +7984,8 @@ | System.Xml.Schema;XmlSchemaXPath;false;get_XPath;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaXPath;false;set_XPath;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[0];ReturnValue;taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;MakeUnique;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;ToArray;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Serialization;ImportContext;false;ImportContext;(System.Xml.Serialization.CodeIdentifiers,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | @@ -8505,7 +8292,6 @@ | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.Xml.XmlQualifiedName);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteId;(System.Object);;Argument[Qualifier];Argument[0];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncoded;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.Byte[],System.Xml.XmlQualifiedName);;Argument[2].Element;Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | @@ -8513,15 +8299,9 @@ | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.Byte[]);;Argument[2].Element;Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteSerializable;(System.Xml.Serialization.IXmlSerializable,System.String,System.String,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | @@ -10357,27 +10137,6 @@ | System;TupleExtensions;false;Deconstruct<,>;(System.Tuple,T1,T2);;Argument[0].Property[System.Tuple<,>.Item1];Argument[1];value;manual | | System;TupleExtensions;false;Deconstruct<,>;(System.Tuple,T1,T2);;Argument[0].Property[System.Tuple<,>.Item2];Argument[2];value;manual | | System;TupleExtensions;false;Deconstruct<>;(System.Tuple,T1);;Argument[0].Property[System.Tuple<>.Item1];Argument[1];value;manual | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index 1a2f70f48e8..a77b56ab64b 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -255,7 +255,6 @@ | System.Collections.Concurrent;ConcurrentDictionary<,>;false;ConcurrentDictionary;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;ConcurrentDictionary;(System.Int32,System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[1].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];ReturnValue.Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;ConcurrentDictionary;(System.Int32,System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[1].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | -| System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetOrAdd;(TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Keys;();;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];ReturnValue.Element;value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Values;();;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element;value;manual | @@ -275,9 +274,6 @@ | System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | | System.Collections.Generic;CollectionExtensions;false;Remove<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;Argument[2];taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[1];Argument[0].Element;taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[2];Argument[0].Element;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Entry;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Key;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -327,8 +323,6 @@ | System.Collections.Generic;IList<>;true;get_Item;(System.Int32);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.Generic;IList<>;true;set_Item;(System.Int32,T);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.Generic;ISet<>;true;Add;(T);;Argument[0];Argument[Qualifier].Element;value;manual | -| System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Generic;KeyValuePair<,>;false;Deconstruct;(TKey,TValue);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;KeyValuePair<,>;false;KeyValuePair;(TKey,TValue);;Argument[0];ReturnValue.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Generic;KeyValuePair<,>;false;KeyValuePair;(TKey,TValue);;Argument[1];ReturnValue.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | @@ -518,12 +512,6 @@ | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;GetValueOrDefault<,>;(System.Collections.Immutable.IImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;taint;generated | @@ -567,8 +555,6 @@ | System.Collections.Immutable;ImmutableDictionary<,>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated | | System.Collections.Immutable;ImmutableDictionary<,>;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary<,>;false;get_Values;();;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableHashSet;false;Create<>;(System.Collections.Generic.IEqualityComparer,T);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableHashSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;ToImmutableHashSet<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | @@ -593,9 +579,6 @@ | System.Collections.Immutable;ImmutableHashSet<>;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated | | System.Collections.Immutable;ImmutableInterlocked;false;GetOrAdd<,>;(System.Collections.Immutable.ImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;Create<>;(T[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;Remove<>;(System.Collections.Immutable.IImmutableList,T);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;RemoveRange<>;(System.Collections.Immutable.IImmutableList,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;Replace<>;(System.Collections.Immutable.IImmutableList,T,T);;Argument[0].Element;ReturnValue;taint;generated | @@ -681,12 +664,6 @@ | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[1];ReturnValue;taint;generated | @@ -709,7 +686,6 @@ | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;get_Values;();;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_KeyComparer;(System.Collections.Generic.IComparer);;Argument[0];Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_ValueComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(System.Collections.Generic.KeyValuePair);;Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(System.Collections.Generic.KeyValuePair);;Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(TKey,TValue);;Argument[0];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | @@ -736,10 +712,7 @@ | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;get_Values;();;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[1];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T[]);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateBuilder<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated | @@ -751,7 +724,6 @@ | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated | @@ -765,12 +737,8 @@ | System.Collections.Immutable;ImmutableSortedSet<>;false;Add;(T);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet<>;false;Except;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;ToBuilder;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated | @@ -796,24 +764,18 @@ | System.Collections.Immutable;ImmutableStack<>;false;Push;(T);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;Collection<>;false;Collection;(System.Collections.Generic.IList);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;Collection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;Collection<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;KeyedCollection;(System.Collections.Generic.IEqualityComparer,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;TryGetValue;(TKey,TItem);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Dictionary;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Item;(TKey);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;ReadOnlyCollection;(System.Collections.Generic.IList);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;get_Item;(System.Int32);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -924,7 +886,6 @@ | System.Collections;BitArray;false;Xor;(System.Collections.BitArray);;Argument[Qualifier];ReturnValue;value;generated | | System.Collections;BitArray;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated | | System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | -| System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[Qualifier];Argument[0];taint;generated | | System.Collections;CollectionBase;false;get_InnerList;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections;CollectionBase;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections;CollectionBase;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -1101,9 +1062,7 @@ | System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[1];ReturnValue;taint;generated | | System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated | | System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.ComponentModel;CategoryAttribute;false;CategoryAttribute;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.ComponentModel;CategoryAttribute;false;get_Category;();;Argument[Qualifier];ReturnValue;taint;generated | | System.ComponentModel;CharConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated | @@ -1388,10 +1347,6 @@ | System.Data.Common;DataTableMappingCollection;false;set_Item;(System.String,System.Data.Common.DataTableMapping);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Data.Common;DbCommand;false;ExecuteReader;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;ExecuteReader;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Connection;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Parameters;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Transaction;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -1399,7 +1354,6 @@ | System.Data.Common;DbCommand;false;set_Connection;(System.Data.IDbConnection);;Argument[0];Argument[Qualifier];taint;generated | | System.Data.Common;DbCommand;false;set_Transaction;(System.Data.Common.DbTransaction);;Argument[0];Argument[Qualifier];taint;generated | | System.Data.Common;DbCommand;false;set_Transaction;(System.Data.IDbTransaction);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data.Common;DbCommand;true;ExecuteDbDataReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;true;PrepareAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1428,7 +1382,6 @@ | System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String);;Argument[2];Argument[0];taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[1];Argument[0];taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[2];Argument[0];taint;generated | -| System.Data.Common;DbConnectionStringBuilder;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetProperties;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetProperties;(System.Attribute[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated | @@ -1458,12 +1411,9 @@ | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[0];ReturnValue;taint;generated | | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[1];ReturnValue;taint;generated | | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[3];ReturnValue;taint;generated | -| System.Data.Common;DbDataReader;false;GetFieldValueAsync<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetFieldValue<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbDataReader;true;GetFieldValueAsync<>;(System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetProviderSpecificValue;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetProviderSpecificValues;(System.Object[]);;Argument[Qualifier];Argument[0].Element;taint;generated | -| System.Data.Common;DbDataReader;true;GetSchemaTableAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetTextReader;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataRecord;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated | | System.Data.Common;DbEnumerator;false;DbEnumerator;(System.Data.IDataReader);;Argument[0];Argument[Qualifier];taint;generated | @@ -1598,11 +1548,8 @@ | System.Data;DataColumn;false;set_Prefix;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataColumnChangeEventArgs;false;DataColumnChangeEventArgs;(System.Data.DataRow,System.Data.DataColumn,System.Object);;Argument[1];Argument[Qualifier];taint;generated | | System.Data;DataColumnChangeEventArgs;false;get_Column;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataColumnCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataColumnCollection;false;Add;(System.Data.DataColumn);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataColumnCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier].Element;value;manual | -| System.Data;DataColumnCollection;false;Add;(System.String,System.Type);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataColumnCollection;false;Add;(System.String,System.Type,System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataColumnCollection;false;AddRange;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataColumnCollection;false;CopyTo;(System.Data.DataColumn[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataColumnCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1610,7 +1557,6 @@ | System.Data;DataColumnCollection;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetDateTime;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetFieldValue<>;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | -| System.Data;DataReaderExtensions;false;GetFieldValueAsync<>;(System.Data.Common.DbDataReader,System.String,System.Threading.CancellationToken);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetGuid;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetProviderSpecificValue;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetString;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | @@ -1642,16 +1588,10 @@ | System.Data;DataRelationCollection;false;Add;(System.Data.DataRelation);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataRelationCollection;false;CopyTo;(System.Data.DataRelation[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataRelationCollection;false;Remove;(System.Data.DataRelation);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;AddRange;(System.Data.DataRelation[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataRow;false;DataRow;(System.Data.DataRowBuilder);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRow;false;GetChildRows;(System.Data.DataRelation);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1755,12 +1695,10 @@ | System.Data;DataTable;false;set_PrimaryKey;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Data;DataTable;false;set_Site;(System.ComponentModel.ISite);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataTable;false;set_TableName;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data;DataTableCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataTableCollection;false;Add;(System.Data.DataTable);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];ReturnValue;taint;generated | -| System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataTableCollection;false;AddRange;(System.Data.DataTable[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;CopyTo;(System.Data.DataTable[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataTableCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | @@ -2341,8 +2279,10 @@ | System.IO.IsolatedStorage;IsolatedStorage;false;get_DomainIdentity;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.IO.IsolatedStorage;IsolatedStorageFileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.MemoryMappedFiles;MemoryMappedFile;false;CreateFromFile;(System.IO.FileStream,System.String,System.Int64,System.IO.MemoryMappedFiles.MemoryMappedFileAccess,System.IO.HandleInheritability,System.Boolean);;Argument[0];ReturnValue;taint;generated | | System.IO.MemoryMappedFiles;MemoryMappedFile;false;get_SafeMemoryMappedFileHandle;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.MemoryMappedFiles;MemoryMappedViewAccessor;false;get_SafeMemoryMappedViewHandle;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -2367,7 +2307,6 @@ | System.IO;BinaryReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | -| System.IO;BinaryWriter;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BinaryWriter;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -2427,8 +2366,10 @@ | System.IO;FileNotFoundException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;FileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;FileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.IO;FileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;FileStream;false;get_SafeFileHandle;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;FileSystemEventArgs;false;FileSystemEventArgs;(System.IO.WatcherChangeTypes,System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.IO;FileSystemEventArgs;false;FileSystemEventArgs;(System.IO.WatcherChangeTypes,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated | @@ -2501,7 +2442,6 @@ | System.IO;Stream;false;CopyToAsync;(System.IO.Stream);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;false;CopyToAsync;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;false;CopyToAsync;(System.IO.Stream,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | -| System.IO;Stream;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;Stream;false;Synchronized;(System.IO.Stream);;Argument[0];ReturnValue;taint;generated | | System.IO;Stream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | @@ -2509,13 +2449,10 @@ | System.IO;Stream;true;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;Stream;true;CopyTo;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;true;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | -| System.IO;Stream;true;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;true;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;Stream;true;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO;Stream;true;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;true;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;Stream;true;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO;Stream;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | | System.IO;StreamReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -2530,13 +2467,10 @@ | System.IO;StringWriter;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;Write;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;Write;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;Write;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextReader;false;Synchronized;(System.IO.TextReader);;Argument[0];ReturnValue;taint;generated | | System.IO;TextReader;true;Read;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;TextReader;true;Read;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;manual | @@ -2554,12 +2488,7 @@ | System.IO;TextWriter;false;Synchronized;(System.IO.TextWriter);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;false;TextWriter;(System.IFormatProvider);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;Write;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated | @@ -2573,14 +2502,7 @@ | System.IO;TextWriter;true;Write;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLine;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | @@ -2597,18 +2519,8 @@ | System.IO;TextWriter;true;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;get_FormatProvider;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;get_NewLine;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;set_NewLine;(System.String);;Argument[0];Argument[Qualifier];taint;generated | @@ -3879,17 +3791,12 @@ | System.Net.Http.Json;JsonContent;false;Create<>;(T,System.Net.Http.Headers.MediaTypeHeaderValue,System.Text.Json.JsonSerializerOptions);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.Net.Http;ByteArrayContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;DelegatingHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;DelegatingHandler;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;get_InnerHandler;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;set_InnerHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | @@ -3916,10 +3823,7 @@ | System.Net.Http;HttpContent;false;ReadAsStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpContent;false;get_Headers;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpContent;true;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;HttpContent;true;CreateContentReadStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpMessageInvoker;false;HttpMessageInvoker;(System.Net.Http.HttpMessageHandler,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;HttpMessageInvoker;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Http;HttpMethod;false;HttpMethod;(System.String);;Argument[0];Argument[Qualifier];taint;generated | @@ -3955,7 +3859,6 @@ | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ReadOnlyMemoryContent;false;ReadOnlyMemoryContent;(System.ReadOnlyMemory);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;SocketsHttpConnectionContext;false;get_DnsEndPoint;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;SocketsHttpConnectionContext;false;get_InitialRequestMessage;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -3992,13 +3895,9 @@ | System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_NegotiatedHttpVersion;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_PlaintextStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[0];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[1];ReturnValue;taint;generated | @@ -4124,7 +4023,6 @@ | System.Net.NetworkInformation;PhysicalAddress;false;PhysicalAddress;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.NetworkInformation;UnicastIPAddressInformationCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;AuthenticatedStream;false;AuthenticatedStream;(System.IO.Stream,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Security;AuthenticatedStream;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;AuthenticatedStream;false;get_InnerStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[2];Argument[Qualifier];taint;generated | @@ -4145,8 +4043,10 @@ | System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.Net.Security;NegotiateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;get_RemoteIdentity;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslApplicationProtocol;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslApplicationProtocol;false;get_Protocol;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4173,7 +4073,9 @@ | System.Net.Sockets;NetworkStream;false;NetworkStream;(System.Net.Sockets.Socket,System.IO.FileAccess,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;NetworkStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;NetworkStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.Net.Sockets;NetworkStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;NetworkStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.Net.Sockets;NetworkStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;NetworkStream;false;get_Socket;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;SafeSocketHandle;false;SafeSocketHandle;(System.IntPtr,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;Socket;false;Accept;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4185,7 +4087,6 @@ | System.Net.Sockets;Socket;false;ConnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;Socket;false;ConnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Sockets;Socket;false;DisconnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Sockets;Socket;false;EndAccept;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;Socket;false;ReceiveAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Sockets;Socket;false;ReceiveFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[4];Argument[Qualifier];taint;generated | | System.Net.Sockets;Socket;false;ReceiveFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[4];ReturnValue;taint;generated | @@ -4228,7 +4129,6 @@ | System.Net.Sockets;SocketAsyncEventArgs;false;set_SendPacketsElements;(System.Net.Sockets.SendPacketsElement[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Sockets;SocketAsyncEventArgs;false;set_UserToken;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;SocketException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;AcceptAsync;(System.Net.Sockets.Socket,System.Net.Sockets.Socket);;Argument[1];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint);;Argument[1];Argument[0];taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated | @@ -4240,8 +4140,6 @@ | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;ReceiveFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;ReceiveMessageFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendToAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];Argument[0];taint;generated | @@ -4252,8 +4150,6 @@ | System.Net.Sockets;TcpClient;false;set_Client;(System.Net.Sockets.Socket);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;AcceptSocket;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;TcpListener;false;AcceptTcpClient;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Sockets;TcpListener;false;EndAcceptSocket;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net.Sockets;TcpListener;false;EndAcceptTcpClient;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPAddress,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPEndPoint);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;get_LocalEndpoint;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4325,17 +4221,11 @@ | System.Net;CookieCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated | | System.Net;CookieException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated | | System.Net;CredentialCache;false;GetCredential;(System.Uri,System.String);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net;Dns;false;EndGetHostAddresses;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndGetHostByName;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndGetHostEntry;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndResolve;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;DnsEndPoint;false;DnsEndPoint;(System.String,System.Int32,System.Net.Sockets.AddressFamily);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;DnsEndPoint;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DnsEndPoint;false;get_Host;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DownloadDataCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DownloadStringCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net;FileWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;FileWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;get_ContentType;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4410,9 +4300,6 @@ | System.Net;HttpListenerTimeoutManager;false;get_IdleConnection;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpListenerTimeoutManager;false;set_DrainEntityBody;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;HttpListenerTimeoutManager;false;set_IdleConnection;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | -| System.Net;HttpWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetRequestStream;(System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4498,8 +4385,6 @@ | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest);;Argument[0];ReturnValue;taint;generated | | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];Argument[Qualifier];taint;generated | -| System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];ReturnValue;taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | @@ -5368,7 +5253,6 @@ | System.Resources;ResourceReader;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Resources;ResourceReader;false;GetResourceData;(System.String,System.String,System.Byte[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Resources;ResourceReader;false;ResourceReader;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | -| System.Resources;ResourceSet;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Resources;ResourceSet;false;ResourceSet;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | | System.Resources;ResourceSet;false;ResourceSet;(System.Resources.IResourceReader);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Resources;ResourceWriter;false;ResourceWriter;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | @@ -5733,7 +5617,6 @@ | System.Security.Cryptography.X509Certificates;X509Certificate;false;ToString;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Issuer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Subject;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;X509CertificateEnumerator;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;Add;(System.Security.Cryptography.X509Certificates.X509Certificate);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;AddRange;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier].Element;value;manual | @@ -6224,10 +6107,6 @@ | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;SendAsync<>;(System.Threading.Tasks.Dataflow.ITargetBlock,TInput,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;TryReceive<>;(System.Threading.Tasks.Dataflow.IReceivableSourceBlock,TOutput);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlockOptions;false;get_CancellationToken;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -7010,12 +6889,9 @@ | System.Xml.Schema;XmlSchemaSet;false;Add;(System.String,System.Xml.XmlReader);;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchemaSet);;Argument[0];Argument[Qualifier];taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;CopyTo;(System.Xml.Schema.XmlSchema[],System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Remove;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;Schemas;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;XmlSchemaSet;(System.Xml.XmlNameTable);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;get_CompilationSettings;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;get_GlobalAttributes;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -7102,10 +6978,8 @@ | System.Xml.Schema;XmlSchemaXPath;false;get_XPath;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaXPath;false;set_XPath;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[0];ReturnValue;taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;MakeUnique;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;ToArray;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Serialization;ImportContext;false;ImportContext;(System.Xml.Serialization.CodeIdentifiers,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | @@ -7411,7 +7285,6 @@ | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.Xml.XmlQualifiedName);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteId;(System.Object);;Argument[Qualifier];Argument[0];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncoded;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.Byte[],System.Xml.XmlQualifiedName);;Argument[2].Element;Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | @@ -7419,15 +7292,9 @@ | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.Byte[]);;Argument[2].Element;Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteSerializable;(System.Xml.Serialization.IXmlSerializable,System.String,System.String,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | @@ -9087,27 +8954,6 @@ | System;TupleExtensions;false;Deconstruct<,>;(System.Tuple,T1,T2);;Argument[0].Property[System.Tuple<,>.Item1];Argument[1];value;manual | | System;TupleExtensions;false;Deconstruct<,>;(System.Tuple,T1,T2);;Argument[0].Property[System.Tuple<,>.Item2];Argument[2];value;manual | | System;TupleExtensions;false;Deconstruct<>;(System.Tuple,T1);;Argument[0].Property[System.Tuple<>.Item1];Argument[1];value;manual | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | diff --git a/csharp/tools/tracing-config.lua b/csharp/tools/tracing-config.lua index b4ff0206b02..8aafc63e7e5 100644 --- a/csharp/tools/tracing-config.lua +++ b/csharp/tools/tracing-config.lua @@ -2,7 +2,54 @@ function RegisterExtractorPack(id) local extractor = GetPlatformToolsDirectory() .. 'Semmle.Extraction.CSharp.Driver' if OperatingSystem == 'windows' then extractor = extractor .. '.exe' end + + function DotnetMatcherBuild(compilerName, compilerPath, compilerArguments, + _languageId) + if compilerName ~= 'dotnet' and compilerName ~= 'dotnet.exe' then + return nil + end + + -- The dotnet CLI has the following usage instructions: + -- dotnet [sdk-options] [command] [command-options] [arguments] + -- we are interested in dotnet build, which has the following usage instructions: + -- dotnet [options] build [...] + -- For now, parse the command line as follows: + -- Everything that starts with `-` (or `/`) will be ignored. + -- The first non-option argument is treated as the command. + -- if that's `build`, we append `/p:UseSharedCompilation=false` to the command line, + -- otherwise we do nothing. + local match = false + local argv = compilerArguments.argv + if OperatingSystem == 'windows' then + -- let's hope that this split matches the escaping rules `dotnet` applies to command line arguments + -- or, at least, that it is close enough + argv = + NativeArgumentsToArgv(compilerArguments.nativeArgumentPointer) + end + for i, arg in ipairs(argv) do + -- dotnet options start with either - or / (both are legal) + local firstCharacter = string.sub(arg, 1, 1) + if not (firstCharacter == '-') and not (firstCharacter == '/') then + Log(1, 'Dotnet subcommand detected: %s', arg) + if arg == 'build' then match = true end + break + end + end + if match then + return { + order = ORDER_REPLACE, + invocation = BuildExtractorInvocation(id, compilerPath, + compilerPath, + compilerArguments, nil, { + '/p:UseSharedCompilation=false' + }) + } + end + return nil + end + local windowsMatchers = { + DotnetMatcherBuild, CreatePatternMatcher({'^dotnet%.exe$'}, MatchCompilerName, extractor, { prepend = {'--dotnetexec', '--cil'}, order = ORDER_BEFORE @@ -10,22 +57,21 @@ function RegisterExtractorPack(id) CreatePatternMatcher({'^csc.*%.exe$'}, MatchCompilerName, extractor, { prepend = {'--compiler', '"${compiler}"', '--cil'}, order = ORDER_BEFORE - }), CreatePatternMatcher({'^fakes.*%.exe$', 'moles.*%.exe'}, MatchCompilerName, nil, {trace = false}) } local posixMatchers = { - CreatePatternMatcher({'^mcs%.exe$', '^csc%.exe$'}, MatchCompilerName, - extractor, { - prepend = {'--compiler', '"${compiler}"', '--cil'}, - order = ORDER_BEFORE - - }), + DotnetMatcherBuild, CreatePatternMatcher({'^mono', '^dotnet$'}, MatchCompilerName, extractor, { prepend = {'--dotnetexec', '--cil'}, order = ORDER_BEFORE + }), + CreatePatternMatcher({'^mcs%.exe$', '^csc%.exe$'}, MatchCompilerName, + extractor, { + prepend = {'--compiler', '"${compiler}"', '--cil'}, + order = ORDER_BEFORE }), function(compilerName, compilerPath, compilerArguments, _languageId) if MatchCompilerName('^msbuild$', compilerName, compilerPath, compilerArguments) or @@ -49,7 +95,6 @@ function RegisterExtractorPack(id) else return posixMatchers end - end -- Return a list of minimum supported versions of the configuration file format 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 d3b04a32a0b..bb428f2c00d 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 @@ -135,6 +135,47 @@ pack names and use the ``--download`` flag:: The ``analyze`` command above runs the default suite from ``microsoft/coding-standards v1.0.0`` and the latest version of ``github/security-queries`` on the specified database. For further information about default suites, see ":ref:`Publishing and using CodeQL packs `". +Running a subset of queries in a CodeQL pack +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are using CodeQL CLI v2.8.1 or later, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack. + +The complete way to specify a set of queries is in the form ``scope/name@range:path``, where: + +- ``scope/name`` is the qualified name of a CodeQL pack. +- ``range`` is a `semver range `_. +- ``path`` is a file system path to a single query, a directory containing queries, or a query suite file. + +When you specify a ``scope/name``, the ``range`` and ``path`` are +optional. If you omit a ``range`` then the latest version of the +specified pack is used. If you omit a ``path`` then the default query suite +of the specified pack is used. + +The ``path`` can be one of a ``*.ql`` query file, a directory +containing one or more queries, or a ``.qls`` query suite file. If +you omit a pack name, then you must provide a ``path``, +which will be interpreted relative to the working directory +of the current process. + +If you specify a ``scope/name`` and ``path``, then the ``path`` cannot +be absolute. It is considered relative to the root of the CodeQL +pack. + +To analyze a database using all queries in the `experimental/Security` folder within the `codeql/cpp-queries` CodeQL pack you can use:: + + codeql database analyze --format=sarif-latest --output=results \ + codeql/cpp-queries:experimental/Security + +To run the `RedundantNullCheckParam.ql` query in the `codeql/cpp-queries` CodeQL pack use:: + + codeql database analyze --format=sarif-latest --output=results \ + 'codeql/cpp-queries:experimental/Likely Bugs/RedundantNullCheckParam.ql' + +To analyze your database using the `cpp-security-and-quality.qls` query suite from a version of the `codeql/cpp-queries` CodeQL pack that is >= 0.0.3 and < 0.1.0 (the highest compatible version will be chosen) you can use:: + + codeql database analyze --format=sarif-latest --output=results \ + 'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls' + For more information about CodeQL packs, see :doc:`About CodeQL Packs `. Running query suites @@ -223,7 +264,7 @@ you can include the query help for your custom queries in SARIF files generated After uploading the SARIF file to GitHub, the query help is shown in the code scanning UI for any alerts generated by the custom queries. -From CodeQL CLI 2.7.1 onwards, you can include markdown-rendered query help in SARIF files +From CodeQL CLI v2.7.1 onwards, you can include markdown-rendered query help in SARIF files by providing the ``--sarif-add-query-help`` option when running ``codeql database analyze``. For more information, see `Configuring CodeQL CLI in your CI system `__ diff --git a/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst b/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst index 6373440bcbb..da7a0872803 100644 --- a/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst +++ b/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst @@ -68,3 +68,11 @@ This command downloads all dependencies to the shared cache on the local disk. Note Running the ``codeql pack add`` and ``codeql pack install`` commands will generate or update the ``qlpack.lock.yml`` file. This file should be checked-in to version control. The ``qlpack.lock.yml`` file contains the precise version numbers used by the pack. + +.. pull-quote:: + + Note + + By default ``codeql pack install`` will install dependencies from the Container registry on GitHub.com. + You can install dependencies from a GitHub Enterprise Server Container registry by creating a ``qlconfig.yml`` file. + For more information, see ":doc:`Publishing and using CodeQL packs `." diff --git a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst index d28e27e10d7..985ca2659f3 100644 --- a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst +++ b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst @@ -72,3 +72,53 @@ The ``analyze`` command will run the default suite of any specified CodeQL packs :: codeql analyze / / + +Working with CodeQL packs on GitHub Enterprise Server +----------------------------------------------------- + +.. pull-quote:: + + Note + + The Container registry for GitHub Enterprise Server supports CodeQL query packs from GitHub Enterprise Server 3.6 onward. + +By default, the CodeQL CLI expects to download CodeQL packs from and publish packs to the Container registry on GitHub.com. However, you can also work with CodeQL packs in a Container registry on GitHub Enterprise Server 3.6, and later, by creating a ``qlconfig.yml`` file to tell the CLI which Container registry to use for each pack. + +Create a ``~/.codeql/qlconfig.yml`` file using your preferred text editor, and add entries to specify which registry to use for one or more package name patterns. +For example, the following ``qlconfig.yml`` file associates all packs with the Container registry for the GitHub Enterprise Server at ``GHE_HOSTNAME``, except packs matching ``codeql/*``, which are associated with the Container registry on GitHub.com: + +.. code-block:: yaml + + registries: + - packages: 'codeql/*' + url: https://ghcr.io/v2/ + - packages: '*' + url: https://containers.GHE_HOSTNAME/v2/ + +The CodeQL CLI will determine which registry to use for a given package name by finding the first item in the ``registries`` list with a ``packages`` property that matches that package name. +This means that you'll generally want to define the most specific package name patterns first. + +You can now use ``codeql pack publish``, ``codeql pack download``, and ``codeql database analyze`` to manage packs on GitHub Enterprise Server. + +Authenticating to GitHub Container registries +--------------------------------------------- + +You can publish packs and download private packs by authenticating to the appropriate GitHub Container registry. + +You can authenticate to the Container registry on GitHub.com in two ways: + +1. Pass the ``--github-auth-stdin`` option to the CodeQL CLI, then supply a GitHub Apps token or personal access token via standard input. +2. Set the ``GITHUB_TOKEN`` environment variable to a GitHub Apps token or personal access token. + +Similarly, you can authenticate to a GHES Container registry, or authenticate to multiple registries simultaneously (for example, to download or run private packs from multiple registries) in two ways: + +1. Pass the ``--registries-auth-stdin`` option to the CodeQL CLI, then supply a registry authentication string via standard input. +2. Set the ``CODEQL_REGISTRIES_AUTH`` environment variable to a registry authentication string. + +A registry authentication string is a comma-separated list of ``=`` pairs, where ``registry-url`` is a GitHub Container registry URL, such as ``https://containers.GHE_HOSTNAME/v2/``, and ``token`` is a GitHub Apps token or personal access token for that GitHub Container registry. +This ensures that each token is only passed to the Container registry you specify. +For instance, the following registry authentication string specifies that the CodeQL CLI should authenticate to the Container registry on GitHub.com using the token ```` and to the Container registry for the GHES instance at ``GHE_HOSTNAME`` using the token ````: + +.. code-block:: none + + https://ghcr.io/v2/=,https://containers.GHE_HOSTNAME/v2/= diff --git a/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst b/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst index 4353f9402b7..be66125846a 100644 --- a/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst +++ b/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst @@ -11,14 +11,17 @@ CodeQL. Languages and compilers ####################### -CodeQL supports the following languages and compilers. +The current versions of the CodeQL CLI (`changelog `__, `releases `__), +CodeQL library packs (`source `__), +and CodeQL bundle (`releases `__) +support the following languages and compilers. .. include:: ../support/reusables/versions-compilers.rst Frameworks and libraries ######################## -The libraries and queries in the current version of CodeQL have been explicitly checked against the libraries and frameworks listed below. +The current versions of the CodeQL library and query packs (`source `__) have been explicitly checked against the libraries and frameworks listed below. .. pull-quote:: diff --git a/docs/codeql/query-help/cpp.rst b/docs/codeql/query-help/cpp.rst index 7c3cbe304d7..12d2dfbf53e 100644 --- a/docs/codeql/query-help/cpp.rst +++ b/docs/codeql/query-help/cpp.rst @@ -3,7 +3,9 @@ CodeQL query help for C and C++ .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/cpp-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-cpp.rst \ No newline at end of file diff --git a/docs/codeql/query-help/csharp.rst b/docs/codeql/query-help/csharp.rst index 9c5c6351ce3..5d7f732a588 100644 --- a/docs/codeql/query-help/csharp.rst +++ b/docs/codeql/query-help/csharp.rst @@ -3,6 +3,8 @@ CodeQL query help for C# .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/csharp-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-csharp.rst \ No newline at end of file diff --git a/docs/codeql/query-help/go.rst b/docs/codeql/query-help/go.rst index 9e3050f74d0..bcd4aba9b51 100644 --- a/docs/codeql/query-help/go.rst +++ b/docs/codeql/query-help/go.rst @@ -3,6 +3,8 @@ CodeQL query help for Go .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/go-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-go.rst diff --git a/docs/codeql/query-help/java.rst b/docs/codeql/query-help/java.rst index 8af2ee52890..4876546d2dc 100644 --- a/docs/codeql/query-help/java.rst +++ b/docs/codeql/query-help/java.rst @@ -3,6 +3,8 @@ CodeQL query help for Java .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/java-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-java.rst diff --git a/docs/codeql/query-help/javascript.rst b/docs/codeql/query-help/javascript.rst index d7cf6797852..58fe97eb3b0 100644 --- a/docs/codeql/query-help/javascript.rst +++ b/docs/codeql/query-help/javascript.rst @@ -3,6 +3,8 @@ CodeQL query help for JavaScript .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/javascript-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-javascript.rst \ No newline at end of file diff --git a/docs/codeql/query-help/python.rst b/docs/codeql/query-help/python.rst index da68c1caa9b..9d915d443f3 100644 --- a/docs/codeql/query-help/python.rst +++ b/docs/codeql/query-help/python.rst @@ -3,6 +3,8 @@ CodeQL query help for Python .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/python-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-python.rst \ No newline at end of file diff --git a/docs/codeql/query-help/ruby.rst b/docs/codeql/query-help/ruby.rst index 3ce1304ba76..e733aecaf79 100644 --- a/docs/codeql/query-help/ruby.rst +++ b/docs/codeql/query-help/ruby.rst @@ -3,6 +3,8 @@ CodeQL query help for Ruby .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/ruby-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-ruby.rst diff --git a/docs/codeql/reusables/beta-note-package-management.rst b/docs/codeql/reusables/beta-note-package-management.rst index a4fd362a70c..7697c9a47d9 100644 --- a/docs/codeql/reusables/beta-note-package-management.rst +++ b/docs/codeql/reusables/beta-note-package-management.rst @@ -2,4 +2,4 @@ Note - The CodeQL package management functionality, including CodeQL packs, is currently available as a beta release and is subject to change. During the beta release, CodeQL packs are available only using GitHub Packages - the GitHub Container registry. To use this beta functionality, install version 2.6.0 or higher of the CodeQL CLI bundle from: https://github.com/github/codeql-action/releases. \ No newline at end of file + The CodeQL package management functionality, including CodeQL packs, is currently available as a beta release and is subject to change. During the beta release, CodeQL packs are available only using GitHub Packages - the GitHub Container registry. To use this beta functionality, install the latest version of the CodeQL CLI bundle from: https://github.com/github/codeql-action/releases. diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/support/reusables/frameworks.rst index 12bcd5af8e6..fc5410648cf 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/support/reusables/frameworks.rst @@ -1,6 +1,10 @@ C and C++ built-in support ================================ +Provided by the current versions of the +CodeQL query pack ``codeql/cpp-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/cpp-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable @@ -14,6 +18,10 @@ C and C++ built-in support C# built-in support ================================ +Provided by the current versions of the +CodeQL query pack ``codeql/csharp-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/csharp-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable @@ -33,6 +41,10 @@ C# built-in support Go built-in support ================================ +Provided by the current versions of the +CodeQL query pack ``codeql/go-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/go-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable @@ -84,6 +96,10 @@ Go built-in support Java built-in support ================================== +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 `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable @@ -113,6 +129,10 @@ Java built-in support JavaScript and TypeScript built-in support ======================================================= +Provided by the current versions of the +CodeQL query pack ``codeql/javascript-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/javascript-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable @@ -156,6 +176,10 @@ JavaScript and TypeScript built-in support Python built-in support ==================================== +Provided by the current versions of the +CodeQL query pack ``codeql/python-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/python-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 1767b297fc6..23c4fc2eb4f 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.2.1 + +## 0.2.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + ## 0.1.4 ## 0.1.3 diff --git a/cpp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/go/ql/lib/change-notes/released/0.2.0.md similarity index 83% rename from cpp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md rename to go/ql/lib/change-notes/released/0.2.0.md index 2bd95798f89..ded60d11b7e 100644 --- a/cpp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ b/go/ql/lib/change-notes/released/0.2.0.md @@ -1,4 +1,5 @@ ---- -category: deprecated ---- +## 0.2.0 + +### Deprecated APIs + * The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/go/ql/lib/change-notes/released/0.2.1.md b/go/ql/lib/change-notes/released/0.2.1.md new file mode 100644 index 00000000000..c260de2a9ee --- /dev/null +++ b/go/ql/lib/change-notes/released/0.2.1.md @@ -0,0 +1 @@ +## 0.2.1 diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index e8ee3af8ef9..df29a726bcc 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.1 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index f416a2612a8..c360e550193 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.2.0-dev +version: 0.2.2-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 541c8c95377..1697aa9e561 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.1 + +## 0.2.0 + ## 0.1.4 ## 0.1.3 diff --git a/go/ql/src/change-notes/released/0.2.0.md b/go/ql/src/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..79a5f33514f --- /dev/null +++ b/go/ql/src/change-notes/released/0.2.0.md @@ -0,0 +1 @@ +## 0.2.0 diff --git a/go/ql/src/change-notes/released/0.2.1.md b/go/ql/src/change-notes/released/0.2.1.md new file mode 100644 index 00000000000..c260de2a9ee --- /dev/null +++ b/go/ql/src/change-notes/released/0.2.1.md @@ -0,0 +1 @@ +## 0.2.1 diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index e8ee3af8ef9..df29a726bcc 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.1 diff --git a/go/ql/lib/definitions.ql b/go/ql/src/definitions.ql similarity index 100% rename from go/ql/lib/definitions.ql rename to go/ql/src/definitions.ql diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 062631cb68b..75ed3c98275 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.2.0-dev +version: 0.2.2-dev groups: - go - queries diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index b9d52d9d75e..598035e03c3 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -1,121 +1,121 @@ -package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value -android.app,16,,103,,,,,,7,,,,,,,,,9,,,,,,,,,,,,,,,,,,18,85 -android.content,24,27,108,,,,,,16,,,,,,,,,,,,,,,,,8,,,,,,,,27,,31,77 -android.database,59,,30,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,30, -android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 -android.os,,,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,41,81 -android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,16,, -android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,2,, -android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, -androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,5,,27,61 -cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -com.google.common.base,4,,85,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,62,23 -com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 -com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 -com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,, -com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,72,1 -com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,, -com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, -com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,, -com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,, -flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,7,, -jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, -jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,94,55 -java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -java.io,37,,39,,15,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,39, -java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,46,12 -java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,3,7, -java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,6, -java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,, -java.util,44,,438,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,24,414 -javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,7,, -javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, -javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,, -javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,, -javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, -javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, -javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, -javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, -javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, -javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,94,55 -javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,6, -javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,, -jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 -kotlin.jvm.internal,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,, -ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, -okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,22,25 -org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.io,104,,561,,89,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,547,14 -org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131 -org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 -org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,2,39, -org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2, -org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 -org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,2,,,3,62,8 -org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,57, -org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,, -org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,4,4 -org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, -org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,, -org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,, -org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,, -org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 -org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,, -org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,, -org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,2,4 -org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 -org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 -org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,60,10 -org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,, -org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,, -org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, -org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 -org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 -org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, -org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,3,, -org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, -org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, -org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,, -org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 -org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, -play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, -ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 -ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, +package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value +android.app,16,,103,,,,,,7,,,,,,,,,9,,,,,,,,,,,,,,,,,,,18,85 +android.content,24,31,108,,,,,,16,,,,,,,,,,,,,,,,,8,,,,,,,4,,27,,31,77 +android.database,59,,30,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,30, +android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 +android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81 +android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,16,, +android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,, +android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, +androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,5,,27,61 +cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +com.google.common.base,4,,85,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,62,23 +com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 +com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 +com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,, +com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,72,1 +com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,, +com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, +com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,, +com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,, +flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, +jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 +java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +java.io,37,,39,,15,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,39, +java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12 +java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,3,7, +java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,6, +java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,, +java.util,44,,458,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,36,422 +javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, +javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,, +javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,, +javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, +javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, +javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, +javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 +javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6, +javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,, +jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 +kotlin.jvm.internal,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,, +ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,, +okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,22,25 +org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.io,104,,561,,89,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,547,14 +org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131 +org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 +org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39, +org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2, +org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 +org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,2,,,,3,62,8 +org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,57, +org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,4,4 +org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, +org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,, +org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,, +org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,, +org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, +org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 +org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,, +org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,, +org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,2,4 +org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 +org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 +org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,60,10 +org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,, +org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,, +org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, +org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 +org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 +org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, +org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,3,, +org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, +org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, +org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,, +org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 +org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, +play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, +ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 +ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index cd8995b77d5..06101b6633d 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -7,7 +7,7 @@ Java framework & library support :widths: auto Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑036` :sub:`Path traversal`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑319` :sub:`Cleartext transmission` - Android,``android.*``,46,424,108,,,3,67,,, + Android,``android.*``,52,424,108,,,3,67,,, `Apache Commons Collections `_,"``org.apache.commons.collections``, ``org.apache.commons.collections4``",,1600,,,,,,,, `Apache Commons IO `_,``org.apache.commons.io``,,561,104,89,,,,,,15 `Apache Commons Lang `_,``org.apache.commons.lang3``,,424,,,,,,,, @@ -15,9 +15,9 @@ Java framework & library support `Apache HttpComponents `_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25 `Google Guava `_,``com.google.common.*``,,728,39,,6,,,,, `JSON-java `_,``org.json``,,236,,,,,,,, - Java Standard Library,``java.*``,3,549,130,28,,,7,,,10 + Java Standard Library,``java.*``,3,569,130,28,,,7,,,10 Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2 `Spring `_,``org.springframework.*``,29,476,101,,,,19,14,,29 Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``kotlin.jvm.internal``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",65,395,932,,,,14,18,,3 - Totals,,211,6410,1474,117,6,10,107,33,1,84 + Totals,,217,6430,1474,117,6,10,107,33,1,84 diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 29376368adc..4100594ad35 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -6,6 +6,7 @@ import com.github.codeql.utils.versions.functionN import com.github.codeql.utils.versions.getIrStubFromDescriptor import com.semmle.extractor.java.OdasaOutput import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.backend.common.lower.parents import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity import org.jetbrains.kotlin.descriptors.* @@ -80,7 +81,7 @@ open class KotlinFileExtractor( } } - file.declarations.map { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) } + file.declarations.forEach { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) } extractStaticInitializer(file, null) CommentExtractor(this, file, tw.fileId).extract() } @@ -133,7 +134,7 @@ open class KotlinFileExtractor( is IrProperty -> { val parentId = useDeclarationParent(declaration.parent, false)?.cast() if (parentId != null) { - extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, null, listOf()) + extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, extractPrivateMembers = extractPrivateMembers, null, listOf()) } Unit } @@ -181,7 +182,7 @@ open class KotlinFileExtractor( } } - fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label? { + private fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label? { with("type parameter", tp) { val parentId = getTypeParameterParentLabel(tp) ?: return null val id = tw.getLabelFor(getTypeParameterLabel(tp)) @@ -216,7 +217,7 @@ open class KotlinFileExtractor( } } - fun extractVisibility(elementForLocation: IrElement, id: Label, v: DescriptorVisibility) { + private fun extractVisibility(elementForLocation: IrElement, id: Label, v: DescriptorVisibility) { with("visibility", elementForLocation) { when (v) { DescriptorVisibilities.PRIVATE -> addModifiers(id, "private") @@ -250,7 +251,7 @@ open class KotlinFileExtractor( } } - fun extractClassModifiers(c: IrClass, id: Label) { + private fun extractClassModifiers(c: IrClass, id: Label) { with("class modifiers", c) { when (c.modality) { Modality.FINAL -> addModifiers(id, "final") @@ -314,8 +315,21 @@ open class KotlinFileExtractor( val locId = getLocation(c, argsIncludingOuterClasses) tw.writeHasLocation(id, locId) - // Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters. - extractEnclosingClass(c, id, locId, argsIncludingOuterClasses?.drop(c.typeParameters.size) ?: listOf()) + // Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters if this is an inner class. + // For example, in `class Outer { inner class Inner { } }`, `Inner` nests within `Outer` and raw `Inner<>` within `Outer<>`, + // but for a similar non-`inner` (in Java terms, static nested) class both `Inner` and `Inner<>` nest within the unbound type `Outer`. + val useBoundOuterType = (c.isInner || c.isLocal) && (c.parents.map { // Would use `firstNotNullOfOrNull`, but this doesn't exist in Kotlin 1.4 + when(it) { + is IrClass -> when { + it.typeParameters.isNotEmpty() -> true // Type parameters visible to this class -- extract an enclosing bound or raw type. + !(it.isInner || it.isLocal) -> false // No type parameters seen yet, and this is a static class -- extract an enclosing unbound type. + else -> null // No type parameters seen here, but may be visible enclosing type parameters; keep searching. + } + else -> null // Look through enclosing non-class entities (this may need to change) + } + }.firstOrNull { it != null } ?: false) + + extractEnclosingClass(c, id, locId, if (useBoundOuterType) argsIncludingOuterClasses?.drop(c.typeParameters.size) else listOf()) return id } @@ -350,7 +364,7 @@ open class KotlinFileExtractor( if (shouldExtractDecl(it, false)) { when(it) { is IrFunction -> extractFunction(it, id, extractBody = false, extractMethodAndParameterTypeAccesses = false, typeParamSubstitution, argsIncludingOuterClasses) - is IrProperty -> extractProperty(it, id, extractBackingField = false, extractFunctionBodies = false, typeParamSubstitution, argsIncludingOuterClasses) + is IrProperty -> extractProperty(it, id, extractBackingField = false, extractFunctionBodies = false, extractPrivateMembers = false, typeParamSubstitution, argsIncludingOuterClasses) else -> {} } } @@ -371,7 +385,7 @@ open class KotlinFileExtractor( tw.writeHasLocation(stmtId, locId) } - fun extractObinitFunction(c: IrClass, parentId: Label) { + private fun extractObinitFunction(c: IrClass, parentId: Label) { // add method: val obinitLabel = getObinitLabel(c) val obinitId = tw.getLabelFor(obinitLabel) @@ -392,6 +406,8 @@ open class KotlinFileExtractor( extractDeclInitializers(c.declarations, false) { Pair(blockId, obinitId) } } + val jvmStaticFqName = FqName("kotlin.jvm.JvmStatic") + fun extractClassSource(c: IrClass, extractDeclarations: Boolean, extractStaticInitializer: Boolean, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean): Label { with("class source", c) { DeclarationStackAdjuster(c).use { @@ -428,9 +444,10 @@ open class KotlinFileExtractor( c.typeParameters.mapIndexed { idx, param -> extractTypeParameter(param, idx, javaClass?.typeParameters?.getOrNull(idx)) } if (extractDeclarations) { - c.declarations.map { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) } + c.declarations.forEach { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) } if (extractStaticInitializer) extractStaticInitializer(c, id) + extractJvmStaticProxyMethods(c, id, extractPrivateMembers, extractFunctionBodies) } if (c.isNonCompanionObject) { // For `object MyObject { ... }`, the .class has an @@ -458,7 +475,78 @@ open class KotlinFileExtractor( } } - private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label, innerLocId: Label, parentClassTypeArguments: List) { + private fun extractJvmStaticProxyMethods(c: IrClass, classId: Label, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) { + + // Add synthetic forwarders for any JvmStatic methods or properties: + val companionObject = c.companionObject() ?: return + + val cType = c.typeWith() + val companionType = companionObject.typeWith() + + fun makeProxyFunction(f: IrFunction) { + // Emit a function in class `c` that delegates to the same function defined on `c.CompanionInstance`. + val proxyFunctionId = tw.getLabelFor(getFunctionLabel(f, classId, listOf())) + // We extract the function prototype with its ID overridden to belong to `c` not the companion object, + // but suppress outputting the body, which we will replace with a delegating call below. + forceExtractFunction(f, classId, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution = null, classTypeArgsIncludingOuterClasses = listOf(), idOverride = proxyFunctionId, locOverride = null, extractOrigin = false) + addModifiers(proxyFunctionId, "static") + tw.writeCompiler_generated(proxyFunctionId, CompilerGeneratedKinds.JVMSTATIC_PROXY_METHOD.kind) + if (extractFunctionBodies) { + val realFunctionLocId = tw.getLocation(f) + extractExpressionBody(proxyFunctionId, realFunctionLocId).also { returnId -> + extractRawMethodAccess( + f, + realFunctionLocId, + f.returnType, + proxyFunctionId, + returnId, + 0, + returnId, + f.valueParameters.size, + { argParent, idxOffset -> + f.valueParameters.forEachIndexed { idx, param -> + val syntheticParamId = useValueParameter(param, proxyFunctionId) + extractVariableAccess(syntheticParamId, param.type, realFunctionLocId, argParent, idxOffset + idx, proxyFunctionId, returnId) + } + }, + companionType, + { callId -> + val companionField = useCompanionObjectClassInstance(companionObject)?.id + extractVariableAccess(companionField, companionType, realFunctionLocId, callId, -1, proxyFunctionId, returnId).also { varAccessId -> + extractTypeAccessRecursive(cType, realFunctionLocId, varAccessId, -1, proxyFunctionId, returnId) + } + }, + null + ) + } + } + } + + companionObject.declarations.forEach { + if (shouldExtractDecl(it, extractPrivateMembers)) { + val wholeDeclAnnotated = it.hasAnnotation(jvmStaticFqName) + when(it) { + is IrFunction -> { + if (wholeDeclAnnotated) + makeProxyFunction(it) + } + is IrProperty -> { + it.getter?.let { getter -> + if (wholeDeclAnnotated || getter.hasAnnotation(jvmStaticFqName)) + makeProxyFunction(getter) + } + it.setter?.let { setter -> + if (wholeDeclAnnotated || setter.hasAnnotation(jvmStaticFqName)) + makeProxyFunction(setter) + } + } + } + } + } + } + + // If `parentClassTypeArguments` is null, the parent class is a raw type. + private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label, innerLocId: Label, parentClassTypeArguments: List?) { with("enclosing class", innerDeclaration) { var parent: IrDeclarationParent? = innerDeclaration.parent while (parent != null) { @@ -506,7 +594,7 @@ open class KotlinFileExtractor( data class FieldResult(val id: Label, val name: String) - fun useCompanionObjectClassInstance(c: IrClass): FieldResult? { + private fun useCompanionObjectClassInstance(c: IrClass): FieldResult? { val parent = c.parent if(!c.isCompanion) { logger.error("Using companion instance for non-companion class") @@ -524,7 +612,7 @@ open class KotlinFileExtractor( } } - fun useObjectClassInstance(c: IrClass): FieldResult { + private fun useObjectClassInstance(c: IrClass): FieldResult { if(!c.isNonCompanionObject) { logger.error("Using instance for non-object class") } @@ -719,13 +807,13 @@ open class KotlinFileExtractor( } } - fun extractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) = + private fun extractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) = if (isFake(f)) null else forceExtractFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, null, null) - fun forceExtractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?, idOverride: Label?, locOverride: Label?): Label { + private fun forceExtractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?, idOverride: Label?, locOverride: Label?, extractOrigin: Boolean = true): Label { with("function", f) { DeclarationStackAdjuster(f).use { @@ -782,13 +870,15 @@ open class KotlinFileExtractor( val methodId = id.cast() tw.writeMethods(methodId, shortName.nameInDB, "${shortName.nameInDB}$paramsSignature", returnType.javaResult.id, parentId, sourceDeclaration.cast()) tw.writeMethodsKotlinType(methodId, returnType.kotlinResult.id) - when (f.origin) { - IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER -> - tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.GENERATED_DATA_CLASS_MEMBER.kind) - IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR -> - tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.DEFAULT_PROPERTY_ACCESSOR.kind) - IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER -> - tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.ENUM_CLASS_SPECIAL_MEMBER.kind) + if (extractOrigin) { + when (f.origin) { + IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER -> + tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.GENERATED_DATA_CLASS_MEMBER.kind) + IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR -> + tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.DEFAULT_PROPERTY_ACCESSOR.kind) + IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER -> + tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.ENUM_CLASS_SPECIAL_MEMBER.kind) + } } if (extractMethodAndParameterTypeAccesses) { @@ -798,6 +888,10 @@ open class KotlinFileExtractor( if (shortName.nameInDB != shortName.kotlinName) { tw.writeKtFunctionOriginalNames(methodId, shortName.kotlinName) } + + if (f.hasInterfaceParent() && f.body != null) { + addModifiers(id, "default") // The actual output class file may or may not have this modifier, depending on the -Xjvm-default setting. + } } tw.writeHasLocation(id, locId) @@ -809,10 +903,13 @@ open class KotlinFileExtractor( } extractVisibility(f, id, f.visibility) - if (isStaticFunction(f)) { + + if (f.isInline) { + addModifiers(id, "inline") + } + if (f.shouldExtractAsStatic) { addModifiers(id, "static") } - if (f is IrSimpleFunction && f.overriddenSymbols.isNotEmpty()) { addModifiers(id, "override") } @@ -828,7 +925,7 @@ open class KotlinFileExtractor( && f.symbol !is IrConstructorSymbol // not a constructor } - fun extractField(f: IrField, parentId: Label): Label { + private fun extractField(f: IrField, parentId: Label): Label { with("field", f) { DeclarationStackAdjuster(f).use { declarationStack.push(f) @@ -862,7 +959,7 @@ open class KotlinFileExtractor( return id } - fun extractProperty(p: IrProperty, parentId: Label, extractBackingField: Boolean, extractFunctionBodies: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) { + private fun extractProperty(p: IrProperty, parentId: Label, extractBackingField: Boolean, extractFunctionBodies: Boolean, extractPrivateMembers: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) { with("property", p) { if (isFake(p)) return @@ -877,28 +974,34 @@ open class KotlinFileExtractor( val getter = p.getter val setter = p.setter - if (getter != null) { - val getterId = extractFunction(getter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast() - if (getterId != null) { - tw.writeKtPropertyGetters(id, getterId) - } - } else { + if (getter == null) { if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) { logger.warnElement("IrProperty without a getter", p) } + } else if (shouldExtractDecl(getter, extractPrivateMembers)) { + val getterId = extractFunction(getter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast() + if (getterId != null) { + tw.writeKtPropertyGetters(id, getterId) + if (getter.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR) { + tw.writeCompiler_generated(getterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_GETTER.kind) + } + } } - if (setter != null) { + if (setter == null) { + if (p.isVar && !isExternalDeclaration(p)) { + logger.warnElement("isVar property without a setter", p) + } + } else if (shouldExtractDecl(setter, extractPrivateMembers)) { if (!p.isVar) { logger.warnElement("!isVar property with a setter", p) } val setterId = extractFunction(setter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast() if (setterId != null) { tw.writeKtPropertySetters(id, setterId) - } - } else { - if (p.isVar && !isExternalDeclaration(p)) { - logger.warnElement("isVar property without a setter", p) + if (setter.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR) { + tw.writeCompiler_generated(setterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_SETTER.kind) + } } } @@ -931,7 +1034,7 @@ open class KotlinFileExtractor( } } - fun extractEnumEntry(ee: IrEnumEntry, parentId: Label, extractTypeAccess: Boolean) { + private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label, extractTypeAccess: Boolean) { with("enum entry", ee) { DeclarationStackAdjuster(ee).use { val id = useEnumEntry(ee) @@ -953,7 +1056,7 @@ open class KotlinFileExtractor( } } - fun extractTypeAlias(ta: IrTypeAlias) { + private fun extractTypeAlias(ta: IrTypeAlias) { with("type alias", ta) { if (ta.typeParameters.isNotEmpty()) { // TODO: Extract this information @@ -968,7 +1071,7 @@ open class KotlinFileExtractor( } } - fun extractBody(b: IrBody, callable: Label) { + private fun extractBody(b: IrBody, callable: Label) { with("body", b) { when (b) { is IrBlockBody -> extractBlockBody(b, callable) @@ -981,7 +1084,7 @@ open class KotlinFileExtractor( } } - fun extractBlockBody(b: IrBlockBody, callable: Label) { + private fun extractBlockBody(b: IrBlockBody, callable: Label) { with("block body", b) { val id = tw.getFreshIdLabel() val locId = tw.getLocation(b) @@ -993,7 +1096,7 @@ open class KotlinFileExtractor( } } - fun extractSyntheticBody(b: IrSyntheticBody, callable: Label) { + private fun extractSyntheticBody(b: IrSyntheticBody, callable: Label) { with("synthetic body", b) { when (b.kind) { IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1) @@ -1002,17 +1105,23 @@ open class KotlinFileExtractor( } } - fun extractExpressionBody(b: IrExpressionBody, callable: Label) { + private fun extractExpressionBody(b: IrExpressionBody, callable: Label) { with("expression body", b) { - val blockId = tw.getFreshIdLabel() val locId = tw.getLocation(b) - tw.writeStmts_block(blockId, callable, 0, callable) - tw.writeHasLocation(blockId, locId) + extractExpressionBody(callable, locId).also { returnId -> + extractExpressionExpr(b.expression, callable, returnId, 0, returnId) + } + } + } - val returnId = tw.getFreshIdLabel() + fun extractExpressionBody(callable: Label, locId: Label): Label { + val blockId = tw.getFreshIdLabel() + tw.writeStmts_block(blockId, callable, 0, callable) + tw.writeHasLocation(blockId, locId) + + return tw.getFreshIdLabel().also { returnId -> tw.writeStmts_returnstmt(returnId, blockId, 0, callable) tw.writeHasLocation(returnId, locId) - extractExpressionExpr(b.expression, callable, returnId, 0, returnId) } } @@ -1026,7 +1135,7 @@ open class KotlinFileExtractor( return v } - fun extractVariable(v: IrVariable, callable: Label, parent: Label, idx: Int) { + private fun extractVariable(v: IrVariable, callable: Label, parent: Label, idx: Int) { with("variable", v) { val stmtId = tw.getFreshIdLabel() val locId = tw.getLocation(getVariableLocationProvider(v)) @@ -1036,7 +1145,7 @@ open class KotlinFileExtractor( } } - fun extractVariableExpr(v: IrVariable, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { + private fun extractVariableExpr(v: IrVariable, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { with("variable expr", v) { val varId = useVariable(v) val exprId = tw.getFreshIdLabel() @@ -1060,7 +1169,7 @@ open class KotlinFileExtractor( } } - fun extractStatement(s: IrStatement, callable: Label, parent: Label, idx: Int) { + private fun extractStatement(s: IrStatement, callable: Label, parent: Label, idx: Int) { with("statement", s) { when(s) { is IrExpression -> { @@ -1281,12 +1390,53 @@ open class KotlinFileExtractor( dispatchReceiver: IrExpression?, extensionReceiver: IrExpression?, typeArguments: List = listOf(), - extractClassTypeArguments: Boolean = false) { + extractClassTypeArguments: Boolean = false, + superQualifierSymbol: IrClassSymbol? = null) { + + val locId = tw.getLocation(callsite) + + extractRawMethodAccess( + syntacticCallTarget, + locId, + callsite.type, + enclosingCallable, + callsiteParent, + childIdx, + enclosingStmt, + valueArguments.size, + { argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) }, + dispatchReceiver?.type, + dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } }, + extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } }, + typeArguments, + extractClassTypeArguments, + superQualifierSymbol + ) + + } + + + fun extractRawMethodAccess( + syntacticCallTarget: IrFunction, + locId: Label, + returnType: IrType, + enclosingCallable: Label, + callsiteParent: Label, + childIdx: Int, + enclosingStmt: Label, + nValueArguments: Int, + extractValueArguments: (Label, Int) -> Unit, + drType: IrType?, + extractDispatchReceiver: ((Label) -> Unit)?, + extractExtensionReceiver: ((Label) -> Unit)?, + typeArguments: List = listOf(), + extractClassTypeArguments: Boolean = false, + superQualifierSymbol: IrClassSymbol? = null) { val callTarget = syntacticCallTarget.target.realOverrideTarget val id = tw.getFreshIdLabel() - val type = useType(callsite.type) - val locId = tw.getLocation(callsite) + val type = useType(returnType) + tw.writeExprs_methodaccess(id, type.javaResult.id, callsiteParent, childIdx) tw.writeExprsKotlinType(id, type.kotlinResult.id) tw.writeHasLocation(id, locId) @@ -1296,8 +1446,6 @@ open class KotlinFileExtractor( // type arguments at index -2, -3, ... extractTypeArguments(typeArguments, locId, id, enclosingCallable, enclosingStmt, -2, true) - val drType = dispatchReceiver?.type - val isFunctionInvoke = drType != null && drType is IrSimpleType && drType.isFunctionOrKFunction() @@ -1340,44 +1488,50 @@ open class KotlinFileExtractor( tw.writeCallableBinding(id, methodId) - if (dispatchReceiver != null) { - extractExpressionExpr(dispatchReceiver, enclosingCallable, id, -1, enclosingStmt) - } else if (isStaticFunction(callTarget)) { + if (callTarget.shouldExtractAsStatic) { extractStaticTypeAccessQualifier(callTarget, id, locId, enclosingCallable, enclosingStmt) + } else if (superQualifierSymbol != null) { + extractSuperAccess(superQualifierSymbol.typeWith(), enclosingCallable, id, -1, enclosingStmt, locId) + } else if (extractDispatchReceiver != null) { + extractDispatchReceiver(id) } } - val idxOffset = if (extensionReceiver != null) 1 else 0 + val idxOffset = if (extractExtensionReceiver != null) 1 else 0 val argParent = if (isBigArityFunctionInvoke) { - extractArrayCreationWithInitializer(id, valueArguments.size + idxOffset, locId, enclosingCallable, enclosingStmt) + extractArrayCreationWithInitializer(id, nValueArguments + idxOffset, locId, enclosingCallable, enclosingStmt) } else { id } - if (extensionReceiver != null) { - extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) + if (extractExtensionReceiver != null) { + extractExtensionReceiver(argParent) } - extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) + extractValueArguments(argParent, idxOffset) } private fun extractStaticTypeAccessQualifier(target: IrDeclaration, parentExpr: Label, locId: Label, enclosingCallable: Label, enclosingStmt: Label) { - if (target.isStaticOfClass) { + if (target.shouldExtractAsStaticMemberOfClass) { extractTypeAccessRecursive(target.parentAsClass.toRawType(), locId, parentExpr, -1, enclosingCallable, enclosingStmt) - } else if (target.isStaticOfFile) { + } else if (target.shouldExtractAsStaticMemberOfFile) { extractTypeAccess(useFileClassType(target.parent as IrFile), locId, parentExpr, -1, enclosingCallable, enclosingStmt) } } - private val IrDeclaration.isStaticOfClass: Boolean - get() = this.isStatic && parent is IrClass + private val IrDeclaration.shouldExtractAsStaticMemberOfClass: Boolean + get() = this.shouldExtractAsStatic && parent is IrClass - private val IrDeclaration.isStaticOfFile: Boolean - get() = this.isStatic && parent is IrFile + private val IrDeclaration.shouldExtractAsStaticMemberOfFile: Boolean + get() = this.shouldExtractAsStatic && parent is IrFile - private val IrDeclaration.isStatic: Boolean - get() = this is IrSimpleFunction && dispatchReceiverParameter == null || + private fun isStaticAnnotatedNonCompanionMember(f: IrSimpleFunction) = + f.parentClassOrNull?.isNonCompanionObject == true && + (f.hasAnnotation(jvmStaticFqName) || f.correspondingPropertySymbol?.owner?.hasAnnotation(jvmStaticFqName) == true) + + private val IrDeclaration.shouldExtractAsStatic: Boolean + get() = this is IrSimpleFunction && (isStaticFunction(this) || isStaticAnnotatedNonCompanionMember(this)) || this is IrField && this.isStatic || this is IrEnumEntry @@ -1399,7 +1553,7 @@ open class KotlinFileExtractor( } } - fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction? + private fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction? val jvmIntrinsicsClass by lazy { val result = pluginContext.referenceClass(FqName("kotlin.jvm.internal.Intrinsics"))?.owner @@ -1407,7 +1561,7 @@ open class KotlinFileExtractor( result } - fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? { + private fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? { val result = jvmIntrinsicsClass?.let { findFunction(it, name) } if(result == null) { logger.errorElement("Couldn't find JVM intrinsic function $name", warnAgainstElement) @@ -1501,7 +1655,7 @@ open class KotlinFileExtractor( result } - fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean { + private fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean { val verbose = false fun verboseln(s: String) { if(verbose) println(s) } verboseln("Attempting match for $pkgName $classNameLogged $fName") @@ -1545,10 +1699,10 @@ open class KotlinFileExtractor( return true } - fun isFunction(target: IrFunction, pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) = + private fun isFunction(target: IrFunction, pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) = isFunction(target, pkgName, className, { it == className }, fName, hasQuestionMark) - fun isNumericFunction(target: IrFunction, fName: String): Boolean { + private fun isNumericFunction(target: IrFunction, fName: String): Boolean { return isFunction(target, "kotlin", "Int", fName) || isFunction(target, "kotlin", "Byte", fName) || isFunction(target, "kotlin", "Short", fName) || @@ -1557,7 +1711,7 @@ open class KotlinFileExtractor( isFunction(target, "kotlin", "Double", fName) } - fun isArrayType(typeName: String) = + private fun isArrayType(typeName: String) = when(typeName) { "Array" -> true "IntArray" -> true @@ -1571,7 +1725,7 @@ open class KotlinFileExtractor( else -> false } - fun extractCall(c: IrCall, callable: Label, stmtExprParent: StmtExprParent) { + private fun extractCall(c: IrCall, callable: Label, stmtExprParent: StmtExprParent) { with("call", c) { val target = tryReplaceSyntheticFunction(c.symbol.owner) @@ -1599,7 +1753,7 @@ open class KotlinFileExtractor( else listOf() - extractRawMethodAccess(syntacticCallTarget, c, callable, parent, idx, enclosingStmt, (0 until c.valueArgumentsCount).map { c.getValueArgument(it) }, c.dispatchReceiver, c.extensionReceiver, typeArgs, extractClassTypeArguments) + extractRawMethodAccess(syntacticCallTarget, c, callable, parent, idx, enclosingStmt, (0 until c.valueArgumentsCount).map { c.getValueArgument(it) }, c.dispatchReceiver, c.extensionReceiver, typeArgs, extractClassTypeArguments, c.superQualifierSymbol) } fun extractSpecialEnumFunction(fnName: String){ @@ -1979,7 +2133,13 @@ open class KotlinFileExtractor( } isFunction(target, "kotlin", "(some array type)", { isArrayType(it) }, "iterator") && c.origin == IrStatementOrigin.FOR_LOOP_ITERATOR -> { findTopLevelFunctionOrWarn("kotlin.jvm.internal.iterator", "kotlin.jvm.internal.ArrayIteratorKt", c)?.let { iteratorFn -> - extractRawMethodAccess(iteratorFn, c, callable, parent, idx, enclosingStmt, listOf(c.dispatchReceiver), null, null, listOf((c.dispatchReceiver!!.type as IrSimpleType).arguments.first().typeOrNull!!)) + val typeArgs = (c.dispatchReceiver!!.type as IrSimpleType).arguments.map { + when(it) { + is IrTypeProjection -> it.type + else -> pluginContext.irBuiltIns.anyNType + } + } + extractRawMethodAccess(iteratorFn, c, callable, parent, idx, enclosingStmt, listOf(c.dispatchReceiver), null, null, typeArgs) } } isFunction(target, "kotlin", "(some array type)", { isArrayType(it) }, "get") && c.origin == IrStatementOrigin.GET_ARRAY_ELEMENT -> { @@ -2250,7 +2410,7 @@ open class KotlinFileExtractor( else -> null } - fun getUpdateInPlaceRHS(origin: IrStatementOrigin?, isExpectedLhs: (IrExpression?) -> Boolean, updateRhs: IrExpression): IrExpression? { + private fun getUpdateInPlaceRHS(origin: IrStatementOrigin?, isExpectedLhs: (IrExpression?) -> Boolean, updateRhs: IrExpression): IrExpression? { // Check for a desugared in-place update operator, such as "v += e": return getStatementOriginOperator(origin)?.let { if (updateRhs is IrCall && @@ -2265,7 +2425,7 @@ open class KotlinFileExtractor( } } - fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label, type: TypeResults, exprParent: ExprParent): Boolean { + private fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label, type: TypeResults, exprParent: ExprParent): Boolean { when(origin) { IrStatementOrigin.PLUSEQ -> tw.writeExprs_assignaddexpr(id.cast(), type.javaResult.id, exprParent.parent, exprParent.idx) IrStatementOrigin.MINUSEQ -> tw.writeExprs_assignsubexpr(id.cast(), type.javaResult.id, exprParent.parent, exprParent.idx) @@ -2277,7 +2437,7 @@ open class KotlinFileExtractor( return true } - fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label, parent: StmtExprParent): Boolean { + private fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label, parent: StmtExprParent): Boolean { /* * We're expecting the pattern * { @@ -2348,7 +2508,7 @@ open class KotlinFileExtractor( return false } - fun extractExpressionStmt(e: IrExpression, callable: Label, parent: Label, idx: Int) { + private fun extractExpressionStmt(e: IrExpression, callable: Label, parent: Label, idx: Int) { extractExpression(e, callable, StmtParent(parent, idx)) } @@ -2356,7 +2516,7 @@ open class KotlinFileExtractor( extractExpression(e, callable, ExprParent(parent, idx, enclosingStmt)) } - fun extractExpression(e: IrExpression, callable: Label, parent: StmtExprParent) { + private fun extractExpression(e: IrExpression, callable: Label, parent: StmtExprParent) { with("expression", e) { when(e) { is IrDelegatingConstructorCall -> { @@ -2599,78 +2759,22 @@ open class KotlinFileExtractor( val exprParent = parent.expr(e, callable) val owner = e.symbol.owner if (owner is IrValueParameter && owner.index == -1 && !owner.isExtensionReceiver()) { - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_thisaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - tw.writeHasLocation(id, locId) - tw.writeCallableEnclosingExpr(id, callable) - tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt) - - - fun extractTypeAccess(parent: IrClass){ - extractTypeAccessRecursive(parent.typeWith(listOf()), locId, id, 0, callable, exprParent.enclosingStmt) - } - - when(val ownerParent = owner.parent) { - is IrFunction -> { - if (ownerParent.dispatchReceiverParameter == owner && - ownerParent.extensionReceiverParameter != null) { - - val ownerParent2 = ownerParent.parent - if (ownerParent2 is IrClass){ - extractTypeAccess(ownerParent2) - } else { - logger.errorElement("Unhandled qualifier for this", e) - } - } - } - is IrClass -> { - if (ownerParent.thisReceiver == owner) { - extractTypeAccess(ownerParent) - } - } - else -> { - logger.errorElement("Unexpected owner parent for this access: " + ownerParent.javaClass, e) - } - } + extractThisAccess(e, exprParent, callable) } else { - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - tw.writeHasLocation(id, locId) - tw.writeCallableEnclosingExpr(id, callable) - tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt) - - val vId = useValueDeclaration(owner) - if (vId != null) { - tw.writeVariableBinding(id, vId) - } + extractVariableAccess(useValueDeclaration(owner), e.type, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt) } } is IrGetField -> { val exprParent = parent.expr(e, callable) - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - tw.writeHasLocation(id, locId) - tw.writeCallableEnclosingExpr(id, callable) - tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt) val owner = tryReplaceAndroidSyntheticField(e.symbol.owner) - val vId = useField(owner) - tw.writeVariableBinding(id, vId) - tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt) - - val receiver = e.receiver - if (receiver != null) { - extractExpressionExpr(receiver, callable, id, -1, exprParent.enclosingStmt) - } else if (owner.isStatic) { - extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt) + val locId = tw.getLocation(e) + extractVariableAccess(useField(owner), e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt).also { id -> + val receiver = e.receiver + if (receiver != null) { + extractExpressionExpr(receiver, callable, id, -1, exprParent.enclosingStmt) + } else if (owner.isStatic) { + extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt) + } } } is IrGetEnumValue -> { @@ -2971,6 +3075,82 @@ open class KotlinFileExtractor( } } + private fun extractSuperAccess(irType: IrType, callable: Label, parent: Label, idx: Int, enclosingStmt: Label, locId: Label) = + tw.getFreshIdLabel().also { + val type = useType(irType) + tw.writeExprs_superaccess(it, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(it, type.kotlinResult.id) + tw.writeHasLocation(it, locId) + tw.writeCallableEnclosingExpr(it, callable) + tw.writeStatementEnclosingExpr(it, enclosingStmt) + extractTypeAccessRecursive(irType, locId, it, 0) + } + + private fun extractThisAccess(e: IrGetValue, exprParent: ExprParent, callable: Label) { + val containingDeclaration = declarationStack.peek() + val locId = tw.getLocation(e) + val type = useType(e.type) + + if (containingDeclaration.shouldExtractAsStatic && containingDeclaration.parentClassOrNull?.isNonCompanionObject == true) { + // Use of `this` in a non-companion object member that will be lowered to a static function -- replace with a reference + // to the corresponding static object instance. + val instanceField = useObjectClassInstance(containingDeclaration.parentAsClass) + extractVariableAccess(instanceField.id, e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt).also { varAccessId -> + extractStaticTypeAccessQualifier(containingDeclaration, varAccessId, locId, callable, exprParent.enclosingStmt) + } + } else { + val id = tw.getFreshIdLabel() + + tw.writeExprs_thisaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx) + tw.writeExprsKotlinType(id, type.kotlinResult.id) + tw.writeHasLocation(id, locId) + tw.writeCallableEnclosingExpr(id, callable) + tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt) + + fun extractTypeAccess(parent: IrClass) { + extractTypeAccessRecursive(parent.typeWith(listOf()), locId, id, 0, callable, exprParent.enclosingStmt) + } + + val owner = e.symbol.owner + when(val ownerParent = owner.parent) { + is IrFunction -> { + if (ownerParent.dispatchReceiverParameter == owner && + ownerParent.extensionReceiverParameter != null) { + + val ownerParent2 = ownerParent.parent + if (ownerParent2 is IrClass){ + extractTypeAccess(ownerParent2) + } else { + logger.errorElement("Unhandled qualifier for this", e) + } + } + } + is IrClass -> { + if (ownerParent.thisReceiver == owner) { + extractTypeAccess(ownerParent) + } + } + else -> { + logger.errorElement("Unexpected owner parent for this access: " + ownerParent.javaClass, e) + } + } + } + } + + private fun extractVariableAccess(variable: Label?, irType: IrType, locId: Label, parent: Label, idx: Int, callable: Label, enclosingStmt: Label) = + tw.getFreshIdLabel().also { + val type = useType(irType) + tw.writeExprs_varaccess(it, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(it, type.kotlinResult.id) + tw.writeHasLocation(it, locId) + tw.writeCallableEnclosingExpr(it, callable) + tw.writeStatementEnclosingExpr(it, enclosingStmt) + + if (variable != null) { + tw.writeVariableBinding(it, variable) + } + } + private fun extractLoop( loop: IrLoop, stmtExprParent: StmtExprParent, @@ -3819,7 +3999,7 @@ open class KotlinFileExtractor( } } - fun extractVarargElement(e: IrVarargElement, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { + private fun extractVarargElement(e: IrVarargElement, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { with("vararg element", e) { val argExpr = when(e) { is IrExpression -> e @@ -3860,7 +4040,7 @@ open class KotlinFileExtractor( /** * Extracts a single wildcard type access expression with no enclosing callable and statement. */ - private fun extractWildcardTypeAccess(type: TypeResults, location: Label, parent: Label, idx: Int): Label { + private fun extractWildcardTypeAccess(type: TypeResults, location: Label, parent: Label, idx: Int): Label { val id = tw.getFreshIdLabel() tw.writeExprs_wildcardtypeaccess(id, type.javaResult.id, parent, idx) tw.writeExprsKotlinType(id, type.kotlinResult.id) @@ -3871,7 +4051,7 @@ 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): Label { // TODO: elementForLocation allows us to give some sort of // location, but a proper location for the type access will // require upstream changes @@ -3897,7 +4077,7 @@ open class KotlinFileExtractor( * `extractTypeAccessRecursive` if the argument is invariant. * No enclosing callable and statement is extracted, this is useful for type access extraction in field declarations. */ - private fun extractWildcardTypeAccessRecursive(t: IrTypeArgument, location: Label, parent: Label, idx: Int) { + private fun extractWildcardTypeAccessRecursive(t: IrTypeArgument, location: Label, parent: Label, idx: Int) { val typeLabels by lazy { TypeResults(getTypeArgumentLabel(t), TypeResult(fakeKotlinType(), "TODO", "TODO")) } when (t) { is IrStarProjection -> extractWildcardTypeAccess(typeLabels, location, parent, idx) @@ -3917,7 +4097,7 @@ 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. * No enclosing callable and statement is extracted, this is useful for type access extraction in field declarations. */ - private fun extractTypeAccessRecursive(t: IrType, location: Label, parent: Label, idx: Int, typeContext: TypeContext = TypeContext.OTHER): Label { + private fun extractTypeAccessRecursive(t: IrType, location: Label, parent: Label, idx: Int, typeContext: TypeContext = TypeContext.OTHER): Label { val typeAccessId = extractTypeAccess(useType(t, typeContext), location, parent, idx) if (t is IrSimpleType) { t.arguments.forEachIndexed { argIdx, arg -> @@ -4011,7 +4191,7 @@ open class KotlinFileExtractor( return initId } - fun extractTypeOperatorCall(e: IrTypeOperatorCall, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { + private fun extractTypeOperatorCall(e: IrTypeOperatorCall, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { with("type operator call", e) { when(e.operator) { IrTypeOperator.CAST -> { @@ -4383,6 +4563,9 @@ open class KotlinFileExtractor( GENERATED_DATA_CLASS_MEMBER(2), DEFAULT_PROPERTY_ACCESSOR(3), CLASS_INITIALISATION_METHOD(4), - ENUM_CLASS_SPECIAL_MEMBER(5) + ENUM_CLASS_SPECIAL_MEMBER(5), + DELEGATED_PROPERTY_GETTER(6), + DELEGATED_PROPERTY_SETTER(7), + JVMSTATIC_PROXY_METHOD(8), } } diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index 0e2202b583a..69ddc410799 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.lower.parents import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor import org.jetbrains.kotlin.builtins.StandardNames +import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* @@ -23,8 +24,10 @@ import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.sources.JavaSourceElement import org.jetbrains.kotlin.load.java.structure.* +import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.NameUtils import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.util.OperatorNameConventions @@ -49,7 +52,7 @@ open class KotlinUsesExtractor( javaLangObject?.typeWith() } - fun usePackage(pkg: String): Label { + private fun usePackage(pkg: String): Label { return extractPackage(pkg) } @@ -108,14 +111,26 @@ open class KotlinUsesExtractor( } data class TypeResults(val javaResult: TypeResult, val kotlinResult: TypeResult) - fun useType(t: IrType, context: TypeContext = TypeContext.OTHER) = + fun useType(t: IrType, context: TypeContext = TypeContext.OTHER): TypeResults { when(t) { - is IrSimpleType -> useSimpleType(t, context) + is IrSimpleType -> return useSimpleType(t, context) else -> { logger.error("Unrecognised IrType: " + t.javaClass) - TypeResults(TypeResult(fakeLabel(), "unknown", "unknown"), TypeResult(fakeLabel(), "unknown", "unknown")) + return extractErrorType() } } + } + + private fun extractErrorType(): TypeResults { + val typeId = tw.getLabelFor("@\"errorType\"") { + tw.writeError_type(it) + } + val kotlinTypeId = tw.getLabelFor("@\"errorKotlinType\"") { + tw.writeKt_nullable_types(it, typeId) + } + return TypeResults(TypeResult(typeId, null, ""), + TypeResult(kotlinTypeId, null, "")) + } fun getJavaEquivalentClass(c: IrClass) = getJavaEquivalentClassId(c)?.let { pluginContext.referenceClass(it.asSingleFqName()) }?.owner @@ -154,12 +169,12 @@ open class KotlinUsesExtractor( } ?: argsIncludingOuterClasses } - fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner + private fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner // Gets nested inner classes starting at `c` and proceeding outwards to the innermost enclosing static class. // For example, for (java syntax) `class A { static class B { class C { class D { } } } }`, // `nonStaticParentsWithSelf(D)` = `[D, C, B]`. - fun parentsWithTypeParametersInScope(c: IrClass): List { + private fun parentsWithTypeParametersInScope(c: IrClass): List { val parentsList = c.parentsWithSelf.toList() val firstOuterClassIdx = parentsList.indexOfFirst { it is IrClass && isStaticClass(it) } return if (firstOuterClassIdx == -1) parentsList else parentsList.subList(0, firstOuterClassIdx + 1) @@ -168,14 +183,14 @@ open class KotlinUsesExtractor( // Gets the type parameter symbols that are in scope for class `c` in Kotlin order (i.e. for // `class NotInScope { static class OutermostInScope { class QueryClass { } } }`, // `getTypeParametersInScope(QueryClass)` = `[C, D, A, B]`. - fun getTypeParametersInScope(c: IrClass) = + private fun getTypeParametersInScope(c: IrClass) = parentsWithTypeParametersInScope(c).mapNotNull({ getTypeParameters(it) }).flatten() // Returns a map from `c`'s type variables in scope to type arguments `argsIncludingOuterClasses`. // Hack for the time being: the substituted types are always nullable, to prevent downstream code // from replacing a generic parameter by a primitive. As and when we extract Kotlin types we will // need to track this information in more detail. - fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List) = + private fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List) = getTypeParametersInScope(c).map({ it.symbol }).zip(argsIncludingOuterClasses.map { it.withQuestionMark(true) }).toMap() fun makeGenericSubstitutionFunction(c: IrClass, argsIncludingOuterClasses: List) = @@ -239,13 +254,13 @@ open class KotlinUsesExtractor( private fun isArray(t: IrSimpleType) = t.isBoxedArray || t.isPrimitiveArray() - fun extractClassLaterIfExternal(c: IrClass) { + private fun extractClassLaterIfExternal(c: IrClass) { if (isExternalDeclaration(c)) { extractExternalClassLater(c) } } - fun extractExternalEnclosingClassLater(d: IrDeclaration) { + private fun extractExternalEnclosingClassLater(d: IrDeclaration) { when (val parent = d.parent) { is IrClass -> extractExternalClassLater(parent) is IrFunction -> extractExternalEnclosingClassLater(parent) @@ -254,7 +269,7 @@ open class KotlinUsesExtractor( } } - fun extractPropertyLaterIfExternalFileMember(p: IrProperty) { + private fun extractPropertyLaterIfExternalFileMember(p: IrProperty) { if (isExternalFileClassMember(p)) { extractExternalClassLater(p.parentAsClass) dependencyCollector?.addDependency(p, externalClassExtractor.propertySignature) @@ -262,7 +277,7 @@ open class KotlinUsesExtractor( } } - fun extractFieldLaterIfExternalFileMember(f: IrField) { + private fun extractFieldLaterIfExternalFileMember(f: IrField) { if (isExternalFileClassMember(f)) { extractExternalClassLater(f.parentAsClass) dependencyCollector?.addDependency(f, externalClassExtractor.fieldSignature) @@ -270,7 +285,7 @@ open class KotlinUsesExtractor( } } - fun extractFunctionLaterIfExternalFileMember(f: IrFunction) { + private fun extractFunctionLaterIfExternalFileMember(f: IrFunction) { if (isExternalFileClassMember(f)) { extractExternalClassLater(f.parentAsClass) (f as? IrSimpleFunction)?.correspondingPropertySymbol?.let { @@ -301,7 +316,7 @@ open class KotlinUsesExtractor( externalClassExtractor.extractLater(c) } - fun tryReplaceAndroidSyntheticClass(c: IrClass): IrClass { + private fun tryReplaceAndroidSyntheticClass(c: IrClass): IrClass { // The Android Kotlin Extensions Gradle plugin introduces synthetic functions, fields and classes. The most // obvious signature is that they lack any supertype information even though they are not root classes. // If possible, replace them by a real version of the same class. @@ -503,7 +518,7 @@ open class KotlinUsesExtractor( // but returns boxed arrays with a nullable, invariant component type, with any nested arrays // similarly transformed. For example, Array> would become Array?> // Array<*> will become Array. - fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType = + private fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType = if (arrayType.isPrimitiveArray()) arrayType else { @@ -528,7 +543,7 @@ open class KotlinUsesExtractor( ) } - fun useArrayType(arrayType: IrSimpleType, componentType: IrType, elementType: IrType, dimensions: Int, isPrimitiveArray: Boolean): TypeResults { + private fun useArrayType(arrayType: IrSimpleType, componentType: IrType, elementType: IrType, dimensions: Int, isPrimitiveArray: Boolean): TypeResults { // Ensure we extract Array as Integer[], not int[], for example: fun nullableIfNotPrimitive(type: IrType) = if (type.isPrimitiveType() && !isPrimitiveArray) type.makeNullable() else type @@ -579,7 +594,7 @@ open class KotlinUsesExtractor( RETURN, GENERIC_ARGUMENT, OTHER } - fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults { + private fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults { if (s.abbreviation != null) { // TODO: Extract this information } @@ -754,11 +769,25 @@ open class KotlinUsesExtractor( data class FunctionNames(val nameInDB: String, val kotlinName: String) + @OptIn(ObsoleteDescriptorBasedAPI::class) + private fun getJvmModuleName(f: IrFunction) = + NameUtils.sanitizeAsJavaIdentifier( + getJvmModuleNameForDeserializedDescriptor(f.descriptor) ?: JvmCodegenUtil.getModuleName(pluginContext.moduleDescriptor) + ) + fun getFunctionShortName(f: IrFunction) : FunctionNames { if (f.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA || f.isAnonymousFunction) return FunctionNames( OperatorNameConventions.INVOKE.asString(), OperatorNameConventions.INVOKE.asString()) + + fun getSuffixIfInternal() = + if (f.visibility == DescriptorVisibilities.INTERNAL) { + "\$" + getJvmModuleName(f) + } else { + "" + } + (f as? IrSimpleFunction)?.correspondingPropertySymbol?.let { val propName = it.owner.name.asString() val getter = it.owner.getter @@ -774,35 +803,26 @@ open class KotlinUsesExtractor( } } - when (f) { - getter -> { - val defaultFunctionName = JvmAbi.getterName(propName) - val defaultDbName = if (getter.visibility == DescriptorVisibilities.PRIVATE && getter.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) { - // In JVM these functions don't exist, instead the backing field is accessed directly - defaultFunctionName + "\$private" - } else { - defaultFunctionName - } - return FunctionNames(getJvmName(getter) ?: defaultDbName, defaultFunctionName) - } - setter -> { - val defaultFunctionName = JvmAbi.setterName(propName) - val defaultDbName = if (setter.visibility == DescriptorVisibilities.PRIVATE && setter.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) { - // In JVM these functions don't exist, instead the backing field is accessed directly - defaultFunctionName + "\$private" - } else { - defaultFunctionName - } - return FunctionNames(getJvmName(setter) ?: defaultDbName, defaultFunctionName) - } + val maybeFunctionName = when (f) { + getter -> JvmAbi.getterName(propName) + setter -> JvmAbi.setterName(propName) else -> { logger.error( "Function has a corresponding property, but is neither the getter nor the setter" ) + null } } + maybeFunctionName?.let { defaultFunctionName -> + val suffix = if (f.visibility == DescriptorVisibilities.PRIVATE && f.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) { + "\$private" + } else { + getSuffixIfInternal() + } + return FunctionNames(getJvmName(f) ?: "$defaultFunctionName$suffix", defaultFunctionName) + } } - return FunctionNames(getJvmName(f) ?: f.name.asString(), f.name.asString()) + return FunctionNames(getJvmName(f) ?: "${f.name.asString()}${getSuffixIfInternal()}", f.name.asString()) } // This excludes class type parameters that show up in (at least) constructors' typeParameters list. @@ -810,14 +830,14 @@ open class KotlinUsesExtractor( return if (f is IrConstructor) f.typeParameters else f.typeParameters.filter { it.parent == f } } - fun getTypeParameters(dp: IrDeclarationParent): List = + private fun getTypeParameters(dp: IrDeclarationParent): List = when(dp) { is IrClass -> dp.typeParameters is IrFunction -> getFunctionTypeParameters(dp) else -> listOf() } - fun getEnclosingClass(it: IrDeclarationParent): IrClass? = + private fun getEnclosingClass(it: IrDeclarationParent): IrClass? = when(it) { is IrClass -> it is IrFunction -> getEnclosingClass(it.parent) @@ -924,7 +944,7 @@ open class KotlinUsesExtractor( null } ?: t - fun getJavaTypeArgument(jt: JavaType, idx: Int) = + private fun getJavaTypeArgument(jt: JavaType, idx: Int) = when(jt) { is JavaClassifierType -> jt.typeArguments.getOrNull(idx) is JavaArrayType -> if (idx == 0) jt.componentType else null @@ -1153,7 +1173,7 @@ open class KotlinUsesExtractor( "kotlin.Boolean", "kotlin.Byte", "kotlin.Char", "kotlin.Double", "kotlin.Float", "kotlin.Int", "kotlin.Long", "kotlin.Number", "kotlin.Short" ) - fun kotlinFunctionToJavaEquivalent(f: IrFunction, noReplace: Boolean) = + private fun kotlinFunctionToJavaEquivalent(f: IrFunction, noReplace: Boolean) = if (noReplace) f else @@ -1346,14 +1366,14 @@ open class KotlinUsesExtractor( return "@\"typevar;{$parentLabel};${param.name}\"" } - fun useTypeParameter(param: IrTypeParameter) = + private fun useTypeParameter(param: IrTypeParameter) = TypeResult( tw.getLabelFor(getTypeParameterLabel(param)), useType(eraseTypeParameter(param)).javaResult.signature, param.name.asString() ) - fun extractModifier(m: String): Label { + private fun extractModifier(m: String): Label { val modifierLabel = "@\"modifier;$m\"" val id: Label = tw.getLabelFor(modifierLabel, { tw.writeModifiers(it, m) @@ -1435,7 +1455,7 @@ open class KotlinUsesExtractor( * Note that `Array` is retained (with `T` itself erased) because these are expected to be lowered to Java * arrays, which are not generic. */ - fun erase (t: IrType): IrType { + private fun erase (t: IrType): IrType { if (t is IrSimpleType) { val classifier = t.classifier val owner = classifier.owner @@ -1488,7 +1508,7 @@ open class KotlinUsesExtractor( fun useValueParameter(vp: IrValueParameter, parent: Label?): Label = tw.getLabelFor(getValueParameterLabel(vp, parent)) - fun isDirectlyExposedCompanionObjectField(f: IrField) = + private fun isDirectlyExposedCompanionObjectField(f: IrField) = f.hasAnnotation(FqName("kotlin.jvm.JvmField")) || f.correspondingPropertySymbol?.owner?.let { it.isConst || it.isLateinit @@ -1514,7 +1534,7 @@ open class KotlinUsesExtractor( // otherwise two extension properties declared in the same enclosing context will get // clashing trap labels. These are always private, so we can just make up a label without // worrying about their names as seen from Java. - val extensionPropertyDiscriminator = getExtensionReceiverType(f)?.let { "extension;${useType(it)}" } ?: "" + val extensionPropertyDiscriminator = getExtensionReceiverType(f)?.let { "extension;${useType(it).javaResult.id}" } ?: "" return "@\"field;{$parentId};${extensionPropertyDiscriminator}${f.name.asString()}\"" } diff --git a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt index 93d3c0534de..03f032f8810 100644 --- a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt @@ -16,7 +16,8 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private val file: IrFile, private val fileLabel: Label) { private val tw = fileExtractor.tw private val logger = fileExtractor.logger - private val ktFile = Psi2Ir().getKtFile(file) + private val psi2Ir = Psi2Ir(logger) + private val ktFile = psi2Ir.getKtFile(file) fun extract() { if (ktFile == null) { @@ -85,7 +86,7 @@ class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private v val ownerPsi = getKDocOwner(comment) ?: return val owners = mutableListOf() - file.accept(IrVisitorLookup(ownerPsi, file), owners) + file.accept(IrVisitorLookup(psi2Ir, ownerPsi, file), owners) for (ownerIr in owners) { val ownerLabel = diff --git a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt index 6f3954cfc34..15ca35a1438 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt @@ -68,7 +68,7 @@ fun getIrClassVirtualFile(irClass: IrClass): VirtualFile? { return null } -fun getRawIrClassBinaryPath(irClass: IrClass) = +private fun getRawIrClassBinaryPath(irClass: IrClass) = getIrClassVirtualFile(irClass)?.let { val path = it.path if(it.fileSystem.protocol == StandardFileSystems.JRT_PROTOCOL) @@ -92,4 +92,4 @@ fun getContainingClassOrSelf(decl: IrDeclaration): IrClass? { } fun getJavaEquivalentClassId(c: IrClass) = - c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) } \ No newline at end of file + c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) } diff --git a/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt b/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt index 0020d00fac4..a25c1a4534f 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt @@ -8,7 +8,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.util.isFakeOverride import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) : +class IrVisitorLookup(private val psi2Ir: Psi2Ir, private val psi: PsiElement, private val file: IrFile) : IrElementVisitor> { private val location = psi.getLocation() @@ -27,7 +27,7 @@ class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) : } if (location.contains(elementLocation)) { - val psiElement = Psi2Ir().findPsiElement(element, file) + val psiElement = psi2Ir.findPsiElement(element, file) if (psiElement == psi) { // There can be multiple IrElements that match the same PSI element. data.add(element) @@ -35,4 +35,4 @@ class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) : } element.acceptChildren(this, data) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt b/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt index dce49790e0e..76d155f8b22 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt @@ -51,11 +51,13 @@ private val specialFunctions = mapOf( makeDescription(FqName("java.lang.Number"), "toFloat") to "floatValue", makeDescription(StandardNames.FqNames.number.toSafe(), "toDouble") to "doubleValue", makeDescription(FqName("java.lang.Number"), "toDouble") to "doubleValue", + makeDescription(StandardNames.FqNames.string.toSafe(), "get") to "charAt", + makeDescription(FqName("java.lang.String"), "get") to "charAt", ) private val specialFunctionShortNames = specialFunctions.keys.map { it.functionName }.toSet() -fun getSpecialJvmName(f: IrFunction): String? { +private fun getSpecialJvmName(f: IrFunction): String? { if (specialFunctionShortNames.contains(f.name) && f is IrSimpleFunction) { f.allOverridden(true).forEach { overriddenFunc -> overriddenFunc.parentClassOrNull?.fqNameWhenAvailable?.let { parentFqName -> @@ -87,4 +89,4 @@ fun getJvmName(container: IrAnnotationContainer): String? { } } return (container as? IrFunction)?.let { getSpecialJvmName(container) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt b/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt index b249bb0091a..694b3dff289 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt @@ -37,7 +37,7 @@ fun IrType.substituteTypeArguments(params: List, arguments: Lis else -> this } -fun IrSimpleType.substituteTypeArguments(substitutionMap: Map): IrSimpleType { +private fun IrSimpleType.substituteTypeArguments(substitutionMap: Map): IrSimpleType { if (substitutionMap.isEmpty()) return this val newArguments = arguments.map { @@ -100,7 +100,7 @@ private fun subProjectedType(substitutionMap: Map context.irBuiltIns.anyNType is IrTypeProjection -> when(this.variance) { @@ -111,7 +111,7 @@ fun IrTypeArgument.upperBound(context: IrPluginContext) = else -> context.irBuiltIns.anyNType } -fun IrTypeArgument.lowerBound(context: IrPluginContext) = +private fun IrTypeArgument.lowerBound(context: IrPluginContext) = when(this) { is IrStarProjection -> context.irBuiltIns.nothingType is IrTypeProjection -> when(this.variance) { @@ -200,7 +200,7 @@ fun IrTypeArgument.withQuestionMark(b: Boolean): IrTypeArgument = typealias TypeSubstitution = (IrType, KotlinUsesExtractor.TypeContext, IrPluginContext) -> IrType -fun matchingTypeParameters(l: IrTypeParameter?, r: IrTypeParameter): Boolean { +private fun matchingTypeParameters(l: IrTypeParameter?, r: IrTypeParameter): Boolean { if (l === r) return true if (l == null) 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 16ee288d05a..fce55c87cd6 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,21 +1,19 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi2ir.PsiSourceManager - -class Psi2Ir : Psi2IrFacade { - companion object { - val psiManager = PsiSourceManager() - } +class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { - return psiManager.getKtFile(irFile) + logger.warn("Comment extraction is not supported for Kotlin < 1.5.20") + return null } override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { - return psiManager.findPsiElement(irElement, irFile) + logger.error("Attempted comment extraction for Kotlin < 1.5.20") + return null } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt index 16ee288d05a..fce55c87cd6 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt @@ -1,21 +1,19 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi2ir.PsiSourceManager - -class Psi2Ir : Psi2IrFacade { - companion object { - val psiManager = PsiSourceManager() - } +class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { - return psiManager.getKtFile(irFile) + logger.warn("Comment extraction is not supported for Kotlin < 1.5.20") + return null } override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { - return psiManager.findPsiElement(irElement, irFile) + logger.error("Attempted comment extraction for Kotlin < 1.5.20") + return null } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt index 16ee288d05a..fce55c87cd6 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt @@ -1,21 +1,19 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi2ir.PsiSourceManager - -class Psi2Ir : Psi2IrFacade { - companion object { - val psiManager = PsiSourceManager() - } +class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { - return psiManager.getKtFile(irFile) + logger.warn("Comment extraction is not supported for Kotlin < 1.5.20") + return null } override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { - return psiManager.findPsiElement(irElement, irFile) + logger.error("Attempted comment extraction for Kotlin < 1.5.20") + return null } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_21/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_21/Psi2Ir.kt index 256a8b3bb63..8e21191f2a0 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_21/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_21/Psi2Ir.kt @@ -1,5 +1,6 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -class Psi2Ir: Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } @@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return PsiSourceManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_31/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_31/Psi2Ir.kt index 256a8b3bb63..8e21191f2a0 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_31/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_31/Psi2Ir.kt @@ -1,5 +1,6 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -class Psi2Ir: Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } @@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return PsiSourceManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_10/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_10/Psi2Ir.kt index 256a8b3bb63..8e21191f2a0 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_10/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_10/Psi2Ir.kt @@ -1,5 +1,6 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -class Psi2Ir: Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } @@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return PsiSourceManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_20/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_20/Psi2Ir.kt index 256a8b3bb63..8e21191f2a0 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_20/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_20/Psi2Ir.kt @@ -1,5 +1,6 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -class Psi2Ir: Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } @@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return PsiSourceManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt index 256a8b3bb63..8e21191f2a0 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt @@ -1,5 +1,6 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -class Psi2Ir: Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } @@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return PsiSourceManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/ql/consistency-queries/typeParametersInScope.ql b/java/ql/consistency-queries/typeParametersInScope.ql index f78bf2d42a4..2f1fd651278 100644 --- a/java/ql/consistency-queries/typeParametersInScope.ql +++ b/java/ql/consistency-queries/typeParametersInScope.ql @@ -12,6 +12,8 @@ Type getAMentionedType(RefType type) { result = getAMentionedType(type).(InstantiatedType).getATypeArgument() or result = getAMentionedType(type).(NestedType).getEnclosingType() + or + result = getAMentionedType(type).(Wildcard).getATypeBound().getType() } Type getATypeUsedInClass(RefType type) { diff --git a/java/ql/consistency-queries/visibility.ql b/java/ql/consistency-queries/visibility.ql index ba90d598236..1b6744cea1d 100644 --- a/java/ql/consistency-queries/visibility.ql +++ b/java/ql/consistency-queries/visibility.ql @@ -18,5 +18,6 @@ where m.getFile().isKotlinSourceFile() and // TODO: This ought to have visibility information not m.getName() = "" and - count(visibility(m)) != 1 + count(visibility(m)) != 1 and + not (count(visibility(m)) = 2 and visibility(m) = "public" and visibility(m) = "internal") // This is a reasonable result, since the JVM symbol is declared public, but Kotlin metadata flags it as internal select m, concat(visibility(m), ", ") 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 a4d9d37a8e2..51186ef7b15 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 @@ -48,7 +48,7 @@ c.kt: d.kt: # 0| [CompilationUnit] d # 1| 1: [Class] D -# 0| 1: [FieldDeclaration] String bar; +# 0| 2: [FieldDeclaration] String bar; # 0| -1: [TypeAccess] String # 0| 0: [StringLiteral] Foobar # 1| 3: [Constructor] D @@ -67,7 +67,7 @@ e.kt: # 0| -3: [TypeAccess] ArrayList # 0| 0: [IntegerLiteral] 1 # 0| 0: [NullLiteral] null -# 0| 1: [Method] +# 0| 2: [Method] # 0| 3: [TypeAccess] Object # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... diff --git a/java/ql/integration-tests/posix-only/kotlin/gradle_kotlinx_serialization/PrintAst.expected b/java/ql/integration-tests/posix-only/kotlin/gradle_kotlinx_serialization/PrintAst.expected index f5a92b6fd3d..e37e65dc3c8 100644 --- a/java/ql/integration-tests/posix-only/kotlin/gradle_kotlinx_serialization/PrintAst.expected +++ b/java/ql/integration-tests/posix-only/kotlin/gradle_kotlinx_serialization/PrintAst.expected @@ -40,43 +40,19 @@ app/src/main/kotlin/testProject/App.kt: # 7| -1: [ThisAccess] Project.this # 7| 0: [TypeAccess] Project # 7| 1: [VarAccess] language -# 0| 1: [Method] write$Self -# 0| 3: [TypeAccess] Unit -#-----| 4: (Parameters) -# 0| 0: [Parameter] self -# 0| 0: [TypeAccess] Project -# 0| 1: [Parameter] output -# 0| 0: [TypeAccess] CompositeEncoder -# 0| 2: [Parameter] serialDesc -# 0| 0: [TypeAccess] SerialDescriptor -# 7| 5: [BlockStmt] { ... } -# 7| 0: [ExprStmt] ; -# 7| 0: [MethodAccess] encodeStringElement(...) -# 7| -1: [VarAccess] output -# 7| 0: [VarAccess] serialDesc -# 7| 1: [IntegerLiteral] 0 -# 7| 2: [MethodAccess] getName(...) -# 7| -1: [VarAccess] self -# 7| 1: [ExprStmt] ; -# 7| 0: [MethodAccess] encodeIntElement(...) -# 7| -1: [VarAccess] output -# 7| 0: [VarAccess] serialDesc -# 7| 1: [IntegerLiteral] 1 -# 7| 2: [MethodAccess] getLanguage(...) -# 7| -1: [VarAccess] self -# 0| 1: [Method] component1 +# 0| 2: [Method] component1 # 0| 3: [TypeAccess] String # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... # 0| 0: [VarAccess] this.name # 0| -1: [ThisAccess] this -# 0| 1: [Method] component2 +# 0| 3: [Method] component2 # 0| 3: [TypeAccess] int # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... # 0| 0: [VarAccess] this.language # 0| -1: [ThisAccess] this -# 0| 1: [Method] copy +# 0| 4: [Method] copy # 0| 3: [TypeAccess] Project #-----| 4: (Parameters) # 8| 0: [Parameter] name @@ -89,41 +65,7 @@ app/src/main/kotlin/testProject/App.kt: # 0| -3: [TypeAccess] Project # 0| 0: [VarAccess] name # 0| 1: [VarAccess] language -# 0| 1: [Method] toString -# 0| 3: [TypeAccess] String -# 0| 5: [BlockStmt] { ... } -# 0| 0: [ReturnStmt] return ... -# 0| 0: [StringTemplateExpr] "..." -# 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| 5: [VarAccess] this.language -# 0| -1: [ThisAccess] this -# 0| 6: [StringLiteral] ) -# 0| 1: [Method] hashCode -# 0| 3: [TypeAccess] int -# 0| 5: [BlockStmt] { ... } -# 0| 0: [LocalVariableDeclStmt] var ...; -# 0| 1: [LocalVariableDeclExpr] result -# 0| 0: [MethodAccess] hashCode(...) -# 0| -1: [VarAccess] this.name -# 0| -1: [ThisAccess] this -# 0| 1: [ExprStmt] ; -# 0| 0: [AssignExpr] ...=... -# 0| 0: [VarAccess] result -# 0| 1: [MethodAccess] plus(...) -# 0| -1: [MethodAccess] times(...) -# 0| -1: [VarAccess] result -# 0| 0: [IntegerLiteral] 31 -# 0| 0: [MethodAccess] hashCode(...) -# 0| -1: [VarAccess] this.language -# 0| -1: [ThisAccess] this -# 0| 2: [ReturnStmt] return ... -# 0| 0: [VarAccess] result -# 0| 1: [Method] equals +# 0| 5: [Method] equals # 0| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 0| 0: [Parameter] other @@ -172,27 +114,68 @@ app/src/main/kotlin/testProject/App.kt: # 0| 0: [BooleanLiteral] false # 0| 5: [ReturnStmt] return ... # 0| 0: [BooleanLiteral] true -# 7| 9: [Class] Companion -# 0| 1: [Method] serializer -# 0| 3: [TypeAccess] KSerializer -# 0| 0: [TypeAccess] Project -# 7| 5: [BlockStmt] { ... } -# 7| 0: [ReturnStmt] return ... -# 7| 0: [VarAccess] INSTANCE -# 7| 2: [Constructor] Companion -# 7| 5: [BlockStmt] { ... } -# 7| 0: [SuperConstructorInvocationStmt] super(...) -# 7| 1: [BlockStmt] { ... } -# 7| 9: [Class] $serializer -# 0| 1: [Method] getDescriptor -# 0| 3: [TypeAccess] SerialDescriptor -# 0| 5: [BlockStmt] { ... } -# 0| 0: [ReturnStmt] return ... -# 0| 0: [VarAccess] this.descriptor +# 0| 6: [Method] hashCode +# 0| 3: [TypeAccess] int +# 0| 5: [BlockStmt] { ... } +# 0| 0: [LocalVariableDeclStmt] var ...; +# 0| 1: [LocalVariableDeclExpr] result +# 0| 0: [MethodAccess] hashCode(...) +# 0| -1: [VarAccess] this.name +# 0| -1: [ThisAccess] this +# 0| 1: [ExprStmt] ; +# 0| 0: [AssignExpr] ...=... +# 0| 0: [VarAccess] result +# 0| 1: [MethodAccess] plus(...) +# 0| -1: [MethodAccess] times(...) +# 0| -1: [VarAccess] result +# 0| 0: [IntegerLiteral] 31 +# 0| 0: [MethodAccess] hashCode(...) +# 0| -1: [VarAccess] this.language +# 0| -1: [ThisAccess] this +# 0| 2: [ReturnStmt] return ... +# 0| 0: [VarAccess] result +# 0| 7: [Method] toString +# 0| 3: [TypeAccess] String +# 0| 5: [BlockStmt] { ... } +# 0| 0: [ReturnStmt] return ... +# 0| 0: [StringTemplateExpr] "..." +# 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| 5: [VarAccess] this.language +# 0| -1: [ThisAccess] this +# 0| 6: [StringLiteral] ) +# 0| 8: [Method] write$Self +# 0| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 0| 0: [Parameter] self +# 0| 0: [TypeAccess] Project +# 0| 1: [Parameter] output +# 0| 0: [TypeAccess] CompositeEncoder +# 0| 2: [Parameter] serialDesc +# 0| 0: [TypeAccess] SerialDescriptor +# 7| 5: [BlockStmt] { ... } +# 7| 0: [ExprStmt] ; +# 7| 0: [MethodAccess] encodeStringElement(...) +# 7| -1: [VarAccess] output +# 7| 0: [VarAccess] serialDesc +# 7| 1: [IntegerLiteral] 0 +# 7| 2: [MethodAccess] getName(...) +# 7| -1: [VarAccess] self +# 7| 1: [ExprStmt] ; +# 7| 0: [MethodAccess] encodeIntElement(...) +# 7| -1: [VarAccess] output +# 7| 0: [VarAccess] serialDesc +# 7| 1: [IntegerLiteral] 1 +# 7| 2: [MethodAccess] getLanguage(...) +# 7| -1: [VarAccess] self +# 7| 9: [Class] $serializer # 0| 1: [FieldDeclaration] SerialDescriptor descriptor; # 0| -1: [TypeAccess] SerialDescriptor -# 0| 1: [Method] childSerializers +# 0| 2: [Method] childSerializers # 0| 3: [TypeAccess] KSerializer[] # 0| 0: [TypeAccess] KSerializer # 0| 0: [WildcardTypeAccess] ? ... @@ -204,7 +187,7 @@ app/src/main/kotlin/testProject/App.kt: # 7| 1: [VarAccess] INSTANCE # 7| -1: [TypeAccess] KSerializer # 7| 0: [IntegerLiteral] 2 -# 0| 1: [Method] deserialize +# 0| 3: [Method] deserialize # 0| 3: [TypeAccess] Project #-----| 4: (Parameters) # 0| 0: [Parameter] decoder @@ -342,7 +325,13 @@ app/src/main/kotlin/testProject/App.kt: # 7| 1: [VarAccess] tmp4_local0 # 7| 2: [VarAccess] tmp5_local1 # 7| 3: [NullLiteral] null -# 0| 1: [Method] serialize +# 0| 4: [Method] getDescriptor +# 0| 3: [TypeAccess] SerialDescriptor +# 0| 5: [BlockStmt] { ... } +# 0| 0: [ReturnStmt] return ... +# 0| 0: [VarAccess] this.descriptor +# 0| -1: [ThisAccess] this +# 0| 5: [Method] serialize # 0| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 0| 0: [Parameter] encoder @@ -397,6 +386,17 @@ app/src/main/kotlin/testProject/App.kt: # 7| -1: [ThisAccess] $serializer.this # 7| 0: [TypeAccess] $serializer # 7| 1: [VarAccess] tmp0_serialDesc +# 7| 10: [Class] Companion +# 0| 1: [Method] serializer +# 0| 3: [TypeAccess] KSerializer +# 0| 0: [TypeAccess] Project +# 7| 5: [BlockStmt] { ... } +# 7| 0: [ReturnStmt] return ... +# 7| 0: [VarAccess] INSTANCE +# 7| 2: [Constructor] Companion +# 7| 5: [BlockStmt] { ... } +# 7| 0: [SuperConstructorInvocationStmt] super(...) +# 7| 1: [BlockStmt] { ... } # 8| 11: [Constructor] Project #-----| 4: (Parameters) # 8| 0: [Parameter] name @@ -412,21 +412,21 @@ app/src/main/kotlin/testProject/App.kt: # 8| 1: [ExprStmt] ; # 8| 0: [KtInitializerAssignExpr] ...=... # 8| 0: [VarAccess] language -# 8| 12: [Method] getName +# 8| 12: [FieldDeclaration] String name; +# 8| -1: [TypeAccess] String +# 8| 0: [VarAccess] name +# 8| 13: [Method] getName # 8| 3: [TypeAccess] String # 8| 5: [BlockStmt] { ... } # 8| 0: [ReturnStmt] return ... # 8| 0: [VarAccess] this.name # 8| -1: [ThisAccess] this -# 8| 12: [FieldDeclaration] String name; -# 8| -1: [TypeAccess] String -# 8| 0: [VarAccess] name # 8| 14: [Method] getLanguage # 8| 3: [TypeAccess] int # 8| 5: [BlockStmt] { ... } # 8| 0: [ReturnStmt] return ... # 8| 0: [VarAccess] this.language # 8| -1: [ThisAccess] this -# 8| 14: [FieldDeclaration] int language; +# 8| 15: [FieldDeclaration] int language; # 8| -1: [TypeAccess] int # 8| 0: [VarAccess] language diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/User.java b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/User.java new file mode 100644 index 00000000000..12d4b0937da --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/User.java @@ -0,0 +1,9 @@ +public class User { + + public static int test(Test1 test1, Test2 test2, Test3 test3) { + + return test1.f$main() + test2.f$mymodule() + test3.f$reservedchars___(); + + } + +} diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.expected b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.expected new file mode 100644 index 00000000000..a1fc953a254 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.expected @@ -0,0 +1,4 @@ +| User.java:3:21:3:24 | test | +| test1.kt:3:12:3:22 | f$main | +| test2.kt:3:12:3:22 | f$mymodule | +| test3.kt:3:12:3:22 | f$reservedchars___ | diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.py b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.py new file mode 100644 index 00000000000..0a41ac5b3bf --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.py @@ -0,0 +1,3 @@ +from create_database_utils import * + +run_codeql_database_create(["kotlinc test1.kt", "kotlinc test2.kt -module-name mymodule", "kotlinc test3.kt -module-name reservedchars\\\"${}/", "javac User.java -cp ." ], lang="java") diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.ql b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.ql new file mode 100644 index 00000000000..f1355df2e88 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.ql @@ -0,0 +1,5 @@ +import java + +from Method m +where m.fromSource() +select m diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test1.kt b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test1.kt new file mode 100644 index 00000000000..c14fec0452e --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test1.kt @@ -0,0 +1,5 @@ +public class Test1 { + + internal fun f() = 1 + +} diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test2.kt b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test2.kt new file mode 100644 index 00000000000..c37d26c39fc --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test2.kt @@ -0,0 +1,5 @@ +public class Test2 { + + internal fun f() = 2 + +} diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test3.kt b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test3.kt new file mode 100644 index 00000000000..5fcdaced80c --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test3.kt @@ -0,0 +1,5 @@ +public class Test3 { + + internal fun f() = 3 + +} diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/JavaUser.java b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/JavaUser.java index 3c79f5828c8..f54b65bde92 100644 --- a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/JavaUser.java +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/JavaUser.java @@ -21,6 +21,15 @@ public class JavaUser { String result4 = d.identity("goodbye"); Short result5 = e.returnSixth(1, "hello", 1.0f, 1.0, 1L, (short)1); + OuterGeneric.InnerNotGeneric innerGetterTest = (new OuterGeneric()).getInnerNotGeneric(); + OuterNotGeneric.InnerGeneric innerGetterTest2 = (new OuterNotGeneric()).getInnerGeneric(); + + TypeParamVisibility tpv = new TypeParamVisibility(); + TypeParamVisibility.VisibleBecauseInner visibleBecauseInner = tpv.getVisibleBecauseInner(); + TypeParamVisibility.VisibleBecauseInnerIndirectContainer.VisibleBecauseInnerIndirect visibleBecauseInnerIndirect = tpv.getVisibleBecauseInnerIndirect(); + TypeParamVisibility.NotVisibleBecauseStatic notVisibleBecauseStatic = tpv.getNotVisibleBecauseStatic(); + TypeParamVisibility.NotVisibleBecauseStaticIndirectContainer.NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect = tpv.getNotVisibleBecauseStaticIndirect(); + } } diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/KotlinUser.kt b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/KotlinUser.kt index 01102e86881..44474b84619 100644 --- a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/KotlinUser.kt +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/KotlinUser.kt @@ -22,6 +22,15 @@ class User { val result4 = d.identity("goodbye") val result5 = e.returnSixth(1, "hello", 1.0f, 1.0, 1L, 1.toShort()) + val innerGetterTest = OuterGeneric().getInnerNotGeneric() + val innerGetterTest2 = OuterNotGeneric().getInnerGeneric() + + val tpv = TypeParamVisibility() + val visibleBecauseInner = tpv.getVisibleBecauseInner(); + val visibleBecauseInnerIndirect = tpv.getVisibleBecauseInnerIndirect() + val notVisibleBecauseStatic = tpv.getNotVisibleBecauseStatic() + val notVisibleBecauseStaticIndirect = tpv.getNotVisibleBecauseStaticIndirect() + } } diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterGeneric.java b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterGeneric.java index 36706f2cd42..b98950ad6dc 100644 --- a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterGeneric.java +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterGeneric.java @@ -8,6 +8,8 @@ public class OuterGeneric { } + public InnerNotGeneric getInnerNotGeneric() { return null; } + public class InnerGeneric { public InnerGeneric(R r) { } diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterNotGeneric.java b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterNotGeneric.java index 8f998968960..68a0f62d768 100644 --- a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterNotGeneric.java +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterNotGeneric.java @@ -8,4 +8,10 @@ public class OuterNotGeneric { } + public InnerGeneric getInnerGeneric() { + + return new InnerGeneric(); + + } + } diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/TypeParamVisibility.java b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/TypeParamVisibility.java new file mode 100644 index 00000000000..1ac6d4892e3 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/TypeParamVisibility.java @@ -0,0 +1,29 @@ +package extlib; + +public class TypeParamVisibility { + + public class VisibleBecauseInner { } + + public class VisibleBecauseInnerIndirectContainer { + + public class VisibleBecauseInnerIndirect { } + + } + + public static class NotVisibleBecauseStatic { } + + public static class NotVisibleBecauseStaticIndirectContainer { + + public class NotVisibleBecauseStaticIndirect { } + + } + + public VisibleBecauseInner getVisibleBecauseInner() { return new VisibleBecauseInner(); } + + public VisibleBecauseInnerIndirectContainer.VisibleBecauseInnerIndirect getVisibleBecauseInnerIndirect() { return (new VisibleBecauseInnerIndirectContainer()).new VisibleBecauseInnerIndirect(); } + + public NotVisibleBecauseStatic getNotVisibleBecauseStatic() { return new NotVisibleBecauseStatic(); } + + public NotVisibleBecauseStaticIndirectContainer.NotVisibleBecauseStaticIndirect getNotVisibleBecauseStaticIndirect() { return (new NotVisibleBecauseStaticIndirectContainer()).new NotVisibleBecauseStaticIndirect(); } + +} diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/test.expected b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/test.expected index e7c0acaa8f6..1c37ebd0eff 100644 --- a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/test.expected +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/test.expected @@ -59,6 +59,15 @@ callArgs | JavaUser.java:22:21:22:70 | returnSixth(...) | JavaUser.java:22:53:22:55 | 1.0 | 3 | | JavaUser.java:22:21:22:70 | returnSixth(...) | JavaUser.java:22:58:22:59 | 1L | 4 | | JavaUser.java:22:21:22:70 | returnSixth(...) | JavaUser.java:22:62:22:69 | (...)... | 5 | +| JavaUser.java:24:60:24:108 | getInnerNotGeneric(...) | JavaUser.java:24:61:24:86 | new OuterGeneric(...) | -1 | +| JavaUser.java:24:61:24:86 | new OuterGeneric(...) | JavaUser.java:24:65:24:84 | OuterGeneric | -3 | +| JavaUser.java:25:61:25:101 | getInnerGeneric(...) | JavaUser.java:25:62:25:82 | new OuterNotGeneric(...) | -1 | +| JavaUser.java:25:62:25:82 | new OuterNotGeneric(...) | JavaUser.java:25:66:25:80 | OuterNotGeneric | -3 | +| JavaUser.java:27:39:27:71 | new TypeParamVisibility(...) | JavaUser.java:27:43:27:69 | TypeParamVisibility | -3 | +| JavaUser.java:28:83:28:110 | getVisibleBecauseInner(...) | JavaUser.java:28:83:28:85 | tpv | -1 | +| JavaUser.java:29:136:29:171 | getVisibleBecauseInnerIndirect(...) | JavaUser.java:29:136:29:138 | tpv | -1 | +| JavaUser.java:30:83:30:114 | getNotVisibleBecauseStatic(...) | JavaUser.java:30:83:30:85 | tpv | -1 | +| JavaUser.java:31:140:31:179 | getNotVisibleBecauseStaticIndirect(...) | JavaUser.java:31:140:31:142 | tpv | -1 | | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | KotlinUser.kt:9:13:9:31 | OuterGeneric | -3 | | KotlinUser.kt:9:33:9:63 | new InnerGeneric(...) | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | -2 | | KotlinUser.kt:9:33:9:63 | new InnerGeneric(...) | KotlinUser.kt:9:33:9:63 | InnerGeneric | -3 | @@ -116,6 +125,15 @@ callArgs | KotlinUser.kt:23:21:23:71 | returnSixth(...) | KotlinUser.kt:23:56:23:57 | 1 | 4 | | KotlinUser.kt:23:21:23:71 | returnSixth(...) | KotlinUser.kt:23:62:23:70 | shortValue(...) | 5 | | KotlinUser.kt:23:62:23:70 | shortValue(...) | KotlinUser.kt:23:60:23:60 | 1 | -1 | +| KotlinUser.kt:25:27:25:48 | new OuterGeneric(...) | KotlinUser.kt:25:27:25:48 | OuterGeneric | -3 | +| KotlinUser.kt:25:50:25:69 | getInnerNotGeneric(...) | KotlinUser.kt:25:27:25:48 | new OuterGeneric(...) | -1 | +| KotlinUser.kt:26:28:26:44 | new OuterNotGeneric(...) | KotlinUser.kt:26:28:26:44 | OuterNotGeneric | -3 | +| KotlinUser.kt:26:46:26:62 | getInnerGeneric(...) | KotlinUser.kt:26:28:26:44 | new OuterNotGeneric(...) | -1 | +| KotlinUser.kt:28:15:28:43 | new TypeParamVisibility(...) | KotlinUser.kt:28:15:28:43 | TypeParamVisibility | -3 | +| KotlinUser.kt:29:35:29:58 | getVisibleBecauseInner(...) | KotlinUser.kt:29:31:29:33 | tpv | -1 | +| KotlinUser.kt:30:43:30:74 | getVisibleBecauseInnerIndirect(...) | KotlinUser.kt:30:39:30:41 | tpv | -1 | +| KotlinUser.kt:31:39:31:66 | getNotVisibleBecauseStatic(...) | KotlinUser.kt:31:35:31:37 | tpv | -1 | +| KotlinUser.kt:32:47:32:82 | getNotVisibleBecauseStaticIndirect(...) | KotlinUser.kt:32:43:32:45 | tpv | -1 | genericTypes | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | S | | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | S | @@ -127,6 +145,11 @@ genericTypes | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | A | | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | B | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | S | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | S | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | S | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | S | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | S | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | T | paramTypes | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | S | | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | String | @@ -149,6 +172,18 @@ paramTypes | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | String | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | S | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | String | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | S | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | String | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | S | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | String | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | S | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | String | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | String | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | S | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | String | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | String | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | T | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | String | constructors | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | InnerGeneric(java.lang.Object) | | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | InnerGeneric(java.lang.Object,java.lang.Object) | @@ -171,6 +206,14 @@ constructors | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | InnerGeneric() | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | InnerGeneric() | | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | OuterNotGeneric() | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | NotVisibleBecauseStatic() | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | NotVisibleBecauseStaticIndirect() | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer.class:0:0:0:0 | NotVisibleBecauseStaticIndirectContainer | NotVisibleBecauseStaticIndirectContainer() | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | VisibleBecauseInner() | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | VisibleBecauseInnerIndirect() | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer | VisibleBecauseInnerIndirectContainer() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | TypeParamVisibility() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | TypeParamVisibility() | methods | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | returnsecond | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | returnsecond(java.lang.Object,java.lang.Object) | | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | returnsecond | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | returnsecond(java.lang.Object,java.lang.Object,java.lang.Object) | @@ -181,14 +224,27 @@ methods | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | identity | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | identity(java.lang.String) | | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | identity | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | identity(java.lang.Object) | | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | identity | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | identity(java.lang.String) | +| extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | getInnerNotGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | getInnerNotGeneric() | +| extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | getInnerNotGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | getInnerNotGeneric() | +| extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | getInnerNotGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | getInnerNotGeneric() | | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | returnSixth | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | returnSixth(java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object) | | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | returnSixth | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | returnSixth(java.lang.Integer,java.lang.String,java.lang.Float,java.lang.Double,java.lang.Long,java.lang.Short) | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | identity | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | identity(java.lang.Object) | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | identity | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | identity(java.lang.String) | +| extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | getInnerGeneric | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | getInnerGeneric() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getNotVisibleBecauseStatic() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getNotVisibleBecauseStatic() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getNotVisibleBecauseStaticIndirect() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getNotVisibleBecauseStaticIndirect() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getVisibleBecauseInner() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getVisibleBecauseInner() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getVisibleBecauseInnerIndirect() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getVisibleBecauseInnerIndirect() | nestedTypes | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | +| extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric<> | | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | @@ -198,7 +254,26 @@ nestedTypes | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | +| extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric<> | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic<> | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer.class:0:0:0:0 | NotVisibleBecauseStaticIndirectContainer | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect<> | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer.class:0:0:0:0 | NotVisibleBecauseStaticIndirectContainer | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer.class:0:0:0:0 | NotVisibleBecauseStaticIndirectContainer | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer.class:0:0:0:0 | NotVisibleBecauseStaticIndirectContainer | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner<> | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility<> | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect<> | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer<> | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer<> | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer<> | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility<> | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer<> | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | javaKotlinCalleeAgreement | JavaUser.java:16:22:16:47 | returnsecond(...) | KotlinUser.kt:17:21:17:44 | returnsecond(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | returnsecond | | JavaUser.java:17:23:17:53 | returnsecond(...) | KotlinUser.kt:18:22:18:50 | returnsecond(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | returnsecond | @@ -207,6 +282,12 @@ javaKotlinCalleeAgreement | JavaUser.java:20:22:20:40 | identity(...) | KotlinUser.kt:21:21:21:37 | identity(...) | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | identity | | JavaUser.java:21:22:21:42 | identity(...) | KotlinUser.kt:22:21:22:39 | identity(...) | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | identity | | JavaUser.java:22:21:22:70 | returnSixth(...) | KotlinUser.kt:23:21:23:71 | returnSixth(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | returnSixth | +| JavaUser.java:24:60:24:108 | getInnerNotGeneric(...) | KotlinUser.kt:25:50:25:69 | getInnerNotGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | getInnerNotGeneric | +| JavaUser.java:25:61:25:101 | getInnerGeneric(...) | KotlinUser.kt:26:46:26:62 | getInnerGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | getInnerGeneric | +| JavaUser.java:28:83:28:110 | getVisibleBecauseInner(...) | KotlinUser.kt:29:35:29:58 | getVisibleBecauseInner(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInner | +| JavaUser.java:29:136:29:171 | getVisibleBecauseInnerIndirect(...) | KotlinUser.kt:30:43:30:74 | getVisibleBecauseInnerIndirect(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInnerIndirect | +| JavaUser.java:30:83:30:114 | getNotVisibleBecauseStatic(...) | KotlinUser.kt:31:39:31:66 | getNotVisibleBecauseStatic(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStatic | +| JavaUser.java:31:140:31:179 | getNotVisibleBecauseStaticIndirect(...) | KotlinUser.kt:32:47:32:82 | getNotVisibleBecauseStaticIndirect(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStaticIndirect | javaKotlinConstructorAgreement | JavaUser.java:7:52:7:110 | new InnerGeneric(...) | KotlinUser.kt:9:33:9:63 | new InnerGeneric(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | | JavaUser.java:7:53:7:79 | new OuterGeneric(...) | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | @@ -224,12 +305,19 @@ javaKotlinConstructorAgreement | JavaUser.java:10:48:10:74 | new OuterGeneric(...) | KotlinUser.kt:10:14:10:32 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | JavaUser.java:10:48:10:74 | new OuterGeneric(...) | KotlinUser.kt:11:13:11:31 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | JavaUser.java:11:48:11:73 | new OuterGeneric(...) | KotlinUser.kt:12:14:12:35 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | +| JavaUser.java:11:48:11:73 | new OuterGeneric(...) | KotlinUser.kt:25:27:25:48 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | JavaUser.java:12:46:12:95 | new InnerGeneric(...) | KotlinUser.kt:13:31:13:52 | new InnerGeneric(...) | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | | JavaUser.java:12:47:12:67 | new OuterNotGeneric(...) | KotlinUser.kt:13:13:13:29 | new OuterNotGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | +| JavaUser.java:12:47:12:67 | new OuterNotGeneric(...) | KotlinUser.kt:26:28:26:44 | new OuterNotGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | | JavaUser.java:13:49:13:111 | new InnerStaticGeneric(...) | KotlinUser.kt:14:26:14:63 | new InnerStaticGeneric(...) | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | | JavaUser.java:14:103:14:248 | new InnerManyParams(...) | KotlinUser.kt:15:69:15:100 | new InnerManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | | JavaUser.java:14:104:14:200 | new MiddleManyParams(...) | KotlinUser.kt:15:41:15:67 | new MiddleManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | | JavaUser.java:14:105:14:152 | new OuterManyParams(...) | KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | +| JavaUser.java:24:61:24:86 | new OuterGeneric(...) | KotlinUser.kt:12:14:12:35 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | +| JavaUser.java:24:61:24:86 | new OuterGeneric(...) | KotlinUser.kt:25:27:25:48 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | +| JavaUser.java:25:62:25:82 | new OuterNotGeneric(...) | KotlinUser.kt:13:13:13:29 | new OuterNotGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | +| 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 | @@ -239,9 +327,20 @@ javaKotlinLocalTypeAgreement | 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 | #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 | @@ -259,6 +358,8 @@ javaKotlinLocalTypeAgreement | JavaUser.java:14:104:14:200 | new MiddleManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | JavaUser.java:14:183:14:188 | Double | | JavaUser.java:14:105:14:152 | new OuterManyParams(...) | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | JavaUser.java:14:125:14:131 | Integer | | JavaUser.java:14:105:14:152 | new OuterManyParams(...) | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | JavaUser.java:14:134:14:139 | String | +| JavaUser.java:24:61:24:86 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | JavaUser.java:24:78:24:83 | String | +| JavaUser.java:27:39:27:71 | new TypeParamVisibility(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | JavaUser.java:27:63:27:68 | String | | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | KotlinUser.kt:9:13:9:31 | Integer | | KotlinUser.kt:9:33:9:63 | new InnerGeneric(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | KotlinUser.kt:9:33:9:63 | String | | KotlinUser.kt:10:14:10:32 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | KotlinUser.kt:10:14:10:32 | Integer | @@ -273,3 +374,5 @@ javaKotlinLocalTypeAgreement | KotlinUser.kt:15:41:15:67 | new MiddleManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | KotlinUser.kt:15:41:15:67 | Float | | KotlinUser.kt:15:69:15:100 | new InnerManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | KotlinUser.kt:15:69:15:100 | Long | | KotlinUser.kt:15:69:15:100 | new InnerManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | KotlinUser.kt:15:69:15:100 | Short | +| KotlinUser.kt:25:27:25:48 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | KotlinUser.kt:25:27:25:48 | String | +| KotlinUser.kt:28:15:28:43 | new TypeParamVisibility(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | KotlinUser.kt:28:15:28:43 | String | diff --git a/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/hasprops.kt b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/hasprops.kt new file mode 100644 index 00000000000..ff83b18a31a --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/hasprops.kt @@ -0,0 +1,9 @@ +class HasProps { + + var accessorsPublic = 1 + + var setterPrivate = 3 + private set + +} + diff --git a/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.expected b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.expected new file mode 100644 index 00000000000..c497684b152 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.expected @@ -0,0 +1,7 @@ +| hasprops.kt:3:3:3:25 | getAccessorsPublic | +| hasprops.kt:3:3:3:25 | setAccessorsPublic | +| hasprops.kt:5:3:6:15 | getSetterPrivate | +| hasprops.kt:6:13:6:15 | setSetterPrivate$private | +| usesprops.kt:1:1:9:1 | user | +| usesprops.kt:3:3:3:58 | useGetters | +| usesprops.kt:5:3:7:3 | useSetter | diff --git a/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.py b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.py new file mode 100644 index 00000000000..5599f459849 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.py @@ -0,0 +1,3 @@ +from create_database_utils import * + +run_codeql_database_create(["kotlinc hasprops.kt", "kotlinc usesprops.kt -cp ."], lang="java") diff --git a/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.ql b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.ql new file mode 100644 index 00000000000..f1355df2e88 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.ql @@ -0,0 +1,5 @@ +import java + +from Method m +where m.fromSource() +select m diff --git a/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/usesprops.kt b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/usesprops.kt new file mode 100644 index 00000000000..5157865df17 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/usesprops.kt @@ -0,0 +1,9 @@ +fun user(hp: HasProps) { + + fun useGetters() = hp.accessorsPublic + hp.setterPrivate + + fun useSetter(x: Int) { + hp.accessorsPublic = x + } + +} diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 02f489ea9c5..b5ceb823e75 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,26 @@ +## 0.3.1 + +### New Features + +* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract a type, or if an up/downgrade script is unable to provide a type. + +### Minor Analysis Improvements + +* Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance. +* Added `Modifier.isInline()`. +* Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs. +* Added additional flow sources for uses of external storage on Android. + +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + +### Minor Analysis Improvements + +Added a flow step for `String.valueOf` calls on tainted `android.text.Editable` objects. + ## 0.2.3 ## 0.2.2 diff --git a/java/ql/src/IDEContextual.qll b/java/ql/lib/IDEContextual.qll similarity index 100% rename from java/ql/src/IDEContextual.qll rename to java/ql/lib/IDEContextual.qll diff --git a/java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md b/java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md new file mode 100644 index 00000000000..f24c9379abb --- /dev/null +++ b/java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* The QL predicate `Expr::getUnderlyingExpr` has been added. It can be used to look through casts and not-null expressions and obtain the underlying expression to which they apply. diff --git a/java/ql/lib/change-notes/2022-05-25-string-valueof-editable-step.md b/java/ql/lib/change-notes/2022-05-25-string-valueof-editable-step.md deleted file mode 100644 index 60b8a5a8a9d..00000000000 --- a/java/ql/lib/change-notes/2022-05-25-string-valueof-editable-step.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -Added a flow step for `String.valueOf` calls on tainted `android.text.Editable` objects. diff --git a/java/ql/lib/change-notes/2022-06-13-kotlin-break-loops.md b/java/ql/lib/change-notes/2022-06-13-kotlin-break-loops.md deleted file mode 100644 index 412cf7d5ff5..00000000000 --- a/java/ql/lib/change-notes/2022-06-13-kotlin-break-loops.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs. diff --git a/java/ql/lib/change-notes/2022-07-26-scanner-models.md b/java/ql/lib/change-notes/2022-07-26-scanner-models.md new file mode 100644 index 00000000000..6a78982d639 --- /dev/null +++ b/java/ql/lib/change-notes/2022-07-26-scanner-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added data flow models for `java.util.Scanner`. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2022-07-27-nullness-junit5.md b/java/ql/lib/change-notes/2022-07-27-nullness-junit5.md new file mode 100644 index 00000000000..6cfb0949c69 --- /dev/null +++ b/java/ql/lib/change-notes/2022-07-27-nullness-junit5.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* The JUnit5 version of `AssertNotNull` is now recognized, which removes + related false positives in the nullness queries. diff --git a/java/ql/lib/change-notes/released/0.3.0.md b/java/ql/lib/change-notes/released/0.3.0.md new file mode 100644 index 00000000000..0c908384d1e --- /dev/null +++ b/java/ql/lib/change-notes/released/0.3.0.md @@ -0,0 +1,9 @@ +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + +### Minor Analysis Improvements + +Added a flow step for `String.valueOf` calls on tainted `android.text.Editable` objects. diff --git a/java/ql/lib/change-notes/released/0.3.1.md b/java/ql/lib/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..a453f034d5c --- /dev/null +++ b/java/ql/lib/change-notes/released/0.3.1.md @@ -0,0 +1,12 @@ +## 0.3.1 + +### New Features + +* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract a type, or if an up/downgrade script is unable to provide a type. + +### Minor Analysis Improvements + +* Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance. +* Added `Modifier.isInline()`. +* Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs. +* Added additional flow sources for uses of external storage on Android. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 0b605901b42..bb106b1cb63 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.3 +lastReleaseVersion: 0.3.1 diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme index cf58c7d9b1f..81ccfabe82e 100755 --- a/java/ql/lib/config/semmlecode.dbscheme +++ b/java/ql/lib/config/semmlecode.dbscheme @@ -332,6 +332,14 @@ modifiers( 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, @@ -1012,13 +1020,13 @@ javadocText( @classorinterfaceorpackage = @classorinterface | @package; @classorinterfaceorcallable = @classorinterface | @callable; @boundedtype = @typevariable | @wildcard; -@reftype = @classorinterface | @array | @boundedtype; +@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 | +@element = @package | @modifier | @annotation | @errortype | @locatableElement; @locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | diff --git a/java/ql/lib/config/semmlecode.dbscheme.stats b/java/ql/lib/config/semmlecode.dbscheme.stats index 2fc1431a73f..0490619a996 100644 --- a/java/ql/lib/config/semmlecode.dbscheme.stats +++ b/java/ql/lib/config/semmlecode.dbscheme.stats @@ -1,20 +1,20 @@ - - @diagnostic - 634718 - - - @externalDataElement - 1 - @javacompilation 8629 @kotlincompilation - 6824 + 6822 + + + @diagnostic + 624933 + + + @externalDataElement + 1 @duplication @@ -26,27 +26,31 @@ @file - 8020653 + 8017700 @folder - 1280356 + 1279884 @package - 612878 + 612652 @primitive - 12284 + 12280 @modifier - 12284 + 13644 + + + @errortype + 1 @class - 12579704 + 12579165 @kt_nullable_type @@ -54,7 +58,7 @@ @kt_notnull_type - 193427 + 194340 @kt_type_alias @@ -66,27 +70,27 @@ @fielddecl - 399940 + 399793 @field - 27583622 + 27573466 @constructor - 6889080 + 6886544 @method - 93482380 - - - @location_default - 431212495 + 93447961 @param - 101137218 + 101099980 + + + @location_default + 431053728 @exception @@ -94,19 +98,19 @@ @typevariable - 5118694 + 5116810 @wildcard - 3116261 + 3637710 @typebound - 3872463 + 4393634 @array - 1119287 + 1118875 @import @@ -114,7 +118,7 @@ @block - 846290 + 845979 @ifstmt @@ -130,7 +134,7 @@ @whilestmt - 19743 + 19739 @dostmt @@ -146,11 +150,11 @@ @synchronizedstmt - 18562 + 18706 @returnstmt - 675212 + 675118 @throwstmt @@ -182,7 +186,7 @@ @localtypedeclstmt - 4069 + 4110 @constructorinvocationstmt @@ -190,7 +194,7 @@ @superconstructorinvocationstmt - 225902 + 226569 @case @@ -202,7 +206,7 @@ @labeledstmt - 2443 + 2518 @yieldstmt @@ -214,7 +218,7 @@ @whenbranch - 238370 + 233347 @arrayaccess @@ -334,7 +338,7 @@ @andlogicalexpr - 41441 + 41715 @orlogicalexpr @@ -410,7 +414,7 @@ @instanceofexpr - 31274 + 31086 @localvariabledeclexpr @@ -418,11 +422,11 @@ @typeliteral - 147176 + 148317 @thisaccess - 952512 + 952380 @superaccess @@ -434,11 +438,11 @@ @methodaccess - 1551591 + 1551738 @unannotatedtypeaccess - 2874591 + 2867985 @arraytypeaccess @@ -486,7 +490,7 @@ @lambdaexpr - 185816 + 186985 @memberref @@ -514,7 +518,7 @@ @whenexpr - 172153 + 172129 @getclassexpr @@ -522,35 +526,35 @@ @safecastexpr - 6986 + 6943 @implicitcastexpr - 33111 + 32911 @implicitnotnullexpr - 241008 + 239473 @implicitcoerciontounitexpr - 93086 + 92272 @notinstanceofexpr - 19586 + 19583 @stmtexpr - 58107 + 57757 @stringtemplateexpr - 55964 + 55943 @notnullexpr - 21375 + 21370 @unsafecoerceexpr @@ -558,15 +562,15 @@ @valueeqexpr - 103390 + 104218 @valueneexpr - 108240 + 108225 @propertyref - 9721 + 9663 @localvar @@ -610,7 +614,7 @@ @xmlelement - 106792352 + 106753032 @javadocText @@ -618,19 +622,19 @@ @xmlattribute - 129898822 + 129850995 @xmlnamespace - 8189 + 8186 @xmlcomment - 107485764 + 107446189 @xmlcharacters - 101574013 + 101536615 @config @@ -646,15 +650,15 @@ @ktcomment - 133768 + 133719 @ktcommentsection - 59246 + 59191 @kt_property - 30317687 + 30306525 @@ -876,30 +880,30 @@ compilation_started - 6824 + 6822 id - 6824 + 6822 compilation_args - 158338 + 158279 id - 6824 + 6822 num - 38219 + 38205 arg - 90089 + 90055 @@ -913,7 +917,7 @@ 20 21 - 2729 + 2728 23 @@ -944,7 +948,7 @@ 20 21 - 2729 + 2728 23 @@ -975,22 +979,22 @@ 1 2 - 4094 + 4093 2 3 - 2729 + 2728 3 4 - 4094 + 4093 5 6 - 27299 + 27289 @@ -1006,27 +1010,27 @@ 1 2 - 8189 + 8186 2 3 - 5459 + 5457 3 4 - 10919 + 10915 4 5 - 6824 + 6822 5 6 - 6824 + 6822 @@ -1042,22 +1046,22 @@ 1 2 - 69614 + 69588 2 3 - 2729 + 2728 4 5 - 6824 + 6822 5 6 - 10919 + 10915 @@ -1073,17 +1077,17 @@ 1 2 - 72344 + 72317 2 3 - 15014 + 15009 4 5 - 2729 + 2728 @@ -1093,19 +1097,19 @@ compilation_compiling_files - 60660 + 61130 id - 2320 + 2338 num - 17899 + 18038 file - 50716 + 51109 @@ -1119,22 +1123,22 @@ 1 2 - 331 + 334 2 3 - 662 + 668 35 36 - 662 + 668 54 55 - 662 + 668 @@ -1150,22 +1154,22 @@ 1 2 - 331 + 334 2 3 - 662 + 668 35 36 - 662 + 668 54 55 - 662 + 668 @@ -1181,17 +1185,17 @@ 2 3 - 6298 + 6346 4 5 - 10938 + 11023 6 8 - 662 + 668 @@ -1207,17 +1211,17 @@ 2 3 - 6298 + 6346 3 4 - 9944 + 10021 4 8 - 1657 + 1670 @@ -1233,12 +1237,12 @@ 1 2 - 40771 + 41087 2 3 - 9944 + 10021 @@ -1254,7 +1258,7 @@ 1 2 - 50716 + 51109 @@ -1264,19 +1268,19 @@ compilation_compiling_files_completed - 60660 + 61130 id - 2320 + 2338 num - 17899 + 18038 result - 331 + 668 @@ -1290,22 +1294,22 @@ 1 2 - 331 + 334 2 3 - 662 + 668 35 36 - 662 + 668 54 55 - 662 + 668 @@ -1321,7 +1325,12 @@ 1 2 - 2320 + 1670 + + + 2 + 3 + 668 @@ -1337,17 +1346,17 @@ 2 3 - 6298 + 6346 4 5 - 10938 + 11023 6 8 - 662 + 668 @@ -1363,7 +1372,12 @@ 1 2 - 17899 + 17704 + + + 2 + 3 + 334 @@ -1376,10 +1390,15 @@ 12 + + 2 + 3 + 334 + 7 8 - 331 + 334 @@ -1392,10 +1411,15 @@ 12 + + 1 + 2 + 334 + 54 55 - 331 + 334 @@ -1826,23 +1850,23 @@ diagnostic_for - 634718 + 624933 diagnostic - 634718 + 624933 compilation - 6824 + 6822 file_number - 8189 + 8186 file_number_diagnostic_number - 60059 + 60037 @@ -1856,7 +1880,7 @@ 1 2 - 634718 + 624933 @@ -1872,7 +1896,7 @@ 1 2 - 634718 + 624933 @@ -1888,7 +1912,7 @@ 1 2 - 634718 + 624933 @@ -1907,18 +1931,18 @@ 1364 - 86 - 87 + 84 + 85 1364 100 101 - 2729 + 2728 - 106 - 107 + 101 + 102 1364 @@ -1935,7 +1959,7 @@ 3 4 - 2729 + 2728 4 @@ -1969,8 +1993,8 @@ 1364 - 36 - 37 + 34 + 35 1364 @@ -1979,8 +2003,8 @@ 1364 - 43 - 44 + 41 + 42 1364 @@ -2005,23 +2029,23 @@ 1364 - 32 - 33 + 34 + 35 1364 - 49 - 50 + 48 + 49 1364 - 106 - 107 + 100 + 101 1364 - 130 - 131 + 128 + 129 1364 @@ -2058,7 +2082,7 @@ 5 6 - 4094 + 4093 @@ -2082,8 +2106,13 @@ 1364 - 36 - 37 + 34 + 35 + 1364 + + + 40 + 41 1364 @@ -2091,11 +2120,6 @@ 42 1364 - - 43 - 44 - 1364 - 44 45 @@ -2114,63 +2138,63 @@ 1 + 3 + 5457 + + + 3 4 - 5459 + 1364 4 5 - 5459 + 5457 5 - 7 - 2729 + 6 + 1364 7 8 - 6824 + 6822 8 9 - 4094 + 4093 9 10 - 6824 + 9551 10 - 12 - 4094 - - - 12 14 - 4094 + 5457 15 16 - 2729 + 4093 16 17 - 9554 + 6822 - 17 + 18 20 - 4094 + 5457 20 22 - 4094 + 4093 @@ -2186,22 +2210,22 @@ 1 3 - 5459 + 5457 3 4 - 5459 + 8186 4 5 - 9554 + 6822 5 6 - 39584 + 39569 @@ -2217,27 +2241,27 @@ 1 3 - 4094 + 5457 3 4 - 6824 + 8186 4 5 - 28664 + 25925 5 6 - 13649 + 13644 6 7 - 6824 + 6822 @@ -2247,11 +2271,11 @@ compilation_compiler_times - 6824 + 6822 id - 6824 + 6822 cpu_seconds @@ -2259,7 +2283,7 @@ elapsed_seconds - 6824 + 6822 @@ -2273,7 +2297,7 @@ 1 2 - 6824 + 6822 @@ -2289,7 +2313,7 @@ 1 2 - 6824 + 6822 @@ -2337,7 +2361,7 @@ 1 2 - 6824 + 6822 @@ -2353,7 +2377,7 @@ 1 2 - 6824 + 6822 @@ -2579,11 +2603,11 @@ diagnostics - 634718 + 624933 id - 634718 + 624933 generated_by @@ -2599,11 +2623,11 @@ error_message - 96913 + 95513 full_error_message - 499584 + 502129 location @@ -2621,7 +2645,7 @@ 1 2 - 634718 + 624933 @@ -2637,7 +2661,7 @@ 1 2 - 634718 + 624933 @@ -2653,7 +2677,7 @@ 1 2 - 634718 + 624933 @@ -2669,7 +2693,7 @@ 1 2 - 634718 + 624933 @@ -2685,7 +2709,7 @@ 1 2 - 634718 + 624933 @@ -2701,7 +2725,7 @@ 1 2 - 634718 + 624933 @@ -2715,8 +2739,8 @@ 12 - 465 - 466 + 458 + 459 1364 @@ -2763,8 +2787,8 @@ 12 - 71 - 72 + 70 + 71 1364 @@ -2779,8 +2803,8 @@ 12 - 366 - 367 + 368 + 369 1364 @@ -2811,8 +2835,8 @@ 12 - 465 - 466 + 458 + 459 1364 @@ -2859,8 +2883,8 @@ 12 - 71 - 72 + 70 + 71 1364 @@ -2875,8 +2899,8 @@ 12 - 366 - 367 + 368 + 369 1364 @@ -2907,8 +2931,8 @@ 12 - 465 - 466 + 458 + 459 1364 @@ -2955,8 +2979,8 @@ 12 - 71 - 72 + 70 + 71 1364 @@ -2971,8 +2995,8 @@ 12 - 366 - 367 + 368 + 369 1364 @@ -3005,67 +3029,62 @@ 1 2 - 19109 + 19102 2 3 - 6824 + 5457 3 4 - 13649 + 12280 4 5 - 4094 + 5457 5 6 - 5459 + 5457 6 7 - 6824 + 6822 7 8 - 2729 + 2728 8 9 - 9554 + 9551 9 10 - 5459 + 6822 10 11 - 6824 + 8186 - 13 - 15 - 5459 + 14 + 17 + 6822 - 16 - 19 - 8189 - - - 20 + 17 21 - 2729 + 6822 @@ -3081,7 +3100,7 @@ 1 2 - 96913 + 95513 @@ -3097,7 +3116,7 @@ 1 2 - 96913 + 95513 @@ -3113,7 +3132,7 @@ 1 2 - 96913 + 95513 @@ -3129,52 +3148,62 @@ 1 2 - 23204 + 21831 2 3 - 5459 + 5457 3 4 - 13649 + 12280 4 + 5 + 5457 + + + 5 6 - 8189 + 4093 6 7 - 6824 + 8186 7 8 - 6824 + 12280 8 9 - 16379 + 6822 9 10 - 2729 + 4093 10 11 - 6824 + 5457 11 12 - 6824 + 5457 + + + 12 + 13 + 4093 @@ -3190,7 +3219,7 @@ 1 2 - 96913 + 95513 @@ -3206,17 +3235,17 @@ 1 2 - 409495 + 418896 2 3 - 49139 + 49121 3 5 - 40949 + 34112 @@ -3232,7 +3261,7 @@ 1 2 - 499584 + 502129 @@ -3248,7 +3277,7 @@ 1 2 - 499584 + 502129 @@ -3264,7 +3293,7 @@ 1 2 - 499584 + 502129 @@ -3280,7 +3309,7 @@ 1 2 - 499584 + 502129 @@ -3296,7 +3325,7 @@ 1 2 - 499584 + 502129 @@ -3310,8 +3339,8 @@ 12 - 465 - 466 + 458 + 459 1364 @@ -3374,8 +3403,8 @@ 12 - 71 - 72 + 70 + 71 1364 @@ -3390,8 +3419,8 @@ 12 - 366 - 367 + 368 + 369 1364 @@ -4848,31 +4877,31 @@ locations_default - 431212495 + 431053728 id - 431212495 + 431053728 file - 8020653 + 8017700 beginLine - 2802314 + 2801282 beginColumn - 176083 + 176018 endLine - 2803679 + 2802647 endColumn - 621068 + 620839 @@ -4886,7 +4915,7 @@ 1 2 - 431212495 + 431053728 @@ -4902,7 +4931,7 @@ 1 2 - 431212495 + 431053728 @@ -4918,7 +4947,7 @@ 1 2 - 431212495 + 431053728 @@ -4934,7 +4963,7 @@ 1 2 - 431212495 + 431053728 @@ -4950,7 +4979,7 @@ 1 2 - 431212495 + 431053728 @@ -4966,17 +4995,17 @@ 1 2 - 7179822 + 7177178 2 20 - 604688 + 604465 20 3605 - 236142 + 236055 @@ -4992,17 +5021,17 @@ 1 2 - 7179822 + 7177178 2 15 - 601958 + 601736 15 1830 - 238872 + 238784 @@ -5018,17 +5047,17 @@ 1 2 - 7179822 + 7177178 2 7 - 629258 + 629026 7 105 - 211572 + 211494 @@ -5044,17 +5073,17 @@ 1 2 - 7179822 + 7177178 2 18 - 601958 + 601736 18 1834 - 238872 + 238784 @@ -5070,17 +5099,17 @@ 1 2 - 7179822 + 7177178 2 15 - 604688 + 604465 15 205 - 236142 + 236055 @@ -5096,67 +5125,67 @@ 1 14 - 222492 + 222410 14 125 - 215667 + 215588 125 142 - 215667 + 215588 142 152 - 223857 + 223775 152 159 - 249792 + 249700 159 165 - 257982 + 257887 165 170 - 226587 + 226504 170 174 - 217032 + 216952 174 179 - 229317 + 229233 179 185 - 214302 + 214223 185 194 - 222492 + 222410 194 215 - 215667 + 215588 215 5877 - 91454 + 91420 @@ -5172,67 +5201,67 @@ 1 7 - 229317 + 229233 7 65 - 212937 + 212859 65 73 - 217032 + 216952 73 78 - 207477 + 207401 78 81 - 191097 + 191027 81 84 - 249792 + 249700 84 86 - 215667 + 215588 86 88 - 257982 + 257887 88 90 - 222492 + 222410 90 93 - 248427 + 248335 93 97 - 218397 + 218317 97 106 - 214302 + 214223 106 5877 - 117388 + 117345 @@ -5248,62 +5277,62 @@ 1 5 - 222492 + 222410 5 17 - 196557 + 196485 17 19 - 167893 + 167831 19 20 - 214302 + 214223 20 21 - 268902 + 268803 21 22 - 283916 + 283812 22 23 - 330326 + 330204 23 24 - 304391 + 304279 24 25 - 236142 + 236055 25 26 - 170623 + 170560 26 28 - 212937 + 212859 28 45 - 193827 + 193756 @@ -5319,32 +5348,32 @@ 1 2 - 904985 + 904652 2 3 - 896795 + 896465 3 4 - 483204 + 483026 4 5 - 211572 + 211494 5 11 - 221127 + 221046 11 97 - 84629 + 84597 @@ -5360,72 +5389,72 @@ 1 13 - 219762 + 219681 13 60 - 210207 + 210130 60 64 - 223857 + 223775 64 66 - 210207 + 210130 66 68 - 259347 + 259251 68 69 - 131038 + 130990 69 70 - 155608 + 155551 70 71 - 135133 + 135083 71 73 - 236142 + 236055 73 75 - 212937 + 212859 75 78 - 234777 + 234691 78 82 - 252522 + 252429 82 89 - 214302 + 214223 89 104 - 106468 + 106429 @@ -5441,67 +5470,67 @@ 1 11 - 15014 + 15009 15 34 - 15014 + 15009 36 58 - 13649 + 13644 63 88 - 13649 + 13644 89 132 - 13649 + 13644 141 196 - 15014 + 15009 210 285 - 13649 + 13644 316 468 - 13649 + 13644 496 853 - 13649 + 13644 899 1420 - 13649 + 13644 1472 2256 - 13649 + 13644 2300 2526 - 13649 + 13644 2589 226687 - 8189 + 8186 @@ -5517,72 +5546,72 @@ 1 9 - 9554 + 9551 9 11 - 13649 + 13644 12 16 - 8189 + 8186 16 19 - 13649 + 13644 19 31 - 13649 + 13644 35 73 - 13649 + 13644 73 83 - 13649 + 13644 85 104 - 15014 + 15009 104 110 - 10919 + 10915 110 114 - 15014 + 15009 115 119 - 13649 + 13644 119 121 - 12284 + 12280 121 126 - 13649 + 13644 126 5877 - 9554 + 9551 @@ -5598,67 +5627,67 @@ 1 10 - 15014 + 15009 10 29 - 13649 + 13644 29 43 - 13649 + 13644 45 58 - 13649 + 13644 58 85 - 13649 + 13644 86 106 - 13649 + 13644 108 167 - 13649 + 13644 171 227 - 13649 + 13644 231 379 - 13649 + 13644 383 650 - 13649 + 13644 651 891 - 13649 + 13644 940 1086 - 13649 + 13644 1093 2051 - 10919 + 10915 @@ -5674,67 +5703,67 @@ 1 10 - 15014 + 15009 10 30 - 13649 + 13644 30 43 - 13649 + 13644 46 59 - 13649 + 13644 60 87 - 13649 + 13644 87 109 - 13649 + 13644 115 173 - 13649 + 13644 174 226 - 13649 + 13644 230 380 - 13649 + 13644 383 650 - 13649 + 13644 653 892 - 13649 + 13644 940 1084 - 13649 + 13644 1092 2051 - 10919 + 10915 @@ -5750,67 +5779,67 @@ 1 8 - 15014 + 15009 8 17 - 13649 + 13644 18 25 - 10919 + 10915 25 30 - 13649 + 13644 30 36 - 13649 + 13644 36 44 - 13649 + 13644 45 56 - 12284 + 12280 57 64 - 13649 + 13644 64 73 - 13649 + 13644 73 86 - 13649 + 13644 86 106 - 13649 + 13644 107 129 - 13649 + 13644 129 197 - 13649 + 13644 392 @@ -5831,67 +5860,67 @@ 1 14 - 221127 + 221046 14 124 - 215667 + 215588 124 143 - 218397 + 218317 143 152 - 236142 + 236055 152 159 - 223857 + 223775 159 165 - 257982 + 257887 165 170 - 240237 + 240148 170 174 - 222492 + 222410 174 179 - 222492 + 222410 179 185 - 211572 + 211494 185 194 - 217032 + 216952 194 217 - 212937 + 212859 217 5877 - 103738 + 103700 @@ -5907,67 +5936,67 @@ 1 7 - 232047 + 231962 7 66 - 225222 + 225139 66 74 - 227952 + 227868 74 80 - 251157 + 251064 80 83 - 241602 + 241513 83 85 - 185637 + 185569 85 87 - 247062 + 246971 87 89 - 247062 + 246971 89 91 - 188367 + 188298 91 94 - 248427 + 248335 94 99 - 226587 + 226504 99 127 - 212937 + 212859 127 5877 - 69614 + 69588 @@ -5983,32 +6012,32 @@ 1 2 - 711157 + 710895 2 3 - 989614 + 989249 3 4 - 644273 + 644035 4 6 - 237507 + 237419 6 18 - 212937 + 212859 18 22 - 8189 + 8186 @@ -6024,62 +6053,62 @@ 1 5 - 219762 + 219681 5 17 - 199287 + 199214 17 19 - 163798 + 163737 19 20 - 192462 + 192392 20 21 - 281186 + 281083 21 22 - 272997 + 272896 22 23 - 330326 + 330204 23 24 - 307121 + 307008 24 25 - 225222 + 225139 25 26 - 184273 + 184205 26 28 - 223857 + 223775 28 44 - 203382 + 203307 @@ -6095,72 +6124,72 @@ 1 13 - 222492 + 222410 13 61 - 251157 + 251064 61 64 - 173353 + 173289 64 66 - 218397 + 218317 66 68 - 251157 + 251064 68 69 - 137863 + 137812 69 70 - 137863 + 137812 70 71 - 158338 + 158279 71 73 - 232047 + 231962 73 75 - 192462 + 192392 75 77 - 184273 + 184205 77 80 - 211572 + 211494 80 85 - 227952 + 227868 85 119 - 204747 + 204672 @@ -6176,57 +6205,57 @@ 1 2 - 146053 + 145999 2 3 - 64154 + 64130 3 5 - 50504 + 50485 5 13 - 50504 + 50485 13 53 - 47774 + 47756 53 146 - 47774 + 47756 146 351 - 47774 + 47756 357 997 - 47774 + 47756 1053 2396 - 47774 + 47756 2407 4957 - 47774 + 47756 5022 5934 - 23204 + 23196 @@ -6242,57 +6271,57 @@ 1 2 - 151513 + 151457 2 3 - 61424 + 61401 3 5 - 53234 + 53214 5 13 - 50504 + 50485 13 42 - 47774 + 47756 42 77 - 47774 + 47756 77 103 - 51869 + 51850 103 116 - 47774 + 47756 116 144 - 49139 + 49121 144 181 - 47774 + 47756 181 5877 - 12284 + 12280 @@ -6308,57 +6337,57 @@ 1 2 - 154243 + 154186 2 3 - 62789 + 62766 3 5 - 49139 + 49121 5 13 - 49139 + 49121 13 52 - 49139 + 49121 52 115 - 47774 + 47756 123 271 - 47774 + 47756 277 658 - 47774 + 47756 669 1200 - 47774 + 47756 1219 1635 - 47774 + 47756 1639 1722 - 17744 + 17738 @@ -6374,47 +6403,47 @@ 1 2 - 195192 + 195121 2 3 - 75074 + 75046 3 6 - 54599 + 54579 6 14 - 54599 + 54579 14 26 - 47774 + 47756 26 36 - 49139 + 49121 36 47 - 49139 + 49121 47 55 - 47774 + 47756 55 68 - 47774 + 47756 @@ -6430,57 +6459,57 @@ 1 2 - 154243 + 154186 2 3 - 61424 + 61401 3 5 - 49139 + 49121 5 13 - 49139 + 49121 13 53 - 50504 + 50485 53 115 - 47774 + 47756 123 271 - 47774 + 47756 280 656 - 47774 + 47756 669 1200 - 47774 + 47756 1217 1638 - 47774 + 47756 1640 1722 - 17744 + 17738 @@ -6490,15 +6519,15 @@ hasLocation - 316110113 + 316902470 locatableid - 315965424 + 316759199 id - 11558695 + 11554439 @@ -6512,12 +6541,12 @@ 1 2 - 315820736 + 316615929 2 3 - 144688 + 143270 @@ -6533,62 +6562,62 @@ 1 2 - 2097982 + 2097209 2 3 - 1008724 + 1008352 3 4 - 719347 + 717717 4 6 - 977329 + 978334 6 7 - 773946 + 773661 7 9 - 1019643 + 1019268 9 12 - 850385 + 848708 12 16 - 925460 + 926483 16 23 - 883145 + 882820 23 39 - 888605 + 888278 39 89 - 874955 + 873268 89 - 9987 - 539169 + 9991 + 540335 @@ -6598,23 +6627,23 @@ numlines - 215080728 + 215001538 element_id - 215080728 + 215001538 num_lines - 432700 + 432541 num_code - 434065 + 433905 num_comment - 1345875 + 1345379 @@ -6628,7 +6657,7 @@ 1 2 - 215080728 + 215001538 @@ -6644,7 +6673,7 @@ 1 2 - 215080728 + 215001538 @@ -6660,7 +6689,7 @@ 1 2 - 215080728 + 215001538 @@ -6676,37 +6705,37 @@ 1 2 - 232047 + 231962 2 3 - 53234 + 53214 3 4 - 45044 + 45027 4 7 - 34124 + 34112 7 14 - 32759 + 32747 15 839 - 32759 + 32747 3519 149603 - 2729 + 2728 @@ -6722,12 +6751,12 @@ 1 2 - 423145 + 422989 2 3 - 9554 + 9551 @@ -6743,27 +6772,27 @@ 1 2 - 274362 + 274261 2 3 - 69614 + 69588 3 4 - 36854 + 36841 4 6 - 34124 + 34112 6 987 - 17744 + 17738 @@ -6779,37 +6808,37 @@ 1 2 - 232047 + 231962 2 3 - 53234 + 53214 3 4 - 45044 + 45027 4 7 - 34124 + 34112 7 14 - 32759 + 32747 15 468 - 32759 + 32747 495 78746 - 4094 + 4093 @@ -6825,7 +6854,7 @@ 1 2 - 432700 + 432541 7 @@ -6846,27 +6875,27 @@ 1 2 - 274362 + 274261 2 3 - 69614 + 69588 3 4 - 36854 + 36841 4 6 - 34124 + 34112 6 987 - 19109 + 19102 @@ -6882,77 +6911,77 @@ 1 7 - 109198 + 109158 7 49 - 101008 + 100971 49 71 - 105103 + 105065 71 78 - 107833 + 107794 78 83 - 103738 + 103700 83 87 - 116023 + 115981 87 89 - 99643 + 99607 89 91 - 95548 + 95513 91 92 - 57329 + 57308 92 93 - 68249 + 68224 93 94 - 75074 + 75046 94 95 - 69614 + 69588 95 97 - 109198 + 109158 97 119 - 101008 + 100971 119 75115 - 27299 + 27289 @@ -6968,22 +6997,22 @@ 1 2 - 1104273 + 1103866 2 3 - 114658 + 114616 3 6 - 102373 + 102336 6 120 - 24569 + 24560 @@ -6999,22 +7028,22 @@ 1 2 - 1104273 + 1103866 2 3 - 114658 + 114616 3 6 - 101008 + 100971 6 121 - 25934 + 25925 @@ -7024,15 +7053,15 @@ files - 8020653 + 8017700 id - 8020653 + 8017700 name - 8020653 + 8017700 @@ -7046,7 +7075,7 @@ 1 2 - 8020653 + 8017700 @@ -7062,7 +7091,7 @@ 1 2 - 8020653 + 8017700 @@ -7072,15 +7101,15 @@ folders - 1280356 + 1279884 id - 1280356 + 1279884 name - 1280356 + 1279884 @@ -7094,7 +7123,7 @@ 1 2 - 1280356 + 1279884 @@ -7110,7 +7139,7 @@ 1 2 - 1280356 + 1279884 @@ -7120,15 +7149,15 @@ containerparent - 9298279 + 9294856 parent - 1321305 + 1320819 child - 9298279 + 9294856 @@ -7142,37 +7171,37 @@ 1 2 - 713887 + 713624 2 3 - 140593 + 140541 3 4 - 79169 + 79139 4 7 - 113293 + 113252 7 14 - 111928 + 111887 14 29 - 102373 + 102336 29 194 - 60059 + 60037 @@ -7188,7 +7217,7 @@ 1 2 - 9298279 + 9294856 @@ -7198,15 +7227,15 @@ cupackage - 7160712 + 7158076 id - 7160712 + 7158076 packageid - 611513 + 611288 @@ -7220,7 +7249,7 @@ 1 2 - 7160712 + 7158076 @@ -7236,52 +7265,52 @@ 1 2 - 148783 + 148728 2 3 - 80534 + 80504 3 4 - 55964 + 55943 4 5 - 42314 + 42298 5 7 - 46409 + 46392 7 10 - 50504 + 50485 10 15 - 50504 + 50485 15 21 - 49139 + 49121 21 36 - 47774 + 47756 39 187 - 39584 + 39569 @@ -8043,15 +8072,15 @@ packages - 612878 + 612652 id - 612878 + 612652 nodeName - 612878 + 612652 @@ -8065,7 +8094,7 @@ 1 2 - 612878 + 612652 @@ -8081,7 +8110,7 @@ 1 2 - 612878 + 612652 @@ -8091,15 +8120,15 @@ primitives - 12284 + 12280 id - 12284 + 12280 nodeName - 12284 + 12280 @@ -8113,7 +8142,7 @@ 1 2 - 12284 + 12280 @@ -8129,7 +8158,7 @@ 1 2 - 12284 + 12280 @@ -8139,15 +8168,15 @@ modifiers - 12284 + 13644 id - 12284 + 13644 nodeName - 12284 + 13644 @@ -8161,7 +8190,7 @@ 1 2 - 12284 + 13644 @@ -8177,7 +8206,7 @@ 1 2 - 12284 + 13644 @@ -8186,24 +8215,35 @@ - classes - 12579704 + error_type + 1 id - 12579704 + 1 + + + + + + classes + 12579165 + + + id + 12579165 nodeName - 6868605 + 6871534 parentid - 443620 + 443456 sourceid - 4519466 + 4517802 @@ -8217,7 +8257,7 @@ 1 2 - 12579704 + 12579165 @@ -8233,7 +8273,7 @@ 1 2 - 12579704 + 12579165 @@ -8249,7 +8289,7 @@ 1 2 - 12579704 + 12579165 @@ -8265,17 +8305,17 @@ 1 2 - 5735668 + 5740378 2 3 - 746646 + 745007 3 236 - 386290 + 386148 @@ -8291,17 +8331,17 @@ 1 2 - 6252997 + 6256153 2 3 - 547359 + 547157 3 52 - 68249 + 68224 @@ -8317,17 +8357,17 @@ 1 2 - 6229792 + 6232956 2 3 - 536439 + 536241 3 160 - 102373 + 102336 @@ -8343,57 +8383,57 @@ 1 2 - 107833 + 107794 2 3 - 54599 + 54579 3 4 - 32759 + 32747 4 5 - 30029 + 30018 5 7 - 34124 + 34112 7 11 - 40949 + 40934 11 17 - 34124 + 34112 17 23 - 34124 + 34112 23 40 - 36854 + 36841 40 707 - 34124 + 34112 1013 - 1412 - 4094 + 1414 + 4093 @@ -8409,52 +8449,52 @@ 1 2 - 107833 + 107794 2 3 - 54599 + 54579 3 4 - 35489 + 35476 4 5 - 34124 + 34112 5 7 - 38219 + 38205 7 11 - 40949 + 40934 11 17 - 36854 + 36841 17 23 - 34124 + 34112 23 40 - 35489 + 35476 40 - 828 - 25934 + 830 + 25925 @@ -8470,52 +8510,52 @@ 1 2 - 118753 + 118709 2 3 - 64154 + 64130 3 4 - 36854 + 36841 4 5 - 34124 + 34112 5 7 - 35489 + 35476 7 11 - 40949 + 40934 11 17 - 34124 + 34112 17 26 - 34124 + 34112 26 56 - 34124 + 34112 64 138 - 10919 + 10915 @@ -8531,17 +8571,17 @@ 1 2 - 4052641 + 4051149 2 11 - 342611 + 342485 11 1358 - 124213 + 124167 @@ -8557,17 +8597,17 @@ 1 2 - 4052641 + 4051149 2 6 - 360356 + 360223 6 783 - 106468 + 106429 @@ -8583,7 +8623,7 @@ 1 2 - 4519466 + 4517802 @@ -8593,26 +8633,26 @@ file_class - 15014 + 15009 id - 15014 + 15009 class_object - 122848 + 122803 id - 122848 + 122803 instance - 122848 + 122803 @@ -8626,7 +8666,7 @@ 1 2 - 122848 + 122803 @@ -8642,7 +8682,7 @@ 1 2 - 122848 + 122803 @@ -8652,19 +8692,19 @@ type_companion_object - 218397 + 218317 id - 218397 + 218317 instance - 218397 + 218317 companion_object - 218397 + 218317 @@ -8678,7 +8718,7 @@ 1 2 - 218397 + 218317 @@ -8694,7 +8734,7 @@ 1 2 - 218397 + 218317 @@ -8710,7 +8750,7 @@ 1 2 - 218397 + 218317 @@ -8726,7 +8766,7 @@ 1 2 - 218397 + 218317 @@ -8742,7 +8782,7 @@ 1 2 - 218397 + 218317 @@ -8758,7 +8798,7 @@ 1 2 - 218397 + 218317 @@ -8816,15 +8856,15 @@ kt_notnull_types - 193427 + 194340 id - 193427 + 194340 classid - 193427 + 194340 @@ -8838,7 +8878,7 @@ 1 2 - 193427 + 194340 @@ -8854,7 +8894,7 @@ 1 2 - 193427 + 194340 @@ -9437,15 +9477,15 @@ fielddecls - 399940 + 399793 id - 399940 + 399793 parentid - 60059 + 60037 @@ -9459,7 +9499,7 @@ 1 2 - 399940 + 399793 @@ -9475,32 +9515,32 @@ 1 2 - 30029 + 30018 2 3 - 13649 + 13644 3 4 - 5459 + 5457 4 5 - 2729 + 2728 6 16 - 5459 + 5457 40 159 - 2729 + 2728 @@ -9510,15 +9550,15 @@ fieldDeclaredIn - 399940 + 399793 fieldId - 399940 + 399793 fieldDeclId - 399940 + 399793 pos @@ -9536,7 +9576,7 @@ 1 2 - 399940 + 399793 @@ -9552,7 +9592,7 @@ 1 2 - 399940 + 399793 @@ -9568,7 +9608,7 @@ 1 2 - 399940 + 399793 @@ -9584,7 +9624,7 @@ 1 2 - 399940 + 399793 @@ -9626,27 +9666,27 @@ fields - 27583622 + 27573466 id - 27583622 + 27573466 nodeName - 10929437 + 10925412 typeid - 2735430 + 2734423 parentid - 3861543 + 3860121 sourceid - 27583622 + 27573466 @@ -9660,7 +9700,7 @@ 1 2 - 27583622 + 27573466 @@ -9676,7 +9716,7 @@ 1 2 - 27583622 + 27573466 @@ -9692,7 +9732,7 @@ 1 2 - 27583622 + 27573466 @@ -9708,7 +9748,7 @@ 1 2 - 27583622 + 27573466 @@ -9724,22 +9764,22 @@ 1 2 - 8083442 + 8080466 2 3 - 1437329 + 1436800 3 11 - 763026 + 762745 11 828 - 645638 + 645400 @@ -9755,17 +9795,17 @@ 1 2 - 9901603 + 9897957 2 4 - 853115 + 852801 4 160 - 174718 + 174653 @@ -9781,22 +9821,22 @@ 1 2 - 8083442 + 8080466 2 3 - 1437329 + 1436800 3 11 - 763026 + 762745 11 828 - 645638 + 645400 @@ -9812,22 +9852,22 @@ 1 2 - 8083442 + 8080466 2 3 - 1437329 + 1436800 3 11 - 763026 + 762745 11 828 - 645638 + 645400 @@ -9843,32 +9883,32 @@ 1 2 - 1737626 + 1736986 2 3 - 339881 + 339756 3 4 - 176083 + 176018 4 7 - 208842 + 208765 7 24 - 206112 + 206036 24 7479 - 66884 + 66859 @@ -9884,27 +9924,27 @@ 1 2 - 1900059 + 1899359 2 3 - 303026 + 302915 3 4 - 184273 + 184205 4 9 - 212937 + 212859 9 2335 - 135133 + 135083 @@ -9920,17 +9960,17 @@ 1 2 - 2332759 + 2331900 2 4 - 229317 + 229233 4 1392 - 173353 + 173289 @@ -9946,32 +9986,32 @@ 1 2 - 1737626 + 1736986 2 3 - 339881 + 339756 3 4 - 176083 + 176018 4 7 - 208842 + 208765 7 24 - 206112 + 206036 24 7479 - 66884 + 66859 @@ -9987,37 +10027,37 @@ 1 2 - 1942374 + 1941658 2 3 - 485934 + 485755 3 4 - 304391 + 304279 4 6 - 342611 + 342485 6 10 - 301661 + 301550 10 27 - 292106 + 291999 27 1610 - 192462 + 192392 @@ -10033,37 +10073,37 @@ 1 2 - 1942374 + 1941658 2 3 - 485934 + 485755 3 4 - 304391 + 304279 4 6 - 342611 + 342485 6 10 - 301661 + 301550 10 27 - 292106 + 291999 27 1610 - 192462 + 192392 @@ -10079,27 +10119,27 @@ 1 2 - 2506112 + 2505190 2 3 - 625163 + 624933 3 4 - 244332 + 244242 4 7 - 339881 + 339756 7 76 - 146053 + 145999 @@ -10115,37 +10155,37 @@ 1 2 - 1942374 + 1941658 2 3 - 485934 + 485755 3 4 - 304391 + 304279 4 6 - 342611 + 342485 6 10 - 301661 + 301550 10 27 - 292106 + 291999 27 1610 - 192462 + 192392 @@ -10161,7 +10201,7 @@ 1 2 - 27583622 + 27573466 @@ -10177,7 +10217,7 @@ 1 2 - 27583622 + 27573466 @@ -10193,7 +10233,7 @@ 1 2 - 27583622 + 27573466 @@ -10209,7 +10249,7 @@ 1 2 - 27583622 + 27573466 @@ -10219,11 +10259,11 @@ fieldsKotlinType - 27583622 + 27573466 id - 27583622 + 27573466 kttypeid @@ -10241,7 +10281,7 @@ 1 2 - 27583622 + 27573466 @@ -10267,31 +10307,31 @@ constrs - 6889080 + 6886544 id - 6889080 + 6886544 nodeName - 3756439 + 3755056 signature - 5887181 + 5885013 typeid - 2729 + 2728 parentid - 4849792 + 4848007 sourceid - 5069555 + 5067688 @@ -10305,7 +10345,7 @@ 1 2 - 6889080 + 6886544 @@ -10321,7 +10361,7 @@ 1 2 - 6889080 + 6886544 @@ -10337,7 +10377,7 @@ 1 2 - 6889080 + 6886544 @@ -10353,7 +10393,7 @@ 1 2 - 6889080 + 6886544 @@ -10369,7 +10409,7 @@ 1 2 - 6889080 + 6886544 @@ -10385,22 +10425,22 @@ 1 2 - 2366884 + 2366012 2 3 - 839465 + 839156 3 5 - 346706 + 346578 5 42 - 203382 + 203307 @@ -10416,22 +10456,22 @@ 1 2 - 2635786 + 2634816 2 3 - 685222 + 684970 3 5 - 303026 + 302915 5 19 - 132403 + 132354 @@ -10447,7 +10487,7 @@ 1 2 - 3756439 + 3755056 @@ -10463,17 +10503,17 @@ 1 2 - 3295074 + 3293861 2 3 - 316676 + 316559 3 42 - 144688 + 144635 @@ -10489,22 +10529,22 @@ 1 2 - 2458338 + 2457433 2 3 - 831276 + 830969 3 5 - 319406 + 319288 5 38 - 147418 + 147364 @@ -10520,12 +10560,12 @@ 1 2 - 5474955 + 5472940 2 42 - 412225 + 412073 @@ -10541,7 +10581,7 @@ 1 2 - 5887181 + 5885013 @@ -10557,7 +10597,7 @@ 1 2 - 5887181 + 5885013 @@ -10573,12 +10613,12 @@ 1 2 - 5474955 + 5472940 2 42 - 412225 + 412073 @@ -10594,12 +10634,12 @@ 1 2 - 5604629 + 5602565 2 32 - 282551 + 282447 @@ -10720,22 +10760,22 @@ 1 2 - 3688190 + 3686832 2 3 - 739822 + 739549 3 6 - 367181 + 367045 6 19 - 54599 + 54579 @@ -10751,7 +10791,7 @@ 1 2 - 4849792 + 4848007 @@ -10767,22 +10807,22 @@ 1 2 - 3688190 + 3686832 2 3 - 739822 + 739549 3 6 - 367181 + 367045 6 19 - 54599 + 54579 @@ -10798,7 +10838,7 @@ 1 2 - 4849792 + 4848007 @@ -10814,22 +10854,22 @@ 1 2 - 3688190 + 3686832 2 3 - 739822 + 739549 3 6 - 367181 + 367045 6 19 - 54599 + 54579 @@ -10845,12 +10885,12 @@ 1 2 - 4756973 + 4755222 2 259 - 312581 + 312466 @@ -10866,12 +10906,12 @@ 1 2 - 4756973 + 4755222 2 212 - 312581 + 312466 @@ -10887,12 +10927,12 @@ 1 2 - 4756973 + 4755222 2 212 - 312581 + 312466 @@ -10908,7 +10948,7 @@ 1 2 - 5069555 + 5067688 @@ -10924,12 +10964,12 @@ 1 2 - 4756973 + 4755222 2 259 - 312581 + 312466 @@ -10939,11 +10979,11 @@ constrsKotlinType - 6889080 + 6886544 id - 6889080 + 6886544 kttypeid @@ -10961,7 +11001,7 @@ 1 2 - 6889080 + 6886544 @@ -10987,31 +11027,31 @@ methods - 93482380 + 93447961 id - 93482380 + 93447961 nodeName - 20395609 + 20385371 signature - 29871337 + 29857610 typeid - 11611929 + 11610383 parentid - 11303442 + 11299281 sourceid - 58623387 + 58601802 @@ -11025,7 +11065,7 @@ 1 2 - 93482380 + 93447961 @@ -11041,7 +11081,7 @@ 1 2 - 93482380 + 93447961 @@ -11057,7 +11097,7 @@ 1 2 - 93482380 + 93447961 @@ -11073,7 +11113,7 @@ 1 2 - 93482380 + 93447961 @@ -11089,7 +11129,7 @@ 1 2 - 93482380 + 93447961 @@ -11105,32 +11145,32 @@ 1 2 - 11927241 + 11921485 2 3 - 3791929 + 3790532 3 4 - 1317210 + 1316725 4 7 - 1789495 + 1788836 7 - 259 - 1530148 + 271 + 1529585 - 270 + 276 2134 - 39584 + 38205 @@ -11146,17 +11186,17 @@ 1 2 - 16912167 + 16903211 2 3 - 2122552 + 2121770 3 361 - 1360890 + 1360389 @@ -11172,22 +11212,22 @@ 1 2 - 17141484 + 17133809 2 3 - 1683026 + 1682407 3 - 52 - 1530148 + 53 + 1529585 - 52 + 53 845 - 40949 + 39569 @@ -11203,27 +11243,27 @@ 1 2 - 12654778 + 12648754 2 3 - 3558516 + 3557206 3 4 - 1250326 + 1249866 4 7 - 1575192 + 1574613 7 1278 - 1356795 + 1354931 @@ -11239,27 +11279,27 @@ 1 2 - 12309437 + 12302175 2 3 - 3921602 + 3921523 3 4 - 1298100 + 1297623 4 7 - 1654362 + 1653753 7 928 - 1212106 + 1210296 @@ -11275,22 +11315,22 @@ 1 2 - 20522553 + 20513632 2 3 - 4879822 + 4878025 3 5 - 2368249 + 2367377 5 1275 - 2100712 + 2098574 @@ -11306,7 +11346,7 @@ 1 2 - 29871337 + 29857610 @@ -11322,17 +11362,17 @@ 1 2 - 26823325 + 26812084 2 5 - 2390089 + 2389209 5 843 - 657922 + 656316 @@ -11348,22 +11388,22 @@ 1 2 - 20526648 + 20517726 2 3 - 4878457 + 4876661 3 5 - 2366884 + 2366012 5 1275 - 2099347 + 2097209 @@ -11379,22 +11419,22 @@ 1 2 - 21147716 + 21137201 2 3 - 4997211 + 4996735 3 6 - 2537507 + 2536573 6 923 - 1188902 + 1187099 @@ -11410,32 +11450,32 @@ 1 2 - 5705638 + 5703537 2 3 - 2455608 + 2457433 3 4 - 1087893 + 1087492 4 6 - 924095 + 925119 6 14 - 877685 + 875997 14 11682 - 561008 + 560802 @@ -11451,22 +11491,22 @@ 1 2 - 7632997 + 7632916 2 3 - 2222196 + 2221377 3 6 - 1063323 + 1064296 6 3956 - 693412 + 691792 @@ -11482,27 +11522,27 @@ 1 2 - 7390030 + 7388673 2 3 - 2276795 + 2278686 3 5 - 879050 + 878726 5 17 - 884510 + 882820 17 5707 - 181543 + 181476 @@ -11518,27 +11558,27 @@ 1 2 - 6811276 + 6808768 2 3 - 2467893 + 2471078 3 4 - 1004629 + 1004259 4 9 - 917270 + 915567 9 3421 - 410860 + 410709 @@ -11554,32 +11594,32 @@ 1 2 - 6202493 + 6200209 2 3 - 2268605 + 2270499 3 4 - 984154 + 983792 4 6 - 909080 + 910109 6 16 - 892700 + 891007 16 8870 - 354896 + 354765 @@ -11595,52 +11635,52 @@ 1 2 - 3200890 + 3199711 2 3 - 1298100 + 1297623 3 4 - 1027833 + 1027455 4 5 - 748011 + 747736 5 7 - 925460 + 925119 7 10 - 959584 + 959231 10 13 - 997804 + 997436 13 19 - 909080 + 908745 19 38 - 910445 + 910109 38 319 - 326231 + 326111 @@ -11656,52 +11696,52 @@ 1 2 - 3254124 + 3252926 2 3 - 1318575 + 1318090 3 4 - 1108368 + 1107959 4 5 - 788961 + 788670 5 7 - 888605 + 888278 7 10 - 1021008 + 1020633 10 13 - 941839 + 942857 13 17 - 876320 + 874633 17 35 - 850385 + 850072 35 290 - 255252 + 255158 @@ -11717,52 +11757,52 @@ 1 2 - 3200890 + 3199711 2 3 - 1298100 + 1297623 3 4 - 1027833 + 1027455 4 5 - 748011 + 747736 5 7 - 925460 + 925119 7 10 - 959584 + 959231 10 13 - 997804 + 997436 13 19 - 909080 + 908745 19 38 - 910445 + 910109 38 319 - 326231 + 326111 @@ -11778,47 +11818,47 @@ 1 2 - 3901127 + 3899691 2 3 - 1624332 + 1623734 3 4 - 1329495 + 1329006 4 5 - 790326 + 790035 5 6 - 636083 + 635848 6 7 - 502314 + 502129 7 9 - 1034658 + 1034277 9 13 - 881780 + 881455 13 78 - 603323 + 603101 @@ -11834,52 +11874,52 @@ 1 2 - 3200890 + 3199711 2 3 - 1298100 + 1297623 3 4 - 1027833 + 1027455 4 5 - 748011 + 747736 5 7 - 925460 + 925119 7 10 - 959584 + 959231 10 13 - 997804 + 997436 13 19 - 909080 + 908745 19 38 - 910445 + 910109 38 319 - 326231 + 326111 @@ -11895,12 +11935,12 @@ 1 2 - 54259529 + 54239551 2 349 - 4363857 + 4362251 @@ -11916,7 +11956,7 @@ 1 2 - 58623387 + 58601802 @@ -11932,12 +11972,12 @@ 1 2 - 58339470 + 58317990 2 347 - 283916 + 283812 @@ -11953,12 +11993,12 @@ 1 2 - 56923980 + 56903021 2 259 - 1699406 + 1698780 @@ -11974,12 +12014,12 @@ 1 2 - 54259529 + 54239551 2 349 - 4363857 + 4362251 @@ -11989,11 +12029,11 @@ methodsKotlinType - 93482380 + 93447961 id - 93482380 + 93447961 kttypeid @@ -12011,7 +12051,7 @@ 1 2 - 93482380 + 93447961 @@ -12037,27 +12077,27 @@ params - 101137218 + 101099980 id - 101137218 + 101099980 typeid - 11278873 + 11198309 pos - 30029 + 30018 parentid - 56339766 + 56319023 sourceid - 61326058 + 61303478 @@ -12071,7 +12111,7 @@ 1 2 - 101137218 + 101099980 @@ -12087,7 +12127,7 @@ 1 2 - 101137218 + 101099980 @@ -12103,7 +12143,7 @@ 1 2 - 101137218 + 101099980 @@ -12119,7 +12159,7 @@ 1 2 - 101137218 + 101099980 @@ -12135,32 +12175,32 @@ 1 2 - 6038694 + 5955966 2 3 - 1756736 + 1720612 3 4 - 853115 + 873268 4 6 - 966409 + 974240 6 12 - 854480 + 866446 12 7464 - 809436 + 807773 @@ -12176,17 +12216,17 @@ 1 2 - 9331039 + 9255286 2 3 - 1156142 + 1159810 3 17 - 791691 + 783213 @@ -12202,32 +12242,32 @@ 1 2 - 6227062 + 6146994 2 3 - 1726706 + 1685136 3 4 - 873590 + 893736 4 6 - 909080 + 918296 6 13 - 854480 + 866446 13 5239 - 687952 + 687699 @@ -12243,32 +12283,32 @@ 1 2 - 6433175 + 6350302 2 3 - 1613412 + 1577341 3 4 - 884510 + 904652 4 6 - 943204 + 951044 6 - 14 - 889970 + 13 + 854166 - 14 + 13 6287 - 514599 + 560802 @@ -12284,57 +12324,57 @@ 1 2 - 2729 + 2728 53 56 - 2729 + 2728 110 112 - 2729 + 2728 165 172 - 2729 + 2728 224 242 - 2729 + 2728 304 329 - 2729 + 2728 523 665 - 2729 + 2728 879 1140 - 2729 + 2728 1514 2087 - 2729 + 2728 3295 5932 - 2729 + 2728 15024 41276 - 2729 + 2728 @@ -12350,57 +12390,57 @@ 1 2 - 2729 + 2728 2 5 - 2729 + 2728 6 7 - 2729 + 2728 10 12 - 2729 + 2728 13 19 - 2729 + 2728 26 38 - 2729 + 2728 57 76 - 2729 + 2728 99 159 - 2729 + 2728 212 - 305 - 2729 + 306 + 2728 - 451 + 452 888 - 2729 + 2728 - 2378 - 6326 - 2729 + 2370 + 6266 + 2728 @@ -12416,57 +12456,57 @@ 1 2 - 2729 + 2728 53 56 - 2729 + 2728 110 112 - 2729 + 2728 165 172 - 2729 + 2728 224 242 - 2729 + 2728 304 329 - 2729 + 2728 523 665 - 2729 + 2728 879 1140 - 2729 + 2728 1514 2087 - 2729 + 2728 3295 5932 - 2729 + 2728 15024 41276 - 2729 + 2728 @@ -12482,57 +12522,57 @@ 1 2 - 2729 + 2728 2 5 - 2729 + 2728 6 8 - 2729 + 2728 10 13 - 2729 + 2728 14 28 - 2729 + 2728 37 62 - 2729 + 2728 97 137 - 2729 + 2728 192 342 - 2729 + 2728 553 963 - 2729 + 2728 1950 4155 - 2729 + 2728 10027 26335 - 2729 + 2728 @@ -12548,27 +12588,27 @@ 1 2 - 35832228 + 35819035 2 3 - 12411811 + 12407241 3 4 - 3598101 + 3596776 4 15 - 4264213 + 4262643 15 23 - 233412 + 233326 @@ -12584,17 +12624,17 @@ 1 2 - 39830270 + 39815605 2 3 - 12671158 + 12666492 3 23 - 3838338 + 3836925 @@ -12610,27 +12650,27 @@ 1 2 - 35832228 + 35819035 2 3 - 12411811 + 12407241 3 4 - 3598101 + 3596776 4 15 - 4264213 + 4262643 15 23 - 233412 + 233326 @@ -12646,27 +12686,27 @@ 1 2 - 35832228 + 35819035 2 3 - 12411811 + 12407241 3 4 - 3598101 + 3596776 4 15 - 4264213 + 4262643 15 23 - 233412 + 233326 @@ -12682,12 +12722,12 @@ 1 2 - 56895315 + 56874367 2 349 - 4430742 + 4429110 @@ -12703,12 +12743,12 @@ 1 2 - 59783624 + 59761613 2 349 - 1542433 + 1541865 @@ -12724,7 +12764,7 @@ 1 2 - 61326058 + 61303478 @@ -12740,12 +12780,12 @@ 1 2 - 56895315 + 56874367 2 349 - 4430742 + 4429110 @@ -12755,11 +12795,11 @@ paramsKotlinType - 101137218 + 101099980 id - 101137218 + 101099980 kttypeid @@ -12777,7 +12817,7 @@ 1 2 - 101137218 + 101099980 @@ -12803,15 +12843,15 @@ paramName - 101137218 + 10199508 id - 101137218 + 10199508 nodeName - 1688486 + 1666033 @@ -12825,7 +12865,7 @@ 1 2 - 101137218 + 10199508 @@ -12841,37 +12881,37 @@ 1 2 - 719347 + 729998 2 3 - 331691 + 338391 3 4 - 173353 + 169195 4 5 - 114658 + 117345 5 9 - 144688 + 140541 9 25 - 126943 + 126896 25 - 32680 - 77804 + 516 + 43663 @@ -12881,11 +12921,11 @@ isVarargsParam - 1005994 + 1005623 param - 1005994 + 1005623 @@ -13108,11 +13148,11 @@ isAnnotType - 29833 + 30064 interfaceid - 29833 + 30064 @@ -13396,11 +13436,11 @@ isEnumType - 350801 + 350672 classid - 350801 + 350672 @@ -13418,19 +13458,19 @@ typeVars - 5118694 + 5116810 id - 5118694 + 5116810 nodeName - 70979 + 70953 pos - 5459 + 5457 kind @@ -13438,7 +13478,7 @@ parentid - 3725044 + 3723673 @@ -13452,7 +13492,7 @@ 1 2 - 5118694 + 5116810 @@ -13468,7 +13508,7 @@ 1 2 - 5118694 + 5116810 @@ -13484,7 +13524,7 @@ 1 2 - 5118694 + 5116810 @@ -13500,7 +13540,7 @@ 1 2 - 5118694 + 5116810 @@ -13516,47 +13556,47 @@ 1 2 - 20474 + 20467 2 3 - 10919 + 10915 3 4 - 6824 + 6822 4 7 - 5459 + 5457 7 10 - 5459 + 5457 10 28 - 5459 + 5457 37 71 - 5459 + 5457 71 253 - 5459 + 5457 459 951 - 5459 + 5457 @@ -13572,17 +13612,17 @@ 1 2 - 45044 + 45027 2 3 - 16379 + 16373 3 4 - 8189 + 8186 4 @@ -13603,7 +13643,7 @@ 1 2 - 70979 + 70953 @@ -13619,47 +13659,47 @@ 1 2 - 20474 + 20467 2 3 - 10919 + 10915 3 4 - 6824 + 6822 4 7 - 5459 + 5457 7 10 - 5459 + 5457 10 28 - 5459 + 5457 37 71 - 5459 + 5457 71 253 - 5459 + 5457 459 951 - 5459 + 5457 @@ -13737,7 +13777,7 @@ 1 2 - 5459 + 5457 @@ -13848,17 +13888,17 @@ 1 2 - 2467893 + 2466984 2 3 - 1128842 + 1128427 3 5 - 128308 + 128261 @@ -13874,17 +13914,17 @@ 1 2 - 2467893 + 2466984 2 3 - 1128842 + 1128427 3 5 - 128308 + 128261 @@ -13900,17 +13940,17 @@ 1 2 - 2467893 + 2466984 2 3 - 1128842 + 1128427 3 5 - 128308 + 128261 @@ -13926,7 +13966,7 @@ 1 2 - 3725044 + 3723673 @@ -13936,19 +13976,19 @@ wildcards - 3116261 + 3637710 id - 3116261 + 3637710 nodeName - 859940 + 982427 kind - 2729 + 2728 @@ -13962,7 +14002,7 @@ 1 2 - 3116261 + 3637710 @@ -13978,7 +14018,7 @@ 1 2 - 3116261 + 3637710 @@ -13994,17 +14034,17 @@ 1 2 - 683857 + 791399 2 3 - 110563 + 120074 3 - 170 - 65519 + 214 + 70953 @@ -14020,7 +14060,7 @@ 1 2 - 859940 + 982427 @@ -14034,13 +14074,13 @@ 12 - 898 - 899 + 1027 + 1028 1364 - 1385 - 1386 + 1639 + 1640 1364 @@ -14055,13 +14095,13 @@ 12 - 196 - 197 + 222 + 223 1364 - 434 - 435 + 498 + 499 1364 @@ -14072,15 +14112,15 @@ typeBounds - 3872463 + 4393634 id - 3872463 + 4393634 typeid - 2723145 + 3191525 pos @@ -14088,7 +14128,7 @@ parentid - 3872463 + 4393634 @@ -14102,7 +14142,7 @@ 1 2 - 3872463 + 4393634 @@ -14118,7 +14158,7 @@ 1 2 - 3872463 + 4393634 @@ -14134,7 +14174,7 @@ 1 2 - 3872463 + 4393634 @@ -14150,17 +14190,17 @@ 1 2 - 2093887 + 2512012 2 3 - 552819 + 603101 3 - 51 - 76439 + 52 + 76411 @@ -14176,7 +14216,7 @@ 1 2 - 2723145 + 3191525 @@ -14192,17 +14232,17 @@ 1 2 - 2093887 + 2512012 2 3 - 552819 + 603101 3 - 51 - 76439 + 52 + 76411 @@ -14216,8 +14256,8 @@ 12 - 2837 - 2838 + 3220 + 3221 1364 @@ -14232,8 +14272,8 @@ 12 - 1995 - 1996 + 2339 + 2340 1364 @@ -14248,8 +14288,8 @@ 12 - 2837 - 2838 + 3220 + 3221 1364 @@ -14266,7 +14306,7 @@ 1 2 - 3872463 + 4393634 @@ -14282,7 +14322,7 @@ 1 2 - 3872463 + 4393634 @@ -14298,7 +14338,7 @@ 1 2 - 3872463 + 4393634 @@ -14604,37 +14644,37 @@ isParameterized - 24792227 + 25167883 memberid - 24792227 + 25167883 isRaw - 642908 + 642671 memberid - 642908 + 642671 erasure - 25435135 + 25810554 memberid - 25435135 + 25810554 erasureid - 868130 + 867810 @@ -14648,7 +14688,7 @@ 1 2 - 25435135 + 25810554 @@ -14664,57 +14704,57 @@ 1 2 - 144688 + 144635 2 3 - 133768 + 133719 3 4 - 88724 + 88691 4 5 - 55964 + 54579 5 6 - 51869 + 50485 6 8 - 62789 + 64130 8 11 - 77804 + 79139 11 19 - 70979 + 70953 19 33 - 70979 + 70953 33 93 - 65519 + 65495 97 - 1723 - 45044 + 1848 + 45027 @@ -14724,15 +14764,15 @@ isAnonymClass - 194713 + 195608 classid - 194713 + 195608 parent - 194713 + 195608 @@ -14746,7 +14786,7 @@ 1 2 - 194713 + 195608 @@ -14762,7 +14802,7 @@ 1 2 - 194713 + 195608 @@ -14772,15 +14812,15 @@ isLocalClassOrInterface - 4069 + 4110 typeid - 4069 + 4110 parent - 4069 + 4110 @@ -14794,7 +14834,7 @@ 1 2 - 4069 + 4110 @@ -14810,7 +14850,7 @@ 1 2 - 4069 + 4110 @@ -14831,15 +14871,15 @@ lambdaKind - 185816 + 186985 exprId - 185816 + 186985 bodyKind - 15 + 16 @@ -14853,7 +14893,7 @@ 1 2 - 185816 + 186985 @@ -14867,9 +14907,9 @@ 12 - 11987 - 11988 - 15 + 11644 + 11645 + 16 @@ -14879,27 +14919,27 @@ arrays - 1119287 + 1118875 id - 1119287 + 1118875 nodeName - 689317 + 689063 elementtypeid - 1112462 + 1112053 dimension - 2729 + 2728 componenttypeid - 1119287 + 1118875 @@ -14913,7 +14953,7 @@ 1 2 - 1119287 + 1118875 @@ -14929,7 +14969,7 @@ 1 2 - 1119287 + 1118875 @@ -14945,7 +14985,7 @@ 1 2 - 1119287 + 1118875 @@ -14961,7 +15001,7 @@ 1 2 - 1119287 + 1118875 @@ -14977,17 +15017,17 @@ 1 2 - 563738 + 563531 2 3 - 99643 + 99607 3 95 - 25934 + 25925 @@ -15003,17 +15043,17 @@ 1 2 - 563738 + 563531 2 3 - 99643 + 99607 3 95 - 25934 + 25925 @@ -15029,7 +15069,7 @@ 1 2 - 689317 + 689063 @@ -15045,17 +15085,17 @@ 1 2 - 563738 + 563531 2 3 - 99643 + 99607 3 95 - 25934 + 25925 @@ -15071,12 +15111,12 @@ 1 2 - 1105638 + 1105230 2 3 - 6824 + 6822 @@ -15092,12 +15132,12 @@ 1 2 - 1105638 + 1105230 2 3 - 6824 + 6822 @@ -15113,12 +15153,12 @@ 1 2 - 1105638 + 1105230 2 3 - 6824 + 6822 @@ -15134,12 +15174,12 @@ 1 2 - 1105638 + 1105230 2 3 - 6824 + 6822 @@ -15239,7 +15279,7 @@ 1 2 - 1119287 + 1118875 @@ -15255,7 +15295,7 @@ 1 2 - 1119287 + 1118875 @@ -15271,7 +15311,7 @@ 1 2 - 1119287 + 1118875 @@ -15287,7 +15327,7 @@ 1 2 - 1119287 + 1118875 @@ -15297,15 +15337,15 @@ enclInReftype - 3417923 + 3419393 child - 3417923 + 3419393 parent - 928189 + 927848 @@ -15319,7 +15359,7 @@ 1 2 - 3417923 + 3419393 @@ -15335,32 +15375,32 @@ 1 2 - 545994 + 545793 2 3 - 150148 + 150093 3 4 - 70979 + 70953 4 7 - 83264 + 83233 7 48 - 69614 + 69588 50 - 277 - 8189 + 279 + 8186 @@ -15370,15 +15410,15 @@ extendsReftype - 47612051 + 47979305 id1 - 33730150 + 34102515 id2 - 13910564 + 14050078 @@ -15392,22 +15432,22 @@ 1 2 - 25830981 + 26206254 2 3 - 3150385 + 3149226 3 4 - 3643145 + 3641804 4 10 - 1105638 + 1105230 @@ -15423,17 +15463,17 @@ 1 2 - 11822137 + 11956961 2 3 - 1423679 + 1429977 3 - 12114 - 664747 + 12283 + 663138 @@ -15526,15 +15566,15 @@ permits - 125 + 143 id1 - 32 + 36 id2 - 125 + 143 @@ -15548,12 +15588,12 @@ 1 2 - 2 + 1 2 3 - 9 + 12 3 @@ -15563,27 +15603,27 @@ 4 5 - 1 + 2 5 6 - 4 + 2 6 + 7 + 4 + + + 7 8 2 8 - 9 - 2 - - - 10 11 - 1 + 2 @@ -15599,7 +15639,7 @@ 1 2 - 125 + 143 @@ -15609,15 +15649,15 @@ hasModifier - 248786309 + 249505212 id1 - 166367134 + 166690663 id2 - 12284 + 13644 @@ -15631,17 +15671,17 @@ 1 2 - 84399769 + 84359142 2 3 - 81515555 + 81848494 3 4 - 451810 + 483026 @@ -15654,6 +15694,11 @@ 12 + + 31 + 32 + 1364 + 34 35 @@ -15680,13 +15725,13 @@ 1364 - 17754 - 17755 + 18033 + 18034 1364 - 18275 - 18276 + 18277 + 18278 1364 @@ -15695,8 +15740,8 @@ 1364 - 116552 - 116553 + 116834 + 116835 1364 @@ -16038,27 +16083,27 @@ stmts - 2534777 + 2533844 id - 2534777 + 2533844 kind - 13649 + 13644 parent - 1785400 + 1784743 idx - 217032 + 216952 bodydecl - 704332 + 704073 @@ -16072,7 +16117,7 @@ 1 2 - 2534777 + 2533844 @@ -16088,7 +16133,7 @@ 1 2 - 2534777 + 2533844 @@ -16104,7 +16149,7 @@ 1 2 - 2534777 + 2533844 @@ -16120,7 +16165,7 @@ 1 2 - 2534777 + 2533844 @@ -16136,7 +16181,7 @@ 2 3 - 4094 + 4093 4 @@ -16192,7 +16237,7 @@ 2 3 - 2729 + 2728 4 @@ -16243,7 +16288,7 @@ 1 2 - 5459 + 5457 2 @@ -16263,7 +16308,7 @@ 7 8 - 2729 + 2728 158 @@ -16289,7 +16334,7 @@ 2 3 - 4094 + 4093 25 @@ -16335,17 +16380,17 @@ 1 2 - 1502848 + 1502295 2 3 - 199287 + 199214 3 159 - 83264 + 83233 @@ -16361,17 +16406,17 @@ 1 2 - 1588842 + 1588257 2 3 - 189732 + 189663 3 4 - 6824 + 6822 @@ -16387,17 +16432,17 @@ 1 2 - 1502848 + 1502295 2 3 - 199287 + 199214 3 159 - 83264 + 83233 @@ -16413,7 +16458,7 @@ 1 2 - 1785400 + 1784743 @@ -16429,22 +16474,22 @@ 1 2 - 161068 + 161008 2 3 - 34124 + 34112 3 24 - 16379 + 16373 34 1211 - 5459 + 5457 @@ -16460,12 +16505,12 @@ 1 2 - 204747 + 204672 2 9 - 12284 + 12280 @@ -16481,22 +16526,22 @@ 1 2 - 161068 + 161008 2 3 - 34124 + 34112 3 24 - 16379 + 16373 34 1211 - 5459 + 5457 @@ -16512,22 +16557,22 @@ 1 2 - 161068 + 161008 2 3 - 34124 + 34112 3 19 - 16379 + 16373 29 517 - 5459 + 5457 @@ -16543,22 +16588,22 @@ 2 3 - 544629 + 544428 3 4 - 58694 + 58672 4 7 - 53234 + 53214 7 162 - 47774 + 47756 @@ -16574,17 +16619,17 @@ 2 3 - 576023 + 575811 3 4 - 81899 + 81868 4 7 - 46409 + 46392 @@ -16600,17 +16645,17 @@ 2 3 - 630623 + 630391 3 8 - 57329 + 57308 9 47 - 16379 + 16373 @@ -16626,22 +16671,22 @@ 1 2 - 544629 + 544428 2 3 - 92818 + 92784 3 7 - 54599 + 54579 7 159 - 12284 + 12280 @@ -17522,7 +17567,7 @@ kttypeid - 12370 + 12368 @@ -17552,7 +17597,7 @@ 1 2 - 9277 + 9276 2 @@ -17560,8 +17605,8 @@ 2061 - 7177 - 7178 + 7178 + 7179 1030 @@ -17841,22 +17886,22 @@ when_if - 83447 + 84712 id - 83447 + 84712 when_branch_else - 80753 + 79813 id - 80753 + 79813 @@ -17901,12 +17946,12 @@ 1 2 - 162246 + 162245 2 3 - 33026 + 33027 3 @@ -17999,15 +18044,15 @@ propertyRefGetBinding - 9718 + 9660 id - 9718 + 9660 getter - 5873 + 5838 @@ -18021,7 +18066,7 @@ 1 2 - 9718 + 9660 @@ -18037,12 +18082,12 @@ 1 2 - 2132 + 2119 2 3 - 3646 + 3624 3 @@ -18105,15 +18150,15 @@ propertyRefSetBinding - 2651 + 2672 id - 2651 + 2672 setter - 1325 + 1336 @@ -18127,7 +18172,7 @@ 1 2 - 2651 + 2672 @@ -18143,7 +18188,7 @@ 2 3 - 1325 + 1336 @@ -18602,11 +18647,11 @@ localvarsKotlinType - 227623 + 227573 id - 227623 + 227573 kttypeid @@ -18624,7 +18669,7 @@ 1 2 - 227623 + 227573 @@ -20540,11 +20585,11 @@ xmlEncoding - 802611 + 802315 id - 802611 + 802315 encoding @@ -20562,7 +20607,7 @@ 1 2 - 802611 + 802315 @@ -20936,27 +20981,27 @@ xmlElements - 106792352 + 106753032 id - 106792352 + 106753032 name - 338516 + 338391 parentid - 2754540 + 2753526 idx - 1210741 + 1210296 fileid - 802611 + 802315 @@ -20970,7 +21015,7 @@ 1 2 - 106792352 + 106753032 @@ -20986,7 +21031,7 @@ 1 2 - 106792352 + 106753032 @@ -21002,7 +21047,7 @@ 1 2 - 106792352 + 106753032 @@ -21018,7 +21063,7 @@ 1 2 - 106792352 + 106753032 @@ -21034,57 +21079,57 @@ 1 2 - 106468 + 106429 2 3 - 40949 + 40934 3 4 - 16379 + 16373 4 6 - 30029 + 30018 6 8 - 24569 + 24560 8 9 - 12284 + 12280 9 10 - 23204 + 23196 10 18 - 28664 + 28654 18 48 - 25934 + 25925 52 250 - 25934 + 25925 342 73380 - 4094 + 4093 @@ -21100,52 +21145,52 @@ 1 2 - 124213 + 124167 2 3 - 46409 + 46392 3 4 - 17744 + 17738 4 5 - 15014 + 15009 5 6 - 19109 + 19102 6 8 - 28664 + 28654 8 10 - 28664 + 28654 10 21 - 27299 + 27289 22 128 - 25934 + 25925 130 229 - 5459 + 5457 @@ -21161,37 +21206,37 @@ 1 2 - 187002 + 186934 2 3 - 49139 + 49121 3 4 - 24569 + 24560 4 6 - 20474 + 20467 6 9 - 20474 + 20467 9 38 - 25934 + 25925 45 888 - 10919 + 10915 @@ -21207,42 +21252,42 @@ 1 2 - 184273 + 184205 2 3 - 36854 + 36841 3 4 - 17744 + 17738 4 5 - 13649 + 13644 5 7 - 30029 + 30018 7 16 - 25934 + 25925 17 114 - 27299 + 27289 118 131 - 2729 + 2728 @@ -21258,32 +21303,32 @@ 1 2 - 1676201 + 1675584 2 3 - 429970 + 429812 3 4 - 178813 + 178747 4 8 - 214302 + 214223 8 777 - 225222 + 225139 777 888 - 30029 + 30018 @@ -21299,17 +21344,17 @@ 1 2 - 2274065 + 2273228 2 3 - 292106 + 291999 3 17 - 188367 + 188298 @@ -21325,32 +21370,32 @@ 1 2 - 1676201 + 1675584 2 3 - 429970 + 429812 3 4 - 178813 + 178747 4 8 - 214302 + 214223 8 777 - 225222 + 225139 777 888 - 30029 + 30018 @@ -21366,7 +21411,7 @@ 1 2 - 2754540 + 2753526 @@ -21382,67 +21427,67 @@ 2 8 - 102373 + 102336 9 76 - 96913 + 96878 76 82 - 91454 + 91420 82 89 - 87359 + 87326 89 92 - 79169 + 79139 92 95 - 95548 + 95513 95 97 - 106468 + 106429 97 98 - 150148 + 150093 98 99 - 92818 + 92784 99 104 - 110563 + 110523 104 106 - 92818 + 92784 106 159 - 91454 + 91420 162 2019 - 13649 + 13644 @@ -21458,22 +21503,22 @@ 1 2 - 981424 + 981063 2 5 - 90089 + 90055 5 9 - 103738 + 103700 9 150 - 35489 + 35476 @@ -21489,67 +21534,67 @@ 2 8 - 102373 + 102336 9 76 - 96913 + 96878 76 82 - 91454 + 91420 82 89 - 87359 + 87326 89 92 - 79169 + 79139 92 95 - 95548 + 95513 95 97 - 106468 + 106429 97 98 - 150148 + 150093 98 99 - 92818 + 92784 99 104 - 110563 + 110523 104 106 - 92818 + 92784 106 159 - 91454 + 91420 162 2019 - 13649 + 13644 @@ -21565,67 +21610,67 @@ 2 8 - 102373 + 102336 9 76 - 96913 + 96878 76 82 - 91454 + 91420 82 89 - 87359 + 87326 89 92 - 79169 + 79139 92 95 - 95548 + 95513 95 97 - 106468 + 106429 97 98 - 150148 + 150093 98 99 - 92818 + 92784 99 104 - 110563 + 110523 104 106 - 92818 + 92784 106 139 - 91454 + 91420 141 589 - 13649 + 13644 @@ -21641,57 +21686,57 @@ 1 2 - 58694 + 58672 2 3 - 135133 + 135083 3 4 - 177448 + 177382 4 5 - 75074 + 75046 5 7 - 60059 + 60037 7 10 - 66884 + 66859 10 31 - 62789 + 62766 35 694 - 61424 + 61401 738 776 - 20474 + 20467 777 779 - 65519 + 65495 788 889 - 19109 + 19102 @@ -21707,37 +21752,37 @@ 1 2 - 58694 + 58672 2 3 - 399940 + 399793 3 4 - 139228 + 139177 4 5 - 65519 + 65495 5 6 - 61424 + 61401 6 9 - 65519 + 65495 9 69 - 12284 + 12280 @@ -21753,27 +21798,27 @@ 1 2 - 58694 + 58672 2 3 - 569198 + 568989 3 4 - 57329 + 57308 4 6 - 58694 + 58672 6 165 - 58694 + 58672 @@ -21789,42 +21834,42 @@ 1 2 - 203382 + 203307 2 3 - 219762 + 219681 3 4 - 88724 + 88691 4 7 - 66884 + 66859 7 17 - 66884 + 66859 18 763 - 61424 + 61401 764 777 - 65519 + 65495 777 888 - 30029 + 30018 @@ -21834,31 +21879,31 @@ xmlAttrs - 129898822 + 129850995 id - 129898822 + 129850995 elementid - 105883272 + 105844287 name - 513234 + 513045 value - 8206291 + 8203269 idx - 31394 + 31383 fileid - 801246 + 800951 @@ -21872,7 +21917,7 @@ 1 2 - 129898822 + 129850995 @@ -21888,7 +21933,7 @@ 1 2 - 129898822 + 129850995 @@ -21904,7 +21949,7 @@ 1 2 - 129898822 + 129850995 @@ -21920,7 +21965,7 @@ 1 2 - 129898822 + 129850995 @@ -21936,7 +21981,7 @@ 1 2 - 129898822 + 129850995 @@ -21952,17 +21997,17 @@ 1 2 - 96893479 + 96857804 2 6 - 7961959 + 7959027 6 24 - 1027833 + 1027455 @@ -21978,17 +22023,17 @@ 1 2 - 96893479 + 96857804 2 6 - 7975608 + 7972672 6 23 - 1014184 + 1013810 @@ -22004,17 +22049,17 @@ 1 2 - 96946713 + 96911018 2 6 - 8015193 + 8012242 6 21 - 921365 + 921025 @@ -22030,17 +22075,17 @@ 1 2 - 96893479 + 96857804 2 6 - 7961959 + 7959027 6 24 - 1027833 + 1027455 @@ -22056,7 +22101,7 @@ 1 2 - 105883272 + 105844287 @@ -22072,62 +22117,62 @@ 1 2 - 106468 + 106429 2 3 - 55964 + 55943 3 4 - 31394 + 31383 4 5 - 17744 + 17738 5 6 - 30029 + 30018 6 8 - 36854 + 36841 8 11 - 42314 + 42298 11 22 - 39584 + 39569 23 38 - 40949 + 40934 38 79 - 40949 + 40934 81 168 - 39584 + 39569 168 74700 - 31394 + 31383 @@ -22143,62 +22188,62 @@ 1 2 - 106468 + 106429 2 3 - 55964 + 55943 3 4 - 31394 + 31383 4 5 - 17744 + 17738 5 6 - 30029 + 30018 6 8 - 36854 + 36841 8 11 - 46409 + 46392 11 25 - 43679 + 43663 25 39 - 42314 + 42298 43 91 - 40949 + 40934 91 227 - 39584 + 39569 227 74700 - 21839 + 21831 @@ -22214,42 +22259,42 @@ 1 2 - 215667 + 215588 2 3 - 80534 + 80504 3 4 - 34124 + 34112 4 5 - 36854 + 36841 5 9 - 42314 + 42298 9 21 - 39584 + 39569 22 64 - 42314 + 42298 68 2100 - 21839 + 21831 @@ -22265,37 +22310,37 @@ 1 2 - 202017 + 201943 2 3 - 95548 + 95513 3 4 - 49139 + 49121 4 5 - 54599 + 54579 5 7 - 32759 + 32747 7 10 - 40949 + 40934 10 21 - 38219 + 38205 @@ -22311,52 +22356,52 @@ 1 2 - 178813 + 178747 2 3 - 53234 + 53214 3 4 - 27299 + 27289 4 5 - 24569 + 24560 5 6 - 38219 + 38205 6 9 - 42314 + 42298 9 17 - 45044 + 45027 17 34 - 39584 + 39569 36 91 - 39584 + 39569 91 223 - 24569 + 24560 @@ -22372,32 +22417,32 @@ 1 2 - 4482611 + 4480961 2 3 - 1213471 + 1213025 3 5 - 629258 + 629026 5 31 - 618338 + 618110 31 91 - 645638 + 645400 91 1111 - 615608 + 615381 3397 @@ -22418,32 +22463,32 @@ 1 2 - 4572700 + 4571017 2 3 - 1156142 + 1155716 3 5 - 637448 + 637213 5 33 - 647003 + 646764 33 93 - 633353 + 633119 93 3398 - 559643 + 559437 @@ -22459,17 +22504,17 @@ 1 2 - 7447359 + 7444617 2 4 - 660652 + 660409 4 53 - 98278 + 98242 @@ -22485,17 +22530,17 @@ 1 2 - 6796261 + 6793759 2 3 - 992344 + 991978 3 20 - 417685 + 417531 @@ -22511,32 +22556,32 @@ 1 2 - 5282492 + 5280548 2 3 - 889970 + 889642 3 10 - 637448 + 637213 10 83 - 623798 + 623568 83 99 - 626528 + 626297 99 182 - 146053 + 145999 @@ -22552,57 +22597,57 @@ 1 6 - 2729 + 2728 12 14 - 2729 + 2728 17 26 - 2729 + 2728 39 56 - 2729 + 2728 83 110 - 2729 + 2728 153 232 - 2729 + 2728 316 400 - 2729 + 2728 468 545 - 2729 + 2728 626 754 - 2729 + 2728 951 1491 - 2729 + 2728 4718 6587 - 2729 + 2728 77571 @@ -22623,57 +22668,57 @@ 1 6 - 2729 + 2728 12 14 - 2729 + 2728 17 26 - 2729 + 2728 39 56 - 2729 + 2728 83 110 - 2729 + 2728 153 232 - 2729 + 2728 316 400 - 2729 + 2728 468 545 - 2729 + 2728 626 754 - 2729 + 2728 951 1491 - 2729 + 2728 4718 6587 - 2729 + 2728 77571 @@ -22694,57 +22739,57 @@ 1 4 - 2729 + 2728 7 10 - 2729 + 2728 11 17 - 2729 + 2728 18 23 - 2729 + 2728 26 38 - 2729 + 2728 39 49 - 2729 + 2728 57 67 - 2729 + 2728 72 79 - 2729 + 2728 95 101 - 2729 + 2728 105 106 - 2729 + 2728 106 132 - 2729 + 2728 140 @@ -22765,57 +22810,57 @@ 1 5 - 2729 + 2728 7 10 - 2729 + 2728 11 18 - 2729 + 2728 22 32 - 2729 + 2728 46 63 - 2729 + 2728 85 119 - 2729 + 2728 142 185 - 2729 + 2728 212 228 - 2729 + 2728 253 275 - 2729 + 2728 307 423 - 2729 + 2728 580 1324 - 2729 + 2728 3579 @@ -22836,57 +22881,57 @@ 1 6 - 2729 + 2728 7 8 - 2729 + 2728 10 19 - 2729 + 2728 23 36 - 2729 + 2728 45 59 - 2729 + 2728 73 97 - 2729 + 2728 115 131 - 2729 + 2728 140 148 - 2729 + 2728 168 181 - 2729 + 2728 248 363 - 2729 + 2728 473 530 - 2729 + 2728 587 @@ -22907,72 +22952,72 @@ 1 3 - 60059 + 60037 3 5 - 61424 + 61401 5 6 - 36854 + 36841 6 7 - 61424 + 61401 7 8 - 51869 + 51850 8 10 - 58694 + 58672 10 15 - 65519 + 65495 15 27 - 61424 + 61401 27 41 - 61424 + 61401 41 65 - 61424 + 61401 65 157 - 65519 + 65495 162 817 - 61424 + 61401 818 832 - 66884 + 66859 832 1187 - 27299 + 27289 @@ -22988,52 +23033,52 @@ 1 2 - 91454 + 91420 2 3 - 188367 + 188298 3 4 - 113293 + 113252 4 5 - 77804 + 77775 5 8 - 72344 + 72317 8 14 - 61424 + 61401 14 295 - 61424 + 61401 330 775 - 50504 + 50485 776 778 - 65519 + 65495 787 888 - 19109 + 19102 @@ -23049,62 +23094,62 @@ 1 2 - 50504 + 50485 2 3 - 65519 + 65495 3 4 - 50504 + 50485 4 5 - 66884 + 66859 5 6 - 121483 + 121438 6 7 - 114658 + 114616 7 8 - 50504 + 50485 8 12 - 61424 + 61401 12 18 - 69614 + 69588 18 24 - 68249 + 68224 24 37 - 62789 + 62766 37 55 - 19109 + 19102 @@ -23120,67 +23165,67 @@ 1 3 - 69614 + 69588 3 4 - 39584 + 39569 4 5 - 73709 + 73682 5 6 - 88724 + 88691 6 8 - 62789 + 62766 8 12 - 70979 + 70953 12 19 - 61424 + 61401 19 27 - 69614 + 69588 27 41 - 61424 + 61401 42 170 - 61424 + 61401 205 780 - 57329 + 57308 781 783 - 65519 + 65495 791 893 - 19109 + 19102 @@ -23196,47 +23241,47 @@ 1 2 - 79169 + 79139 2 3 - 76439 + 76411 3 4 - 151513 + 151457 4 5 - 155608 + 155551 5 6 - 92818 + 92784 6 10 - 68249 + 68224 10 12 - 46409 + 46392 12 15 - 69614 + 69588 15 24 - 61424 + 61401 @@ -23246,23 +23291,23 @@ xmlNs - 1287181 + 1286707 id - 8189 + 8186 prefixName - 9554 + 9551 URI - 8189 + 8186 fileid - 749376 + 749100 @@ -23276,7 +23321,7 @@ 1 2 - 6824 + 6822 2 @@ -23297,7 +23342,7 @@ 1 2 - 8189 + 8186 @@ -23354,7 +23399,7 @@ 1 2 - 9554 + 9551 @@ -23370,7 +23415,7 @@ 1 2 - 9554 + 9551 @@ -23432,7 +23477,7 @@ 1 2 - 8189 + 8186 @@ -23448,7 +23493,7 @@ 1 2 - 6824 + 6822 2 @@ -23510,17 +23555,17 @@ 1 2 - 334421 + 334298 2 3 - 292106 + 291999 3 4 - 122848 + 122803 @@ -23536,17 +23581,17 @@ 1 2 - 334421 + 334298 2 3 - 292106 + 291999 3 4 - 122848 + 122803 @@ -23562,17 +23607,17 @@ 1 2 - 334421 + 334298 2 3 - 292106 + 291999 3 4 - 122848 + 122803 @@ -23582,19 +23627,19 @@ xmlHasNs - 25966114 + 25956554 elementId - 25966114 + 25956554 nsId - 8189 + 8186 fileid - 745281 + 745007 @@ -23608,7 +23653,7 @@ 1 2 - 25966114 + 25956554 @@ -23624,7 +23669,7 @@ 1 2 - 25966114 + 25956554 @@ -23722,77 +23767,77 @@ 1 3 - 45044 + 45027 3 5 - 62789 + 62766 5 6 - 34124 + 34112 6 7 - 65519 + 65495 7 8 - 49139 + 49121 8 10 - 61424 + 61401 10 15 - 65519 + 65495 15 25 - 55964 + 55943 25 36 - 57329 + 57308 36 49 - 58694 + 58672 49 54 - 15014 + 15009 54 55 - 58694 + 58672 55 81 - 57329 + 57308 81 298 - 55964 + 55943 298 833 - 2729 + 2728 @@ -23808,17 +23853,17 @@ 1 2 - 335786 + 335662 2 3 - 289376 + 289270 3 4 - 120118 + 120074 @@ -23828,23 +23873,23 @@ xmlComments - 107485764 + 107446189 id - 107485764 + 107446189 text - 1696676 + 1696051 parentid - 842195 + 841885 fileid - 787596 + 787306 @@ -23858,7 +23903,7 @@ 1 2 - 107485764 + 107446189 @@ -23874,7 +23919,7 @@ 1 2 - 107485764 + 107446189 @@ -23890,7 +23935,7 @@ 1 2 - 107485764 + 107446189 @@ -23906,67 +23951,67 @@ 1 2 - 233412 + 233326 2 7 - 139228 + 139177 7 32 - 140593 + 140541 32 61 - 128308 + 128261 61 76 - 128308 + 128261 76 84 - 136498 + 136448 84 90 - 125578 + 125532 90 94 - 111928 + 111887 94 95 - 60059 + 60037 95 96 - 101008 + 100971 96 98 - 140593 + 140541 98 100 - 126943 + 126896 100 460 - 124213 + 124167 @@ -23982,67 +24027,67 @@ 1 2 - 236142 + 236055 2 6 - 135133 + 135083 6 32 - 143323 + 143270 32 61 - 129673 + 129625 61 75 - 132403 + 132354 75 84 - 148783 + 148728 84 90 - 122848 + 122803 90 94 - 120118 + 120074 94 95 - 66884 + 66859 95 96 - 103738 + 103700 96 98 - 143323 + 143270 98 100 - 135133 + 135083 100 460 - 79169 + 79139 @@ -24058,67 +24103,67 @@ 1 2 - 247062 + 246971 2 7 - 133768 + 133719 7 32 - 133768 + 133719 32 61 - 129673 + 129625 61 75 - 132403 + 132354 75 84 - 148783 + 148728 84 90 - 122848 + 122803 90 94 - 120118 + 120074 94 95 - 66884 + 66859 95 96 - 103738 + 103700 96 98 - 143323 + 143270 98 100 - 135133 + 135083 100 460 - 79169 + 79139 @@ -24134,22 +24179,22 @@ 1 2 - 670207 + 669961 2 724 - 64154 + 64130 726 830 - 77804 + 77775 831 941 - 30029 + 30018 @@ -24165,27 +24210,27 @@ 1 2 - 670207 + 669961 2 697 - 64154 + 64130 697 795 - 34124 + 34112 795 827 - 64154 + 64130 838 899 - 9554 + 9551 @@ -24201,7 +24246,7 @@ 1 2 - 842195 + 841885 @@ -24217,27 +24262,27 @@ 1 2 - 601958 + 601736 2 549 - 60059 + 60037 579 829 - 40949 + 40934 829 832 - 65519 + 65495 834 941 - 19109 + 19102 @@ -24253,27 +24298,27 @@ 1 2 - 601958 + 601736 2 536 - 60059 + 60037 560 795 - 51869 + 51850 795 812 - 60059 + 60037 819 899 - 13649 + 13644 @@ -24289,12 +24334,12 @@ 1 2 - 748011 + 747736 2 6 - 39584 + 39569 @@ -24304,19 +24349,19 @@ xmlChars - 101574013 + 101536615 id - 101574013 + 101536615 text - 78006178 + 77977457 parentid - 101574013 + 101536615 idx @@ -24324,11 +24369,11 @@ isCDATA - 2729 + 2728 fileid - 177448 + 177382 @@ -24342,7 +24387,7 @@ 1 2 - 101574013 + 101536615 @@ -24358,7 +24403,7 @@ 1 2 - 101574013 + 101536615 @@ -24374,7 +24419,7 @@ 1 2 - 101574013 + 101536615 @@ -24390,7 +24435,7 @@ 1 2 - 101574013 + 101536615 @@ -24406,7 +24451,7 @@ 1 2 - 101574013 + 101536615 @@ -24422,17 +24467,17 @@ 1 2 - 66746414 + 66721839 2 3 - 7010564 + 7007983 3 128 - 4249199 + 4247634 @@ -24448,17 +24493,17 @@ 1 2 - 66746414 + 66721839 2 3 - 7010564 + 7007983 3 128 - 4249199 + 4247634 @@ -24474,7 +24519,7 @@ 1 2 - 78006178 + 77977457 @@ -24490,7 +24535,7 @@ 1 2 - 78006178 + 77977457 @@ -24506,12 +24551,12 @@ 1 2 - 74636029 + 74608549 2 76 - 3370148 + 3368907 @@ -24527,7 +24572,7 @@ 1 2 - 101574013 + 101536615 @@ -24543,7 +24588,7 @@ 1 2 - 101574013 + 101536615 @@ -24559,7 +24604,7 @@ 1 2 - 101574013 + 101536615 @@ -24575,7 +24620,7 @@ 1 2 - 101574013 + 101536615 @@ -24591,7 +24636,7 @@ 1 2 - 101574013 + 101536615 @@ -24750,7 +24795,7 @@ 1 2 - 2729 + 2728 @@ -24787,57 +24832,57 @@ 1 2 - 15014 + 15009 2 23 - 13649 + 13644 24 243 - 13649 + 13644 294 566 - 13649 + 13644 610 686 - 13649 + 13644 691 764 - 13649 + 13644 765 775 - 13649 + 13644 775 776 - 4094 + 4093 776 777 - 49139 + 49121 777 803 - 13649 + 13644 807 888 - 13649 + 13644 @@ -24853,67 +24898,67 @@ 1 2 - 15014 + 15009 2 21 - 13649 + 13644 22 188 - 13649 + 13644 208 492 - 13649 + 13644 525 589 - 13649 + 13644 590 638 - 13649 + 13644 639 651 - 13649 + 13644 652 656 - 12284 + 12280 656 659 - 16379 + 16373 659 663 - 15014 + 15009 663 667 - 13649 + 13644 667 701 - 13649 + 13644 702 744 - 9554 + 9551 @@ -24929,57 +24974,57 @@ 1 2 - 15014 + 15009 2 23 - 13649 + 13644 24 243 - 13649 + 13644 294 566 - 13649 + 13644 610 686 - 13649 + 13644 691 764 - 13649 + 13644 765 775 - 13649 + 13644 775 776 - 4094 + 4093 776 777 - 49139 + 49121 777 803 - 13649 + 13644 807 888 - 13649 + 13644 @@ -24995,7 +25040,7 @@ 1 2 - 177448 + 177382 @@ -25011,12 +25056,12 @@ 1 2 - 43679 + 43663 2 3 - 133768 + 133719 @@ -25026,15 +25071,15 @@ xmllocations - 447840746 + 447675856 xmlElement - 446561755 + 446397336 location - 419653800 + 419499288 @@ -25048,12 +25093,12 @@ 1 2 - 446553565 + 446389149 2 454 - 8189 + 8186 @@ -25069,12 +25114,12 @@ 1 2 - 410141218 + 409990208 2 25 - 9512582 + 9509079 @@ -25315,19 +25360,19 @@ ktComments - 133768 + 133719 id - 133768 + 133719 kind - 4094 + 4093 text - 96913 + 96878 @@ -25341,7 +25386,7 @@ 1 2 - 133768 + 133719 @@ -25357,7 +25402,7 @@ 1 2 - 133768 + 133719 @@ -25425,12 +25470,12 @@ 1 2 - 92818 + 92784 4 23 - 4094 + 4093 @@ -25446,7 +25491,7 @@ 1 2 - 96913 + 96878 @@ -25456,19 +25501,19 @@ ktCommentSections - 59246 + 59191 id - 59246 + 59191 comment - 54224 + 54069 content - 50410 + 50263 @@ -25482,7 +25527,7 @@ 1 2 - 59246 + 59191 @@ -25498,7 +25543,7 @@ 1 2 - 59246 + 59191 @@ -25514,12 +25559,12 @@ 1 2 - 52208 + 52013 2 18 - 2015 + 2055 @@ -25535,12 +25580,12 @@ 1 2 - 52208 + 52013 2 18 - 2015 + 2055 @@ -25556,17 +25601,17 @@ 1 2 - 44628 + 44482 2 3 - 4836 + 4801 3 63 - 945 + 979 @@ -25582,17 +25627,17 @@ 1 2 - 44737 + 44594 2 3 - 4743 + 4705 3 56 - 930 + 963 @@ -25602,15 +25647,15 @@ ktCommentSectionNames - 5022 + 5122 id - 5022 + 5122 name - 15 + 16 @@ -25624,7 +25669,7 @@ 1 2 - 5022 + 5122 @@ -25638,9 +25683,9 @@ 12 - 324 - 325 - 15 + 319 + 320 + 16 @@ -25650,15 +25695,15 @@ ktCommentSectionSubjectNames - 5022 + 5122 id - 5022 + 5122 subjectname - 3301 + 3388 @@ -25672,7 +25717,7 @@ 1 2 - 5022 + 5122 @@ -25688,22 +25733,22 @@ 1 2 - 2511 + 2601 2 3 - 496 + 497 3 - 9 - 248 + 10 + 256 - 10 - 15 - 46 + 13 + 16 + 32 @@ -25713,15 +25758,15 @@ ktCommentOwners - 84203 + 82540 id - 53480 + 53314 owner - 82173 + 80437 @@ -25735,22 +25780,22 @@ 1 2 - 34335 + 34638 2 3 - 12184 + 12076 3 4 - 4526 + 4496 4 6 - 2433 + 2103 @@ -25766,12 +25811,12 @@ 1 2 - 80142 + 78333 2 3 - 2030 + 2103 @@ -25781,15 +25826,15 @@ ktExtensionFunctions - 702967 + 702708 id - 702967 + 702708 typeid - 84629 + 84597 kttypeid @@ -25807,7 +25852,7 @@ 1 2 - 702967 + 702708 @@ -25823,7 +25868,7 @@ 1 2 - 702967 + 702708 @@ -25839,12 +25884,12 @@ 1 2 - 53234 + 53214 2 3 - 6824 + 6822 3 @@ -25854,22 +25899,22 @@ 4 5 - 6824 + 6822 5 12 - 6824 + 6822 12 69 - 6824 + 6822 84 174 - 2729 + 2728 @@ -25885,7 +25930,7 @@ 1 2 - 84629 + 84597 @@ -25927,15 +25972,15 @@ ktProperties - 30317687 + 30306525 id - 30317687 + 30306525 nodeName - 10696024 + 10692086 @@ -25949,7 +25994,7 @@ 1 2 - 30317687 + 30306525 @@ -25965,22 +26010,22 @@ 1 2 - 7889614 + 7886709 2 3 - 1216201 + 1215754 3 8 - 809436 + 809138 8 554 - 780771 + 780484 @@ -25990,15 +26035,15 @@ ktPropertyGetters - 4569970 + 4568288 id - 4569970 + 4568288 getter - 4569970 + 4568288 @@ -26012,7 +26057,7 @@ 1 2 - 4569970 + 4568288 @@ -26028,7 +26073,7 @@ 1 2 - 4569970 + 4568288 @@ -26038,15 +26083,15 @@ ktPropertySetters - 290741 + 290634 id - 290741 + 290634 setter - 290741 + 290634 @@ -26060,7 +26105,7 @@ 1 2 - 290741 + 290634 @@ -26076,7 +26121,7 @@ 1 2 - 290741 + 290634 @@ -26086,15 +26131,15 @@ ktPropertyBackingFields - 23615610 + 23606915 id - 23615610 + 23606915 backingField - 23615610 + 23606915 @@ -26108,7 +26153,7 @@ 1 2 - 23615610 + 23606915 @@ -26124,7 +26169,7 @@ 1 2 - 23615610 + 23606915 @@ -26134,11 +26179,11 @@ ktSyntheticBody - 10308 + 10307 id - 10308 + 10307 kind @@ -26156,7 +26201,7 @@ 1 2 - 10308 + 10307 @@ -26182,37 +26227,37 @@ ktLocalFunction - 2729 + 2728 id - 2729 + 2728 ktInitializerAssignment - 393115 + 392971 id - 393115 + 392971 ktPropertyDelegates - 5698 + 5664 id - 5698 + 5664 variableId - 5698 + 5664 @@ -26226,7 +26271,7 @@ 1 2 - 5698 + 5664 @@ -26242,7 +26287,7 @@ 1 2 - 5698 + 5664 @@ -26252,15 +26297,15 @@ compiler_generated - 120 + 491650 id - 120 + 491650 kind - 2 + 5153 @@ -26274,7 +26319,7 @@ 1 2 - 120 + 491650 @@ -26288,9 +26333,29 @@ 12 - 42 - 43 - 2 + 2 + 3 + 1030 + + + 5 + 6 + 1030 + + + 10 + 11 + 1030 + + + 184 + 185 + 1030 + + + 276 + 277 + 1030 @@ -26300,15 +26365,15 @@ ktFunctionOriginalNames - 981424 + 1147529 id - 981424 + 1147529 name - 66884 + 79139 @@ -26322,7 +26387,7 @@ 1 2 - 981424 + 1147529 @@ -26338,22 +26403,27 @@ 1 2 - 53234 + 55943 2 - 3 - 5459 + 4 + 6822 - 3 - 96 - 5459 + 7 + 14 + 4093 - 96 + 16 + 31 + 6822 + + + 92 380 - 2729 + 5457 diff --git a/java/ql/src/definitions.qll b/java/ql/lib/definitions.qll similarity index 100% rename from java/ql/src/definitions.qll rename to java/ql/lib/definitions.qll diff --git a/java/ql/src/localDefinitions.ql b/java/ql/lib/localDefinitions.ql similarity index 100% rename from java/ql/src/localDefinitions.ql rename to java/ql/lib/localDefinitions.ql diff --git a/java/ql/src/localReferences.ql b/java/ql/lib/localReferences.ql similarity index 100% rename from java/ql/src/localReferences.ql rename to java/ql/lib/localReferences.ql diff --git a/java/ql/src/printAst.ql b/java/ql/lib/printAst.ql similarity index 100% rename from java/ql/src/printAst.ql rename to java/ql/lib/printAst.ql diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 0eb686d7f94..0de218dcd22 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.3.0-dev +version: 0.3.2-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/lib/semmle/code/Location.qll b/java/ql/lib/semmle/code/Location.qll index d977395a83c..8bb81becb11 100755 --- a/java/ql/lib/semmle/code/Location.qll +++ b/java/ql/lib/semmle/code/Location.qll @@ -47,6 +47,8 @@ predicate hasName(Element e, string name) { kt_type_alias(e, name, _) or ktProperties(e, name) + or + e instanceof ErrorType and name = "" } /** diff --git a/java/ql/lib/semmle/code/java/Element.qll b/java/ql/lib/semmle/code/java/Element.qll index dbf2efc71b5..96c8a8c5c21 100755 --- a/java/ql/lib/semmle/code/java/Element.qll +++ b/java/ql/lib/semmle/code/java/Element.qll @@ -57,6 +57,12 @@ class Element extends @element, Top { i = 4 and result = "Class initialisation method " or i = 5 and result = "Enum class special member" + or + i = 6 and result = "Getter for a Kotlin delegated property" + or + i = 7 and result = "Setter for a Kotlin delegated property" + or + i = 8 and result = "Proxy static method for a @JvmStatic-annotated function or property" ) } } diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index 48023e135af..2c969a8d442 100755 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -100,6 +100,18 @@ class Expr extends ExprParent, @expr { /** Holds if this expression is parenthesized. */ predicate isParenthesized() { isParenthesized(this, _) } + + /** + * Gets the underlying expression looking through casts and not-nulls, if any. + * Otherwise just gets this expression. + */ + Expr getUnderlyingExpr() { + if this instanceof CastingExpr or this instanceof NotNullExpr + then + result = this.(CastingExpr).getExpr().getUnderlyingExpr() or + result = this.(NotNullExpr).getExpr().getUnderlyingExpr() + else result = this + } } /** diff --git a/java/ql/lib/semmle/code/java/Modifier.qll b/java/ql/lib/semmle/code/java/Modifier.qll index d3971e42e59..8f947383d1e 100755 --- a/java/ql/lib/semmle/code/java/Modifier.qll +++ b/java/ql/lib/semmle/code/java/Modifier.qll @@ -58,6 +58,9 @@ abstract class Modifiable extends Element { /** Holds if this element has an `internal` modifier. */ predicate isInternal() { this.hasModifier("internal") } + /** Holds if this element has an `inline` modifier. */ + predicate isInline() { this.hasModifier("inline") } + /** Holds if this element has a `volatile` modifier. */ predicate isVolatile() { this.hasModifier("volatile") } diff --git a/java/ql/lib/semmle/code/java/PrintAst.qll b/java/ql/lib/semmle/code/java/PrintAst.qll index 05453baa045..9d88550faa3 100644 --- a/java/ql/lib/semmle/code/java/PrintAst.qll +++ b/java/ql/lib/semmle/code/java/PrintAst.qll @@ -534,10 +534,12 @@ final class ClassInterfaceNode extends ElementNode { or childIndex >= 0 and result.(ElementNode).getElement() = - rank[childIndex](Element e, string file, int line, int column | - e = this.getADeclaration() and locationSortKeys(e, file, line, column) + rank[childIndex](Element e, string file, int line, int column, string childStr | + e = this.getADeclaration() and + locationSortKeys(e, file, line, column) and + childStr = e.toString() | - e order by file, line, column + e order by file, line, column, childStr ) } } diff --git a/java/ql/lib/semmle/code/java/Type.qll b/java/ql/lib/semmle/code/java/Type.qll index a37f9810c44..2e83c31f26a 100755 --- a/java/ql/lib/semmle/code/java/Type.qll +++ b/java/ql/lib/semmle/code/java/Type.qll @@ -413,8 +413,12 @@ class RefType extends Type, Annotatable, Modifiable, @reftype { /** Gets a direct or indirect supertype of this type, including itself. */ RefType getAnAncestor() { hasDescendant(result, this) } - /** Gets a direct or indirect supertype of this type, not including itself. */ - RefType getAStrictAncestor() { result = this.getAnAncestor() and result != this } + /** + * Gets a direct or indirect supertype of this type. + * This does not including itself, unless this type is part of a cycle + * in the type hierarchy. + */ + RefType getAStrictAncestor() { result = this.getASupertype().getAnAncestor() } /** * Gets the source declaration of a direct supertype of this type, excluding itself. @@ -666,6 +670,14 @@ class RefType extends Type, Annotatable, Modifiable, @reftype { } } +/** + * An `ErrorType` is generated when CodeQL is unable to correctly + * extract a type. + */ +class ErrorType extends RefType, @errortype { + override string getAPrimaryQlClass() { result = "ErrorType" } +} + /** A type that is the same as its source declaration. */ class SrcRefType extends RefType { SrcRefType() { this.isSourceDeclaration() } diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index db1b5a61ef6..e8c1034a83a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -84,6 +84,7 @@ 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 @@ -646,7 +647,7 @@ module CsvValidation { or exists(string row, string kind | sourceModel(row) | kind = row.splitAt(";", 7) and - not kind = ["remote", "contentprovider", "android-widget"] and + not kind = ["remote", "contentprovider", "android-widget", "android-external-storage-dir"] and not kind.matches("qltest%") and msg = "Invalid kind \"" + kind + "\" in source model." ) diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index 2c44d7a15b6..fcd4fe90b6d 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -17,6 +17,7 @@ import semmle.code.java.frameworks.android.WebView import semmle.code.java.frameworks.JaxWS import semmle.code.java.frameworks.javase.WebSocket import semmle.code.java.frameworks.android.Android +import semmle.code.java.frameworks.android.ExternalStorage import semmle.code.java.frameworks.android.OnActivityResultSource import semmle.code.java.frameworks.android.Intent import semmle.code.java.frameworks.play.Play @@ -152,6 +153,12 @@ private class ThriftIfaceParameterSource extends RemoteFlowSource { override string getSourceType() { result = "Thrift Iface parameter" } } +private class AndroidExternalStorageSource extends RemoteFlowSource { + AndroidExternalStorageSource() { androidExternalStorageSource(this) } + + override string getSourceType() { result = "Android external storage" } +} + /** Class for `tainted` user input. */ abstract class UserInput extends DataFlow::Node { } 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 0f5d5e39f39..6c4a369527c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -241,8 +241,29 @@ private class ContainerFlowSummaries extends SummaryModelCsv { "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;Scanner;true;next;(Pattern);;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;next;(String);;Argument[-1];ReturnValue;taint;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;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", 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } 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 7b9e78d2c4b..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/frameworks/Assertions.qll b/java/ql/lib/semmle/code/java/frameworks/Assertions.qll index 3c3d090b993..ff95c71b037 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Assertions.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Assertions.qll @@ -2,7 +2,8 @@ * A library providing uniform access to various assertion frameworks. * * Currently supports `org.junit.Assert`, `junit.framework.*`, - * `com.google.common.base.Preconditions`, and `java.util.Objects`. + * `org.junit.jupiter.api.Assertions`, `com.google.common.base.Preconditions`, + * and `java.util.Objects`. */ import java @@ -17,7 +18,11 @@ private newtype AssertKind = private predicate assertionMethod(Method m, AssertKind kind) { exists(RefType junit | m.getDeclaringType() = junit and - (junit.hasQualifiedName("org.junit", "Assert") or junit.hasQualifiedName("junit.framework", _)) + ( + junit.hasQualifiedName("org.junit", "Assert") or + junit.hasQualifiedName("junit.framework", _) or + junit.hasQualifiedName("org.junit.jupiter.api", "Assertions") + ) | m.hasName("assertNotNull") and kind = AssertKindNotNull() or diff --git a/java/ql/lib/semmle/code/java/frameworks/Properties.qll b/java/ql/lib/semmle/code/java/frameworks/Properties.qll index 7b749a13e05..0c7b83b2e52 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Properties.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Properties.qll @@ -10,13 +10,11 @@ class TypeProperty extends Class { } /** The `getProperty` method of the class `java.util.Properties`. */ -class PropertiesGetPropertyMethod extends ValuePreservingMethod { +class PropertiesGetPropertyMethod extends Method { PropertiesGetPropertyMethod() { getDeclaringType() instanceof TypeProperty and hasName("getProperty") } - - override predicate returnsValue(int arg) { arg = 1 } } /** The `get` method of the class `java.util.Properties`. */ diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll new file mode 100644 index 00000000000..1e6919c023b --- /dev/null +++ b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll @@ -0,0 +1,50 @@ +/** Provides definitions for working with uses of Android external storage */ + +import java +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 + exists(ConstructorCall c | c.getConstructedType() instanceof TypeFile | + node1.asExpr() = c.getArgument(0) and + node2.asExpr() = c + ) + or + node2.asExpr().(ArrayAccess).getArray() = node1.asExpr() + or + node2.asExpr().(FieldRead).getField().getInitializer() = node1.asExpr() +} + +private predicate externalStorageFlow(DataFlow::Node node1, DataFlow::Node node2) { + externalStorageFlowStep*(node1, node2) +} + +/** + * Holds if `n` is a node that reads the contents of an external file in Android. + * This is controllable by third-party applications, so is treated as a remote flow source. + */ +predicate androidExternalStorageSource(DataFlow::Node n) { + exists(DataFlow::Node externalDir, DirectFileReadExpr read | + sourceNode(externalDir, "android-external-storage-dir") and + n.asExpr() = read and + externalStorageFlow(externalDir, DataFlow::exprNode(read.getFileExpr())) + ) +} diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll index 30a8ffc3a12..e67a2d1aa21 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll @@ -51,7 +51,7 @@ private predicate sharedPreferencesInput(DataFlow::Node editor, Expr input) { exists(MethodAccess m | m.getMethod() instanceof PutSharedPreferenceMethod and input = m.getArgument(1) and - editor.asExpr() = m.getQualifier() + editor.asExpr() = m.getQualifier().getUnderlyingExpr() ) } @@ -61,7 +61,7 @@ private predicate sharedPreferencesInput(DataFlow::Node editor, Expr input) { */ private predicate sharedPreferencesStore(DataFlow::Node editor, MethodAccess m) { m.getMethod() instanceof StoreSharedPreferenceMethod and - editor.asExpr() = m.getQualifier() + editor.asExpr() = m.getQualifier().getUnderlyingExpr() } /** Flow from `SharedPreferences.Editor` to either a setter or a store method. */ diff --git a/java/ql/lib/semmle/code/java/security/FileReadWrite.qll b/java/ql/lib/semmle/code/java/security/FileReadWrite.qll index e79f98bdca4..84be71d6a04 100644 --- a/java/ql/lib/semmle/code/java/security/FileReadWrite.qll +++ b/java/ql/lib/semmle/code/java/security/FileReadWrite.qll @@ -1,9 +1,9 @@ import java /** - * Holds if `fileAccess` is used in the `fileReadingExpr` to read the represented file. + * Holds if `fileAccess` is directly used in the `fileReadingExpr` to read the represented file. */ -private predicate fileRead(VarAccess fileAccess, Expr fileReadingExpr) { +private predicate directFileRead(Expr fileAccess, Expr fileReadingExpr) { // `fileAccess` used to construct a class that reads a file. exists(ClassInstanceExpr cie | cie = fileReadingExpr and @@ -28,6 +28,13 @@ private predicate fileRead(VarAccess fileAccess, Expr fileReadingExpr) { ]) ) ) +} + +/** + * Holds if `fileAccess` is used in the `fileReadingExpr` to read the represented file. + */ +private predicate fileRead(VarAccess fileAccess, Expr fileReadingExpr) { + directFileRead(fileAccess, fileReadingExpr) or // The `fileAccess` is used in a call which directly or indirectly accesses the file. exists(Call call, int parameterPos, VarAccess nestedFileAccess, Expr nestedFileReadingExpr | @@ -49,3 +56,15 @@ class FileReadExpr extends Expr { */ VarAccess getFileVarAccess() { fileRead(result, this) } } + +/** + * An expression that directly reads from a file and returns its contents. + */ +class DirectFileReadExpr extends Expr { + DirectFileReadExpr() { directFileRead(_, this) } + + /** + * Gets the `Expr` representing the file that is read. + */ + Expr getFileExpr() { directFileRead(result, this) } +} diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll new file mode 100644 index 00000000000..00a6dae69e9 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -0,0 +1,79 @@ +/** Definitions for the improper intent verification query. */ + +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.xml.AndroidManifest +import semmle.code.java.frameworks.android.Intent + +/** An `onReceive` method of a `BroadcastReceiver` */ +private class OnReceiveMethod extends Method { + OnReceiveMethod() { this.getASourceOverriddenMethod*() instanceof AndroidReceiveIntentMethod } + + /** Gets the parameter of this method that holds the received `Intent`. */ + Parameter getIntentParameter() { result = this.getParameter(1) } +} + +/** A configuration to detect whether the `action` of an `Intent` is checked. */ +private class VerifiedIntentConfig extends DataFlow::Configuration { + VerifiedIntentConfig() { this = "VerifiedIntentConfig" } + + override predicate isSource(DataFlow::Node src) { + src.asParameter() = any(OnReceiveMethod orm).getIntentParameter() + } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma | + ma.getMethod().hasQualifiedName("android.content", "Intent", "getAction") and + sink.asExpr() = ma.getQualifier() + ) + } +} + +/** An `onReceive` method that doesn't verify the action of the intent it receives. */ +private class UnverifiedOnReceiveMethod extends OnReceiveMethod { + UnverifiedOnReceiveMethod() { + not any(VerifiedIntentConfig c).hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _) + } +} + +/** Gets the name of an intent action that can only be sent by the system. */ +string getASystemActionName() { + result = + [ + "AIRPLANE_MODE", "AIRPLANE_MODE_CHANGED", "APPLICATION_LOCALE_CHANGED", + "APPLICATION_RESTRICTIONS_CHANGED", "BATTERY_CHANGED", "BATTERY_LOW", "BATTERY_OKAY", + "BOOT_COMPLETED", "CONFIGURATION_CHANGED", "DEVICE_STORAGE_LOW", "DEVICE_STORAGE_OK", + "DREAMING_STARTED", "DREAMING_STOPPED", "EXTERNAL_APPLICATIONS_AVAILABLE", + "EXTERNAL_APPLICATIONS_UNAVAILABLE", "LOCALE_CHANGED", "LOCKED_BOOT_COMPLETED", + "MY_PACKAGE_REPLACED", "MY_PACKAGE_SUSPENDED", "MY_PACKAGE_UNSUSPENDED", "NEW_OUTGOING_CALL", + "PACKAGES_SUSPENDED", "PACKAGES_UNSUSPENDED", "PACKAGE_ADDED", "PACKAGE_CHANGED", + "PACKAGE_DATA_CLEARED", "PACKAGE_FIRST_LAUNCH", "PACKAGE_FULLY_REMOVED", "PACKAGE_INSTALL", + "PACKAGE_NEEDS_VERIFICATION", "PACKAGE_REMOVED", "PACKAGE_REPLACED", "PACKAGE_RESTARTED", + "PACKAGE_VERIFIED", "POWER_CONNECTED", "POWER_DISCONNECTED", "REBOOT", "SCREEN_OFF", + "SCREEN_ON", "SHUTDOWN", "TIMEZONE_CHANGED", "TIME_TICK", "UID_REMOVED", "USER_PRESENT" + ] +} + +/** An expression or XML attribute that contains the name of a system intent action. */ +class SystemActionName extends AndroidActionXmlElement { + string name; + + SystemActionName() { + name = getASystemActionName() and + this.getActionName() = "android.intent.action." + name + } + + /** Gets the name of the system intent that this expression or attribute represents. */ + string getSystemActionName() { result = name } +} + +/** Holds if the XML element `rec` declares a receiver `orm` to receive the system action named `sa` that doesn't verify intents it receives. */ +predicate unverifiedSystemReceiver( + AndroidReceiverXmlElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa +) { + exists(Class ormty | + ormty = orm.getDeclaringType() and + rec.getComponentName() = ["." + ormty.getName(), ormty.getQualifiedName()] and + rec.getAnIntentFilterElement().getAnActionElement() = sa + ) +} diff --git a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll index 176b093b68a..ba162ede986 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll @@ -75,6 +75,8 @@ private predicate webViewLoadUrl(Argument urlArg, WebViewRef webview) { loadUrl.getArgument(0) = urlArg and loadUrl.getMethod() instanceof WebViewLoadUrlMethod | + webview.getAnAccess() = DataFlow::exprNode(loadUrl.getQualifier().getUnderlyingExpr()) + or webview.getAnAccess() = DataFlow::getInstanceArgument(loadUrl) or // `webview` is received as a parameter of an event method in a custom `WebViewClient`, @@ -82,8 +84,9 @@ private predicate webViewLoadUrl(Argument urlArg, WebViewRef webview) { exists(WebViewClientEventMethod eventMethod, MethodAccess setWebClient | setWebClient.getMethod() instanceof WebViewSetWebViewClientMethod and setWebClient.getArgument(0).getType() = eventMethod.getDeclaringType() and - loadUrl.getQualifier() = eventMethod.getWebViewParameter().getAnAccess() + loadUrl.getQualifier().getUnderlyingExpr() = eventMethod.getWebViewParameter().getAnAccess() | + webview.getAnAccess() = DataFlow::exprNode(setWebClient.getQualifier().getUnderlyingExpr()) or webview.getAnAccess() = DataFlow::getInstanceArgument(setWebClient) ) ) diff --git a/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/old.dbscheme b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/old.dbscheme new file mode 100644 index 00000000000..cf58c7d9b1f --- /dev/null +++ b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/old.dbscheme @@ -0,0 +1,1228 @@ +/** + * 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 +); + +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; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | + @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 ; + +@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 +) diff --git a/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/semmlecode.dbscheme b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/semmlecode.dbscheme new file mode 100755 index 00000000000..81ccfabe82e --- /dev/null +++ b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/semmlecode.dbscheme @@ -0,0 +1,1236 @@ +/** + * 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 ; + +@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 +) diff --git a/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/upgrade.properties b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/upgrade.properties new file mode 100644 index 00000000000..25c651f591b --- /dev/null +++ b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/upgrade.properties @@ -0,0 +1,2 @@ +description: Add errortype +compatibility: full diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 4e3bacee693..b39e648bf04 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,21 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/java-all` package. + +### New Queries + +* A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added. + This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered + to receive system intents. + +## 0.2.0 + +### Minor Analysis Improvements + +* The query `java/log-injection` now reports problems at the source (user-controlled data) instead of at the ultimate logging call. This was changed because user functions that wrap the ultimate logging call could result in most alerts being reported in an uninformative location. + ## 0.1.4 ## 0.1.3 diff --git a/java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml b/java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml new file mode 100644 index 00000000000..f9e11a1ee81 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-925/Bad.java b/java/ql/src/Security/CWE/CWE-925/Bad.java new file mode 100644 index 00000000000..376805f824e --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-925/Bad.java @@ -0,0 +1,7 @@ +public class ShutdownReceiver extends BroadcastReceiver { + @Override + public void onReceive(final Context context, final Intent intent) { + mainActivity.saveLocalData(); + mainActivity.stopActivity(); + } +} \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-925/Good.java b/java/ql/src/Security/CWE/CWE-925/Good.java new file mode 100644 index 00000000000..b6ad1c43193 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-925/Good.java @@ -0,0 +1,10 @@ +public class ShutdownReceiver extends BroadcastReceiver { + @Override + public void onReceive(final Context context, final Intent intent) { + if (!intent.getAction().equals(Intent.ACTION_SHUTDOWN)) { + return; + } + mainActivity.saveLocalData(); + mainActivity.stopActivity(); + } +} \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp new file mode 100644 index 00000000000..e489e411379 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp @@ -0,0 +1,40 @@ + + + + + +

    +When an Android application uses a BroadcastReceiver to receive intents, +it is also able to receive explicit intents that are sent directly to it, regardless of its filter. + +Certain intent actions are only able to be sent by the operating system, not third-party applications. +However, a BroadcastReceiver that is registered to receive system intents is still able to receive +intents from a third-party application, so it should check that the intent received has the expected action. +Otherwise, a third-party application could impersonate the system this way to cause unintended behavior, such as a denial of service. +

    +
    + + +

    In the following code, the ShutdownReceiver initiates a shutdown procedure upon receiving an intent, + without checking that the received action is indeed ACTION_SHUTDOWN. This allows third-party applications to + send explicit intents to this receiver to cause a denial of service.

    + + +
    + + +

    +In the onReceive method of a BroadcastReciever, the action of the received Intent should be checked. The following code demonstrates this. +

    + +
    + + + + + + + +
    diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql new file mode 100644 index 00000000000..51c54e288ac --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql @@ -0,0 +1,19 @@ +/** + * @name Improper verification of intent by broadcast receiver + * @description A broadcast receiver that does not verify intents it receives may be susceptible to unintended behavior by third party applications sending it explicit intents. + * @kind problem + * @problem.severity warning + * @security-severity 8.2 + * @precision high + * @id java/improper-intent-verification + * @tags security + * external/cwe/cwe-925 + */ + +import java +import semmle.code.java.security.ImproperIntentVerificationQuery + +from AndroidReceiverXmlElement reg, Method orm, SystemActionName sa +where unverifiedSystemReceiver(reg, orm, sa) +select orm, "This reciever doesn't verify intents it receives, and is registered $@ to receive $@.", + reg, "here", sa, "the system action " + sa.getName() diff --git a/java/ql/src/change-notes/2022-06-22-log-injection-location.md b/java/ql/src/change-notes/released/0.2.0.md similarity index 86% rename from java/ql/src/change-notes/2022-06-22-log-injection-location.md rename to java/ql/src/change-notes/released/0.2.0.md index b74f7d5faf9..2deabd93b15 100644 --- a/java/ql/src/change-notes/2022-06-22-log-injection-location.md +++ b/java/ql/src/change-notes/released/0.2.0.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.2.0 + +### Minor Analysis Improvements + * The query `java/log-injection` now reports problems at the source (user-controlled data) instead of at the ultimate logging call. This was changed because user functions that wrap the ultimate logging call could result in most alerts being reported in an uninformative location. diff --git a/java/ql/src/change-notes/released/0.3.0.md b/java/ql/src/change-notes/released/0.3.0.md new file mode 100644 index 00000000000..d91c653a471 --- /dev/null +++ b/java/ql/src/change-notes/released/0.3.0.md @@ -0,0 +1,11 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/java-all` package. + +### New Queries + +* A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added. + This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered + to receive system intents. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index e8ee3af8ef9..95f6e3a0ba6 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.3.0 diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java new file mode 100644 index 00000000000..83157c14251 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java @@ -0,0 +1,46 @@ + +// BAD: Using an outdated SDK that does not support client side encryption version V2_0 +new EncryptedBlobClientBuilder() + .blobClient(blobClient) + .key(resolver.buildAsyncKeyEncryptionKey(keyid).block(), keyWrapAlgorithm) + .buildEncryptedBlobClient() + .uploadWithResponse(new BlobParallelUploadOptions(data) + .setMetadata(metadata) + .setHeaders(headers) + .setTags(tags) + .setTier(tier) + .setRequestConditions(requestConditions) + .setComputeMd5(computeMd5) + .setParallelTransferOptions(parallelTransferOptions), + timeout, context); + +// BAD: Using the deprecatedd client side encryption version V1_0 +new EncryptedBlobClientBuilder(EncryptionVersion.V1) + .blobClient(blobClient) + .key(resolver.buildAsyncKeyEncryptionKey(keyid).block(), keyWrapAlgorithm) + .buildEncryptedBlobClient() + .uploadWithResponse(new BlobParallelUploadOptions(data) + .setMetadata(metadata) + .setHeaders(headers) + .setTags(tags) + .setTier(tier) + .setRequestConditions(requestConditions) + .setComputeMd5(computeMd5) + .setParallelTransferOptions(parallelTransferOptions), + timeout, context); + + +// GOOD: Using client side encryption version V2_0 +new EncryptedBlobClientBuilder(EncryptionVersion.V2) + .blobClient(blobClient) + .key(resolver.buildAsyncKeyEncryptionKey(keyid).block(), keyWrapAlgorithm) + .buildEncryptedBlobClient() + .uploadWithResponse(new BlobParallelUploadOptions(data) + .setMetadata(metadata) + .setHeaders(headers) + .setTags(tags) + .setTier(tier) + .setRequestConditions(requestConditions) + .setComputeMd5(computeMd5) + .setParallelTransferOptions(parallelTransferOptions), + timeout, context); diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp new file mode 100644 index 00000000000..b6884aed914 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -0,0 +1,29 @@ + + + + + +

    Azure Storage .NET, Java, and Python SDKs support encryption on the client with a customer-managed key that is maintained in Azure Key Vault or another key store.

    +

    The Azure Storage SDK version 12.18.0 or later supports version V2 for client-side encryption. All previous versions of Azure Storage SDK only support client-side encryption V1 which is unsafe.

    + +
    + + +

    Consider switching to V2 client-side encryption.

    + +
    + + + + + + +
  • + Azure Storage Client Encryption Blog. +
  • +
  • + CVE-2022-30187 +
  • + +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql new file mode 100644 index 00000000000..287a3f07a6c --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -0,0 +1,92 @@ +/** + * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-30187). + * @description Unsafe usage of v1 version of Azure Storage client-side encryption, please refer to http://aka.ms/azstorageclientencryptionblog + * @kind problem + * @tags security + * cryptography + * external/cwe/cwe-327 + * @id java/azure-storage/unsafe-client-side-encryption-in-use + * @problem.severity error + * @precision high + */ + +import java +import semmle.code.java.dataflow.DataFlow + +/** + * Holds if `call` is an object creation for a class `EncryptedBlobClientBuilder` + * that takes no arguments, which means that it is using V1 encryption. + */ +predicate isCreatingOutdatedAzureClientSideEncryptionObject(Call call, Class c) { + exists(string package, string type, Constructor constructor | + c.hasQualifiedName(package, type) and + c.getAConstructor() = constructor and + call.getCallee() = constructor and + ( + type = "EncryptedBlobClientBuilder" and + package = "com.azure.storage.blob.specialized.cryptography" and + constructor.hasNoParameters() + or + type = "BlobEncryptionPolicy" and package = "com.microsoft.azure.storage.blob" + ) + ) +} + +/** + * Holds if `call` is an object creation for a class `EncryptedBlobClientBuilder` + * that takes `versionArg` as the argument specifying the encryption version. + */ +predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c, Expr versionArg) { + exists(string package, string type, Constructor constructor | + c.hasQualifiedName(package, type) and + c.getAConstructor() = constructor and + call.getCallee() = constructor and + type = "EncryptedBlobClientBuilder" and + package = "com.azure.storage.blob.specialized.cryptography" and + versionArg = call.getArgument(0) + ) +} + +/** + * A dataflow config that tracks `EncryptedBlobClientBuilder.version` argument initialization. + */ +private class EncryptedBlobClientBuilderSafeEncryptionVersionConfig extends DataFlow::Configuration { + EncryptedBlobClientBuilderSafeEncryptionVersionConfig() { + this = "EncryptedBlobClientBuilderSafeEncryptionVersionConfig" + } + + override predicate isSource(DataFlow::Node source) { + exists(FieldRead fr, Field f | fr = source.asExpr() | + f.getAnAccess() = fr and + f.hasQualifiedName("com.azure.storage.blob.specialized.cryptography", "EncryptionVersion", + "V2") + ) + } + + override predicate isSink(DataFlow::Node sink) { + isCreatingAzureClientSideEncryptionObjectNewVersion(_, _, sink.asExpr()) + } +} + +/** + * Holds if `call` is an object creation for a class `EncryptedBlobClientBuilder` + * that takes `versionArg` as the argument specifying the encryption version, and that version is safe. + */ +predicate isCreatingSafeAzureClientSideEncryptionObject(Call call, Class c, Expr versionArg) { + isCreatingAzureClientSideEncryptionObjectNewVersion(call, c, versionArg) and + exists(EncryptedBlobClientBuilderSafeEncryptionVersionConfig config, DataFlow::Node sink | + sink.asExpr() = versionArg + | + config.hasFlow(_, sink) + ) +} + +from Expr e, Class c +where + exists(Expr argVersion | + isCreatingAzureClientSideEncryptionObjectNewVersion(e, c, argVersion) and + not isCreatingSafeAzureClientSideEncryptionObject(e, c, argVersion) + ) + or + isCreatingOutdatedAzureClientSideEncryptionObject(e, c) +select e, "Unsafe usage of v1 version of Azure Storage client-side encryption." diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index e9a69afa178..9cd3341f443 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.2.0-dev +version: 0.3.1-dev groups: - java - queries diff --git a/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll b/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll index 5233f92f406..e61d3dabe70 100644 --- a/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll +++ b/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll @@ -20,3 +20,15 @@ private class KtExpectationComment extends KtComment, ExpectationComment { override string getContents() { result = this.getText().suffix(2).trim() } } + +private class XmlExpectationComment extends ExpectationComment instanceof XMLComment { + override string getContents() { result = this.(XMLComment).getText().trim() } + + override Location getLocation() { result = this.(XMLComment).getLocation() } + + override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { + this.(XMLComment).hasLocationInfo(path, sl, sc, el, ec) + } + + override string toString() { result = this.(XMLComment).toString() } +} diff --git a/java/ql/test/kotlin/library-tests/classes/PrintAst.expected b/java/ql/test/kotlin/library-tests/classes/PrintAst.expected index 0346a4e0292..1ba8a3396bf 100644 --- a/java/ql/test/kotlin/library-tests/classes/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/classes/PrintAst.expected @@ -32,7 +32,7 @@ classes.kt: # 4| 0: [ReturnStmt] return ... # 4| 0: [VarAccess] this.arg # 4| -1: [ThisAccess] this -# 4| 2: [FieldDeclaration] int arg; +# 4| 3: [FieldDeclaration] int arg; # 4| -1: [TypeAccess] int # 4| 0: [VarAccess] arg # 5| 4: [Method] getX @@ -41,7 +41,7 @@ classes.kt: # 5| 0: [ReturnStmt] return ... # 5| 0: [VarAccess] this.x # 5| -1: [ThisAccess] this -# 5| 4: [FieldDeclaration] int x; +# 5| 5: [FieldDeclaration] int x; # 5| -1: [TypeAccess] int # 5| 0: [IntegerLiteral] 3 # 8| 4: [Class] ClassThree @@ -118,18 +118,18 @@ classes.kt: # 42| 0: [ReturnStmt] return ... # 42| 0: [VarAccess] this.x # 42| -1: [ThisAccess] this -# 42| 2: [FieldDeclaration] int x; +# 42| 3: [FieldDeclaration] int x; # 42| -1: [TypeAccess] int # 42| 0: [IntegerLiteral] 3 # 49| 11: [Class] Direction -# 0| 1: [Method] values -# 0| 3: [TypeAccess] Direction[] -# 0| 0: [TypeAccess] Direction -# 0| 1: [Method] valueOf +# 0| 2: [Method] valueOf # 0| 3: [TypeAccess] Direction #-----| 4: (Parameters) # 0| 0: [Parameter] value # 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Direction[] +# 0| 0: [TypeAccess] Direction # 49| 4: [Constructor] Direction # 49| 5: [BlockStmt] { ... } # 49| 0: [ExprStmt] ; @@ -154,14 +154,14 @@ classes.kt: # 50| 0: [ClassInstanceExpr] new Direction(...) # 50| -3: [TypeAccess] Direction # 53| 12: [Class] Color -# 0| 1: [Method] values -# 0| 3: [TypeAccess] Color[] -# 0| 0: [TypeAccess] Color -# 0| 1: [Method] valueOf +# 0| 2: [Method] valueOf # 0| 3: [TypeAccess] Color #-----| 4: (Parameters) # 0| 0: [Parameter] value # 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Color[] +# 0| 0: [TypeAccess] Color # 53| 4: [Constructor] Color #-----| 4: (Parameters) # 53| 0: [Parameter] rgb @@ -181,7 +181,7 @@ classes.kt: # 53| 0: [ReturnStmt] return ... # 53| 0: [VarAccess] this.rgb # 53| -1: [ThisAccess] this -# 53| 5: [FieldDeclaration] int rgb; +# 53| 6: [FieldDeclaration] int rgb; # 53| -1: [TypeAccess] int # 53| 0: [VarAccess] rgb # 54| 7: [FieldDeclaration] Color RED; @@ -266,7 +266,7 @@ classes.kt: # 73| 0: [ReturnStmt] return ... # 73| 0: [VarAccess] this.x # 73| -1: [ThisAccess] this -# 73| 2: [FieldDeclaration] int x; +# 73| 3: [FieldDeclaration] int x; # 73| -1: [TypeAccess] int # 73| 0: [IntegerLiteral] 1 # 74| 4: [Method] foo @@ -434,7 +434,7 @@ classes.kt: # 118| 1: [Constructor] # 118| 5: [BlockStmt] { ... } # 118| 0: [SuperConstructorInvocationStmt] super(...) -# 118| 1: [Method] localFn +# 118| 2: [Method] localFn # 118| 3: [TypeAccess] Unit # 118| 5: [BlockStmt] { ... } # 119| 0: [LocalTypeDeclStmt] class ... @@ -541,15 +541,15 @@ generic_anonymous.kt: # 3| 1: [ExprStmt] ; # 3| 0: [KtInitializerAssignExpr] ...=... # 3| 0: [VarAccess] x -# 1| 2: [Method] getT +# 1| 2: [FieldDeclaration] T t; +# 1| -1: [TypeAccess] T +# 1| 0: [VarAccess] t +# 1| 3: [Method] getT # 1| 3: [TypeAccess] T # 1| 5: [BlockStmt] { ... } # 1| 0: [ReturnStmt] return ... # 1| 0: [VarAccess] this.t # 1| -1: [ThisAccess] this -# 1| 2: [FieldDeclaration] T t; -# 1| -1: [TypeAccess] T -# 1| 0: [VarAccess] t # 3| 4: [FieldDeclaration] new Object(...) { ... } x; # 3| -1: [TypeAccess] new Object(...) { ... } # 3| 0: [TypeAccess] T @@ -564,17 +564,17 @@ generic_anonymous.kt: # 4| 0: [ExprStmt] ; # 4| 0: [KtInitializerAssignExpr] ...=... # 4| 0: [VarAccess] member -# 4| 2: [Method] getMember -# 4| 3: [TypeAccess] T -# 4| 5: [BlockStmt] { ... } -# 4| 0: [ReturnStmt] return ... -# 4| 0: [VarAccess] this.member -# 4| -1: [ThisAccess] this # 4| 2: [FieldDeclaration] T member; # 4| -1: [TypeAccess] T # 4| 0: [MethodAccess] getT(...) # 4| -1: [ThisAccess] Generic.this # 4| 0: [TypeAccess] Generic +# 4| 3: [Method] getMember +# 4| 3: [TypeAccess] T +# 4| 5: [BlockStmt] { ... } +# 4| 0: [ReturnStmt] return ... +# 4| 0: [VarAccess] this.member +# 4| -1: [ThisAccess] this # 3| 1: [ExprStmt] ; # 3| 0: [ClassInstanceExpr] new (...) # 3| -3: [TypeAccess] Object @@ -605,12 +605,6 @@ localClassField.kt: # 7| 1: [ExprStmt] ; # 7| 0: [KtInitializerAssignExpr] ...=... # 7| 0: [VarAccess] y -# 2| 2: [Method] getX -# 2| 3: [TypeAccess] Object -# 2| 5: [BlockStmt] { ... } -# 2| 0: [ReturnStmt] return ... -# 2| 0: [VarAccess] this.x -# 2| -1: [ThisAccess] this # 2| 2: [FieldDeclaration] Object x; # 2| -1: [TypeAccess] Object # 2| 0: [WhenExpr] when ... @@ -629,12 +623,12 @@ localClassField.kt: # 2| 1: [WhenBranch] ... -> ... # 2| 0: [BooleanLiteral] true # 5| 1: [BlockStmt] { ... } -# 7| 4: [Method] getY -# 7| 3: [TypeAccess] Object -# 7| 5: [BlockStmt] { ... } -# 7| 0: [ReturnStmt] return ... -# 7| 0: [VarAccess] this.y -# 7| -1: [ThisAccess] this +# 2| 3: [Method] getX +# 2| 3: [TypeAccess] Object +# 2| 5: [BlockStmt] { ... } +# 2| 0: [ReturnStmt] return ... +# 2| 0: [VarAccess] this.x +# 2| -1: [ThisAccess] this # 7| 4: [FieldDeclaration] Object y; # 7| -1: [TypeAccess] Object # 7| 0: [WhenExpr] when ... @@ -653,6 +647,12 @@ localClassField.kt: # 7| 1: [WhenBranch] ... -> ... # 7| 0: [BooleanLiteral] true # 10| 1: [BlockStmt] { ... } +# 7| 5: [Method] getY +# 7| 3: [TypeAccess] Object +# 7| 5: [BlockStmt] { ... } +# 7| 0: [ReturnStmt] return ... +# 7| 0: [VarAccess] this.y +# 7| -1: [ThisAccess] this local_anonymous.kt: # 0| [CompilationUnit] local_anonymous # 3| 1: [Class] Class1 @@ -686,7 +686,7 @@ local_anonymous.kt: # 11| 1: [Constructor] # 11| 5: [BlockStmt] { ... } # 11| 0: [SuperConstructorInvocationStmt] super(...) -# 11| 1: [Method] fnLocal +# 11| 2: [Method] fnLocal # 11| 3: [TypeAccess] Unit # 11| 5: [BlockStmt] { ... } # 12| 1: [ExprStmt] ; @@ -703,7 +703,7 @@ local_anonymous.kt: # 16| 1: [Constructor] # 16| 5: [BlockStmt] { ... } # 16| 0: [SuperConstructorInvocationStmt] super(...) -# 16| 1: [Method] invoke +# 16| 2: [Method] invoke # 16| 3: [TypeAccess] int #-----| 4: (Parameters) # 16| 0: [Parameter] a @@ -726,7 +726,7 @@ local_anonymous.kt: # 17| 1: [Constructor] # 17| 5: [BlockStmt] { ... } # 17| 0: [SuperConstructorInvocationStmt] super(...) -# 17| 1: [Method] invoke +# 17| 2: [Method] invoke # 17| 3: [TypeAccess] int #-----| 4: (Parameters) # 17| 0: [Parameter] a @@ -752,7 +752,7 @@ local_anonymous.kt: # 21| 1: [Constructor] # 21| 5: [BlockStmt] { ... } # 21| 0: [SuperConstructorInvocationStmt] super(...) -# 21| 1: [Method] invoke +# 21| 2: [Method] invoke #-----| 4: (Parameters) # 21| 0: [Parameter] a0 # 21| 5: [BlockStmt] { ... } @@ -797,7 +797,10 @@ local_anonymous.kt: # 30| 0: [ReturnStmt] return ... # 30| 0: [VarAccess] this.x # 30| -1: [ThisAccess] this -# 30| 2: [Method] setX +# 30| 3: [FieldDeclaration] int x; +# 30| -1: [TypeAccess] int +# 30| 0: [IntegerLiteral] 1 +# 30| 4: [Method] setX # 30| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 30| 0: [Parameter] @@ -808,9 +811,6 @@ local_anonymous.kt: # 30| 0: [VarAccess] this.x # 30| -1: [ThisAccess] this # 30| 1: [VarAccess] -# 30| 2: [FieldDeclaration] int x; -# 30| -1: [TypeAccess] int -# 30| 0: [IntegerLiteral] 1 # 32| 5: [Method] member # 32| 3: [TypeAccess] Unit # 32| 5: [BlockStmt] { ... } @@ -840,23 +840,6 @@ local_anonymous.kt: # 40| 0: [ExprStmt] ; # 40| 0: [KtInitializerAssignExpr] ...=... # 40| 0: [VarAccess] i -# 40| 2: [Method] getI -# 40| 3: [TypeAccess] Interface2 -# 40| 5: [BlockStmt] { ... } -# 40| 0: [ReturnStmt] return ... -# 40| 0: [VarAccess] this.i -# 40| -1: [ThisAccess] this -# 40| 2: [Method] setI -# 40| 3: [TypeAccess] Unit -#-----| 4: (Parameters) -# 40| 0: [Parameter] -# 40| 0: [TypeAccess] Interface2 -# 40| 5: [BlockStmt] { ... } -# 40| 0: [ExprStmt] ; -# 40| 0: [AssignExpr] ...=... -# 40| 0: [VarAccess] this.i -# 40| -1: [ThisAccess] this -# 40| 1: [VarAccess] # 40| 2: [FieldDeclaration] Interface2 i; # 40| -1: [TypeAccess] Interface2 # 40| 0: [StmtExpr] @@ -873,6 +856,23 @@ local_anonymous.kt: # 40| 1: [ExprStmt] ; # 40| 0: [ClassInstanceExpr] new (...) # 40| -3: [TypeAccess] Interface2 +# 40| 3: [Method] getI +# 40| 3: [TypeAccess] Interface2 +# 40| 5: [BlockStmt] { ... } +# 40| 0: [ReturnStmt] return ... +# 40| 0: [VarAccess] this.i +# 40| -1: [ThisAccess] this +# 40| 4: [Method] setI +# 40| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 40| 0: [Parameter] +# 40| 0: [TypeAccess] Interface2 +# 40| 5: [BlockStmt] { ... } +# 40| 0: [ExprStmt] ; +# 40| 0: [AssignExpr] ...=... +# 40| 0: [VarAccess] this.i +# 40| -1: [ThisAccess] this +# 40| 1: [VarAccess] superChain.kt: # 0| [CompilationUnit] superChain # 1| 1: [Class,GenericType,ParameterizedType] SuperChain1 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 06f6a78ce60..aa31626daeb 100644 --- a/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected @@ -7,14 +7,14 @@ dc.kt: # 0| 0: [ReturnStmt] return ... # 0| 0: [VarAccess] this.bytes # 0| -1: [ThisAccess] this -# 0| 1: [Method] component2 +# 0| 2: [Method] component2 # 0| 3: [TypeAccess] String[] # 0| 0: [TypeAccess] String # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... # 0| 0: [VarAccess] this.strs # 0| -1: [ThisAccess] this -# 0| 1: [Method] copy +# 0| 3: [Method] copy # 0| 3: [TypeAccess] ProtoMapValue #-----| 4: (Parameters) # 1| 0: [Parameter] bytes @@ -28,47 +28,7 @@ dc.kt: # 0| -3: [TypeAccess] ProtoMapValue # 0| 0: [VarAccess] bytes # 0| 1: [VarAccess] strs -# 0| 1: [Method] toString -# 0| 3: [TypeAccess] String -# 0| 5: [BlockStmt] { ... } -# 0| 0: [ReturnStmt] return ... -# 0| 0: [StringTemplateExpr] "..." -# 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| 5: [MethodAccess] toString(...) -# 0| -1: [TypeAccess] Arrays -# 0| 0: [VarAccess] this.strs -# 0| -1: [ThisAccess] this -# 0| 6: [StringLiteral] ) -# 0| 1: [Method] hashCode -# 0| 3: [TypeAccess] int -# 0| 5: [BlockStmt] { ... } -# 0| 0: [LocalVariableDeclStmt] var ...; -# 0| 1: [LocalVariableDeclExpr] result -# 0| 0: [MethodAccess] hashCode(...) -# 0| -1: [TypeAccess] Arrays -# 0| 0: [VarAccess] this.bytes -# 0| -1: [ThisAccess] this -# 0| 1: [ExprStmt] ; -# 0| 0: [AssignExpr] ...=... -# 0| 0: [VarAccess] result -# 0| 1: [MethodAccess] plus(...) -# 0| -1: [MethodAccess] times(...) -# 0| -1: [VarAccess] result -# 0| 0: [IntegerLiteral] 31 -# 0| 0: [MethodAccess] hashCode(...) -# 0| -1: [TypeAccess] Arrays -# 0| 0: [VarAccess] this.strs -# 0| -1: [ThisAccess] this -# 0| 2: [ReturnStmt] return ... -# 0| 0: [VarAccess] result -# 0| 1: [Method] equals +# 0| 4: [Method] equals # 0| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 0| 0: [Parameter] other @@ -117,6 +77,46 @@ dc.kt: # 0| 0: [BooleanLiteral] false # 0| 5: [ReturnStmt] return ... # 0| 0: [BooleanLiteral] true +# 0| 5: [Method] hashCode +# 0| 3: [TypeAccess] int +# 0| 5: [BlockStmt] { ... } +# 0| 0: [LocalVariableDeclStmt] var ...; +# 0| 1: [LocalVariableDeclExpr] result +# 0| 0: [MethodAccess] hashCode(...) +# 0| -1: [TypeAccess] Arrays +# 0| 0: [VarAccess] this.bytes +# 0| -1: [ThisAccess] this +# 0| 1: [ExprStmt] ; +# 0| 0: [AssignExpr] ...=... +# 0| 0: [VarAccess] result +# 0| 1: [MethodAccess] plus(...) +# 0| -1: [MethodAccess] times(...) +# 0| -1: [VarAccess] result +# 0| 0: [IntegerLiteral] 31 +# 0| 0: [MethodAccess] hashCode(...) +# 0| -1: [TypeAccess] Arrays +# 0| 0: [VarAccess] this.strs +# 0| -1: [ThisAccess] this +# 0| 2: [ReturnStmt] return ... +# 0| 0: [VarAccess] result +# 0| 6: [Method] toString +# 0| 3: [TypeAccess] String +# 0| 5: [BlockStmt] { ... } +# 0| 0: [ReturnStmt] return ... +# 0| 0: [StringTemplateExpr] "..." +# 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| 5: [MethodAccess] toString(...) +# 0| -1: [TypeAccess] Arrays +# 0| 0: [VarAccess] this.strs +# 0| -1: [ThisAccess] this +# 0| 6: [StringLiteral] ) # 1| 7: [Constructor] ProtoMapValue #-----| 4: (Parameters) # 1| 0: [Parameter] bytes @@ -133,23 +133,23 @@ dc.kt: # 1| 1: [ExprStmt] ; # 1| 0: [KtInitializerAssignExpr] ...=... # 1| 0: [VarAccess] strs -# 1| 8: [Method] getBytes +# 1| 8: [FieldDeclaration] byte[] bytes; +# 1| -1: [TypeAccess] byte[] +# 1| 0: [VarAccess] bytes +# 1| 9: [Method] getBytes # 1| 3: [TypeAccess] byte[] # 1| 5: [BlockStmt] { ... } # 1| 0: [ReturnStmt] return ... # 1| 0: [VarAccess] this.bytes # 1| -1: [ThisAccess] this -# 1| 8: [FieldDeclaration] byte[] bytes; -# 1| -1: [TypeAccess] byte[] -# 1| 0: [VarAccess] bytes -# 1| 10: [Method] getStrs +# 1| 10: [FieldDeclaration] String[] strs; +# 1| -1: [TypeAccess] String[] +# 1| 0: [TypeAccess] String +# 1| 0: [VarAccess] strs +# 1| 11: [Method] getStrs # 1| 3: [TypeAccess] String[] # 1| 0: [TypeAccess] String # 1| 5: [BlockStmt] { ... } # 1| 0: [ReturnStmt] return ... # 1| 0: [VarAccess] this.strs # 1| -1: [ThisAccess] this -# 1| 10: [FieldDeclaration] String[] strs; -# 1| -1: [TypeAccess] String[] -# 1| 0: [TypeAccess] String -# 1| 0: [VarAccess] strs diff --git a/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected b/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected index 8696254be8f..879eb93c94e 100644 --- a/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected @@ -7,7 +7,10 @@ delegatedProperties.kt: # 60| 0: [ReturnStmt] return ... # 60| 0: [VarAccess] DelegatedPropertiesKt.topLevelInt # 60| -1: [TypeAccess] DelegatedPropertiesKt -# 60| 2: [Method] setTopLevelInt +# 60| 3: [FieldDeclaration] int topLevelInt; +# 60| -1: [TypeAccess] int +# 60| 0: [IntegerLiteral] 0 +# 60| 4: [Method] setTopLevelInt # 60| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 60| 0: [Parameter] @@ -18,10 +21,35 @@ delegatedProperties.kt: # 60| 0: [VarAccess] DelegatedPropertiesKt.topLevelInt # 60| -1: [TypeAccess] DelegatedPropertiesKt # 60| 1: [VarAccess] -# 60| 2: [FieldDeclaration] int topLevelInt; -# 60| -1: [TypeAccess] int -# 60| 0: [IntegerLiteral] 0 -# 87| 5: [ExtensionMethod] getExtDelegated +# 87| 5: [FieldDeclaration] KMutableProperty0 extDelegated$delegateMyClass; +# 87| -1: [TypeAccess] KMutableProperty0 +# 87| 0: [TypeAccess] Integer +# 87| 0: [PropertyRefExpr] ...::... +# 87| -4: [AnonymousClass] new KMutableProperty0(...) { ... } +# 87| 1: [Constructor] +# 87| 5: [BlockStmt] { ... } +# 87| 0: [SuperConstructorInvocationStmt] super(...) +# 87| 2: [Method] get +# 87| 5: [BlockStmt] { ... } +# 87| 0: [ReturnStmt] return ... +# 87| 0: [MethodAccess] getTopLevelInt(...) +# 87| -1: [TypeAccess] DelegatedPropertiesKt +# 87| 3: [Method] invoke +# 87| 5: [BlockStmt] { ... } +# 87| 0: [ReturnStmt] return ... +# 87| 0: [MethodAccess] get(...) +# 87| -1: [ThisAccess] this +# 87| 4: [Method] set +#-----| 4: (Parameters) +# 87| 0: [Parameter] a0 +# 87| 5: [BlockStmt] { ... } +# 87| 0: [ReturnStmt] return ... +# 87| 0: [MethodAccess] setTopLevelInt(...) +# 87| -1: [TypeAccess] DelegatedPropertiesKt +# 87| 0: [VarAccess] a0 +# 87| -3: [TypeAccess] KMutableProperty0 +# 87| 0: [TypeAccess] Integer +# 87| 6: [ExtensionMethod] getExtDelegated # 87| 3: [TypeAccess] int #-----| 4: (Parameters) # 87| 0: [Parameter] @@ -39,7 +67,7 @@ delegatedProperties.kt: # 87| 1: [Constructor] # 87| 5: [BlockStmt] { ... } # 87| 0: [SuperConstructorInvocationStmt] super(...) -# 87| 1: [Method] get +# 87| 2: [Method] get #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 5: [BlockStmt] { ... } @@ -47,7 +75,7 @@ delegatedProperties.kt: # 87| 0: [MethodAccess] getExtDelegated(...) # 87| -1: [TypeAccess] DelegatedPropertiesKt # 87| 0: [VarAccess] a0 -# 87| 1: [Method] invoke +# 87| 3: [Method] invoke #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 5: [BlockStmt] { ... } @@ -55,7 +83,7 @@ delegatedProperties.kt: # 87| 0: [MethodAccess] get(...) # 87| -1: [ThisAccess] this # 87| 0: [VarAccess] a0 -# 87| 1: [Method] set +# 87| 4: [Method] set #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 1: [Parameter] a1 @@ -68,7 +96,7 @@ delegatedProperties.kt: # 87| -3: [TypeAccess] KMutableProperty1 # 87| 0: [TypeAccess] MyClass # 87| 1: [TypeAccess] Integer -# 87| 5: [ExtensionMethod] setExtDelegated +# 87| 7: [ExtensionMethod] setExtDelegated # 87| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 87| 0: [Parameter] @@ -88,7 +116,7 @@ delegatedProperties.kt: # 87| 1: [Constructor] # 87| 5: [BlockStmt] { ... } # 87| 0: [SuperConstructorInvocationStmt] super(...) -# 87| 1: [Method] get +# 87| 2: [Method] get #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 5: [BlockStmt] { ... } @@ -96,7 +124,7 @@ delegatedProperties.kt: # 87| 0: [MethodAccess] getExtDelegated(...) # 87| -1: [TypeAccess] DelegatedPropertiesKt # 87| 0: [VarAccess] a0 -# 87| 1: [Method] invoke +# 87| 3: [Method] invoke #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 5: [BlockStmt] { ... } @@ -104,7 +132,7 @@ delegatedProperties.kt: # 87| 0: [MethodAccess] get(...) # 87| -1: [ThisAccess] this # 87| 0: [VarAccess] a0 -# 87| 1: [Method] set +# 87| 4: [Method] set #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 1: [Parameter] a1 @@ -118,34 +146,6 @@ delegatedProperties.kt: # 87| 0: [TypeAccess] MyClass # 87| 1: [TypeAccess] Integer # 87| 3: [VarAccess] -# 87| 5: [FieldDeclaration] KMutableProperty0 extDelegated$delegateMyClass; -# 87| -1: [TypeAccess] KMutableProperty0 -# 87| 0: [TypeAccess] Integer -# 87| 0: [PropertyRefExpr] ...::... -# 87| -4: [AnonymousClass] new KMutableProperty0(...) { ... } -# 87| 1: [Constructor] -# 87| 5: [BlockStmt] { ... } -# 87| 0: [SuperConstructorInvocationStmt] super(...) -# 87| 1: [Method] get -# 87| 5: [BlockStmt] { ... } -# 87| 0: [ReturnStmt] return ... -# 87| 0: [MethodAccess] getTopLevelInt(...) -# 87| -1: [TypeAccess] DelegatedPropertiesKt -# 87| 1: [Method] invoke -# 87| 5: [BlockStmt] { ... } -# 87| 0: [ReturnStmt] return ... -# 87| 0: [MethodAccess] get(...) -# 87| -1: [ThisAccess] this -# 87| 1: [Method] set -#-----| 4: (Parameters) -# 87| 0: [Parameter] a0 -# 87| 5: [BlockStmt] { ... } -# 87| 0: [ReturnStmt] return ... -# 87| 0: [MethodAccess] setTopLevelInt(...) -# 87| -1: [TypeAccess] DelegatedPropertiesKt -# 87| 0: [VarAccess] a0 -# 87| -3: [TypeAccess] KMutableProperty0 -# 87| 0: [TypeAccess] Integer # 4| 2: [Class] ClassProp1 # 4| 1: [Constructor] ClassProp1 # 4| 5: [BlockStmt] { ... } @@ -165,7 +165,7 @@ delegatedProperties.kt: # 6| 1: [Constructor] # 6| 5: [BlockStmt] { ... } # 6| 0: [SuperConstructorInvocationStmt] super(...) -# 6| 1: [Method] invoke +# 6| 2: [Method] invoke # 6| 3: [TypeAccess] int # 7| 5: [BlockStmt] { ... } # 7| 0: [ExprStmt] ; @@ -181,7 +181,7 @@ delegatedProperties.kt: # 6| 1: [Constructor] # 6| 5: [BlockStmt] { ... } # 6| 0: [SuperConstructorInvocationStmt] super(...) -# 6| 1: [Method] +# 6| 2: [Method] # 6| 3: [TypeAccess] int # 6| 5: [BlockStmt] { ... } # 6| 0: [ReturnStmt] return ... @@ -195,13 +195,13 @@ delegatedProperties.kt: # 6| 1: [Constructor] # 6| 5: [BlockStmt] { ... } # 6| 0: [SuperConstructorInvocationStmt] super(...) -# 6| 1: [Method] get +# 6| 2: [Method] get # 6| 5: [BlockStmt] { ... } # 6| 0: [ReturnStmt] return ... # 6| 0: [MethodAccess] (...) # 6| -1: [ClassInstanceExpr] new (...) # 6| -3: [TypeAccess] Object -# 6| 1: [Method] invoke +# 6| 3: [Method] invoke # 6| 5: [BlockStmt] { ... } # 6| 0: [ReturnStmt] return ... # 6| 0: [MethodAccess] get(...) @@ -252,7 +252,7 @@ delegatedProperties.kt: # 19| 1: [Constructor] # 19| 5: [BlockStmt] { ... } # 19| 0: [SuperConstructorInvocationStmt] super(...) -# 19| 1: [Method] +# 19| 2: [Method] # 19| 3: [TypeAccess] int # 19| 5: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... @@ -264,18 +264,18 @@ delegatedProperties.kt: # 19| 1: [Constructor] # 19| 5: [BlockStmt] { ... } # 19| 0: [SuperConstructorInvocationStmt] super(...) -# 19| 1: [Method] get +# 19| 2: [Method] get # 19| 5: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... # 19| 0: [MethodAccess] (...) # 19| -1: [ClassInstanceExpr] new (...) # 19| -3: [TypeAccess] Object -# 19| 1: [Method] invoke +# 19| 3: [Method] invoke # 19| 5: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... # 19| 0: [MethodAccess] get(...) # 19| -1: [ThisAccess] this -# 19| 1: [Method] set +# 19| 4: [Method] set #-----| 4: (Parameters) # 19| 0: [Parameter] a0 # 19| 5: [BlockStmt] { ... } @@ -291,7 +291,7 @@ delegatedProperties.kt: # 19| 1: [Constructor] # 19| 5: [BlockStmt] { ... } # 19| 0: [SuperConstructorInvocationStmt] super(...) -# 19| 1: [Method] +# 19| 2: [Method] # 19| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 19| 0: [Parameter] value @@ -306,18 +306,18 @@ delegatedProperties.kt: # 19| 1: [Constructor] # 19| 5: [BlockStmt] { ... } # 19| 0: [SuperConstructorInvocationStmt] super(...) -# 19| 1: [Method] get +# 19| 2: [Method] get # 19| 5: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... # 19| 0: [MethodAccess] (...) # 19| -1: [ClassInstanceExpr] new (...) # 19| -3: [TypeAccess] Object -# 19| 1: [Method] invoke +# 19| 3: [Method] invoke # 19| 5: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... # 19| 0: [MethodAccess] get(...) # 19| -1: [ThisAccess] this -# 19| 1: [Method] set +# 19| 4: [Method] set #-----| 4: (Parameters) # 19| 0: [Parameter] a0 # 19| 5: [BlockStmt] { ... } @@ -349,7 +349,7 @@ delegatedProperties.kt: # 23| 1: [Constructor] # 23| 5: [BlockStmt] { ... } # 23| 0: [SuperConstructorInvocationStmt] super(...) -# 23| 1: [Method] +# 23| 2: [Method] # 23| 3: [TypeAccess] String # 23| 5: [BlockStmt] { ... } # 23| 0: [ReturnStmt] return ... @@ -364,13 +364,13 @@ delegatedProperties.kt: # 23| 1: [Constructor] # 23| 5: [BlockStmt] { ... } # 23| 0: [SuperConstructorInvocationStmt] super(...) -# 23| 1: [Method] get +# 23| 2: [Method] get # 23| 5: [BlockStmt] { ... } # 23| 0: [ReturnStmt] return ... # 23| 0: [MethodAccess] (...) # 23| -1: [ClassInstanceExpr] new (...) # 23| -3: [TypeAccess] Object -# 23| 1: [Method] invoke +# 23| 3: [Method] invoke # 23| 5: [BlockStmt] { ... } # 23| 0: [ReturnStmt] return ... # 23| 0: [MethodAccess] get(...) @@ -382,7 +382,7 @@ delegatedProperties.kt: # 25| 1: [Constructor] # 25| 5: [BlockStmt] { ... } # 25| 0: [SuperConstructorInvocationStmt] super(...) -# 25| 1: [Method] resourceDelegate +# 25| 2: [Method] resourceDelegate # 25| 3: [TypeAccess] ReadWriteProperty # 25| 0: [TypeAccess] Object # 25| 1: [TypeAccess] Integer @@ -405,7 +405,10 @@ delegatedProperties.kt: # 26| 0: [ReturnStmt] return ... # 26| 0: [VarAccess] this.curValue # 26| -1: [ThisAccess] this -# 26| 2: [Method] setCurValue +# 26| 3: [FieldDeclaration] int curValue; +# 26| -1: [TypeAccess] int +# 26| 0: [IntegerLiteral] 0 +# 26| 4: [Method] setCurValue # 26| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 26| 0: [Parameter] @@ -416,9 +419,6 @@ delegatedProperties.kt: # 26| 0: [VarAccess] this.curValue # 26| -1: [ThisAccess] this # 26| 1: [VarAccess] -# 26| 2: [FieldDeclaration] int curValue; -# 26| -1: [TypeAccess] int -# 26| 0: [IntegerLiteral] 0 # 27| 5: [Method] getValue # 27| 3: [TypeAccess] int #-----| 4: (Parameters) @@ -460,7 +460,7 @@ delegatedProperties.kt: # 33| 1: [Constructor] # 33| 5: [BlockStmt] { ... } # 33| 0: [SuperConstructorInvocationStmt] super(...) -# 33| 1: [Method] +# 33| 2: [Method] # 33| 3: [TypeAccess] int # 33| 5: [BlockStmt] { ... } # 33| 0: [ReturnStmt] return ... @@ -472,13 +472,13 @@ delegatedProperties.kt: # 33| 1: [Constructor] # 33| 5: [BlockStmt] { ... } # 33| 0: [SuperConstructorInvocationStmt] super(...) -# 33| 1: [Method] get +# 33| 2: [Method] get # 33| 5: [BlockStmt] { ... } # 33| 0: [ReturnStmt] return ... # 33| 0: [MethodAccess] (...) # 33| -1: [ClassInstanceExpr] new (...) # 33| -3: [TypeAccess] Object -# 33| 1: [Method] invoke +# 33| 3: [Method] invoke # 33| 5: [BlockStmt] { ... } # 33| 0: [ReturnStmt] return ... # 33| 0: [MethodAccess] get(...) @@ -496,7 +496,7 @@ delegatedProperties.kt: # 34| 1: [Constructor] # 34| 5: [BlockStmt] { ... } # 34| 0: [SuperConstructorInvocationStmt] super(...) -# 34| 1: [Method] +# 34| 2: [Method] # 34| 3: [TypeAccess] int # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... @@ -508,18 +508,18 @@ delegatedProperties.kt: # 34| 1: [Constructor] # 34| 5: [BlockStmt] { ... } # 34| 0: [SuperConstructorInvocationStmt] super(...) -# 34| 1: [Method] get +# 34| 2: [Method] get # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... # 34| 0: [MethodAccess] (...) # 34| -1: [ClassInstanceExpr] new (...) # 34| -3: [TypeAccess] Object -# 34| 1: [Method] invoke +# 34| 3: [Method] invoke # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... # 34| 0: [MethodAccess] get(...) # 34| -1: [ThisAccess] this -# 34| 1: [Method] set +# 34| 4: [Method] set #-----| 4: (Parameters) # 34| 0: [Parameter] a0 # 34| 5: [BlockStmt] { ... } @@ -535,7 +535,7 @@ delegatedProperties.kt: # 34| 1: [Constructor] # 34| 5: [BlockStmt] { ... } # 34| 0: [SuperConstructorInvocationStmt] super(...) -# 34| 1: [Method] +# 34| 2: [Method] # 34| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 34| 0: [Parameter] value @@ -550,18 +550,18 @@ delegatedProperties.kt: # 34| 1: [Constructor] # 34| 5: [BlockStmt] { ... } # 34| 0: [SuperConstructorInvocationStmt] super(...) -# 34| 1: [Method] get +# 34| 2: [Method] get # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... # 34| 0: [MethodAccess] (...) # 34| -1: [ClassInstanceExpr] new (...) # 34| -3: [TypeAccess] Object -# 34| 1: [Method] invoke +# 34| 3: [Method] invoke # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... # 34| 0: [MethodAccess] get(...) # 34| -1: [ThisAccess] this -# 34| 1: [Method] set +# 34| 4: [Method] set #-----| 4: (Parameters) # 34| 0: [Parameter] a0 # 34| 5: [BlockStmt] { ... } @@ -594,13 +594,13 @@ delegatedProperties.kt: # 39| 1: [Constructor] # 39| 5: [BlockStmt] { ... } # 39| 0: [SuperConstructorInvocationStmt] super(...) -# 39| 1: [Method] get +# 39| 2: [Method] get # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... # 39| 0: [MethodAccess] (...) # 39| -1: [ClassInstanceExpr] new (...) # 39| -3: [TypeAccess] Object -# 39| 1: [Method] invoke +# 39| 3: [Method] invoke # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... # 39| 0: [MethodAccess] get(...) @@ -612,7 +612,7 @@ delegatedProperties.kt: # 39| 1: [Constructor] # 39| 5: [BlockStmt] { ... } # 39| 0: [SuperConstructorInvocationStmt] super(...) -# 39| 1: [Method] +# 39| 2: [Method] # 39| 3: [TypeAccess] int # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... @@ -624,20 +624,24 @@ delegatedProperties.kt: # 39| 1: [Constructor] # 39| 5: [BlockStmt] { ... } # 39| 0: [SuperConstructorInvocationStmt] super(...) -# 39| 1: [Method] get +# 39| 2: [Method] get # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... # 39| 0: [MethodAccess] (...) # 39| -1: [ClassInstanceExpr] new (...) # 39| -3: [TypeAccess] Object -# 39| 1: [Method] invoke +# 39| 3: [Method] invoke # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... # 39| 0: [MethodAccess] get(...) # 39| -1: [ThisAccess] this # 39| -3: [TypeAccess] KProperty0 # 39| 0: [TypeAccess] Integer -# 42| 3: [Method] getVarResource0 +# 42| 3: [FieldDeclaration] ResourceDelegate varResource0$delegate; +# 42| -1: [TypeAccess] ResourceDelegate +# 42| 0: [ClassInstanceExpr] new ResourceDelegate(...) +# 42| -3: [TypeAccess] ResourceDelegate +# 42| 4: [Method] getVarResource0 # 42| 3: [TypeAccess] int # 42| 5: [BlockStmt] { ... } # 42| 0: [ReturnStmt] return ... @@ -650,14 +654,14 @@ delegatedProperties.kt: # 42| 1: [Constructor] # 42| 5: [BlockStmt] { ... } # 42| 0: [SuperConstructorInvocationStmt] super(...) -# 42| 1: [Method] get +# 42| 2: [Method] get #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 5: [BlockStmt] { ... } # 42| 0: [ReturnStmt] return ... # 42| 0: [MethodAccess] getVarResource0(...) # 42| -1: [VarAccess] a0 -# 42| 1: [Method] invoke +# 42| 3: [Method] invoke #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 5: [BlockStmt] { ... } @@ -665,7 +669,7 @@ delegatedProperties.kt: # 42| 0: [MethodAccess] get(...) # 42| -1: [ThisAccess] this # 42| 0: [VarAccess] a0 -# 42| 1: [Method] set +# 42| 4: [Method] set #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 1: [Parameter] a1 @@ -677,7 +681,7 @@ delegatedProperties.kt: # 42| -3: [TypeAccess] KMutableProperty1 # 42| 0: [TypeAccess] Owner # 42| 1: [TypeAccess] Integer -# 42| 3: [Method] setVarResource0 +# 42| 5: [Method] setVarResource0 # 42| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 42| 0: [Parameter] @@ -693,14 +697,14 @@ delegatedProperties.kt: # 42| 1: [Constructor] # 42| 5: [BlockStmt] { ... } # 42| 0: [SuperConstructorInvocationStmt] super(...) -# 42| 1: [Method] get +# 42| 2: [Method] get #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 5: [BlockStmt] { ... } # 42| 0: [ReturnStmt] return ... # 42| 0: [MethodAccess] getVarResource0(...) # 42| -1: [VarAccess] a0 -# 42| 1: [Method] invoke +# 42| 3: [Method] invoke #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 5: [BlockStmt] { ... } @@ -708,7 +712,7 @@ delegatedProperties.kt: # 42| 0: [MethodAccess] get(...) # 42| -1: [ThisAccess] this # 42| 0: [VarAccess] a0 -# 42| 1: [Method] set +# 42| 4: [Method] set #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 1: [Parameter] a1 @@ -721,10 +725,6 @@ delegatedProperties.kt: # 42| 0: [TypeAccess] Owner # 42| 1: [TypeAccess] Integer # 42| 2: [VarAccess] -# 42| 3: [FieldDeclaration] ResourceDelegate varResource0$delegate; -# 42| -1: [TypeAccess] ResourceDelegate -# 42| 0: [ClassInstanceExpr] new ResourceDelegate(...) -# 42| -3: [TypeAccess] ResourceDelegate # 45| 5: [Class] ResourceDelegate # 45| 1: [Constructor] ResourceDelegate # 45| 5: [BlockStmt] { ... } @@ -786,7 +786,7 @@ delegatedProperties.kt: # 62| 0: [ReturnStmt] return ... # 62| 0: [VarAccess] this.anotherClassInt # 62| -1: [ThisAccess] this -# 62| 2: [FieldDeclaration] int anotherClassInt; +# 62| 3: [FieldDeclaration] int anotherClassInt; # 62| -1: [TypeAccess] int # 62| 0: [VarAccess] anotherClassInt # 63| 8: [Class] Base @@ -806,7 +806,7 @@ delegatedProperties.kt: # 63| 0: [ReturnStmt] return ... # 63| 0: [VarAccess] this.baseClassInt # 63| -1: [ThisAccess] this -# 63| 2: [FieldDeclaration] int baseClassInt; +# 63| 3: [FieldDeclaration] int baseClassInt; # 63| -1: [TypeAccess] int # 63| 0: [VarAccess] baseClassInt # 65| 9: [Class] MyClass @@ -859,7 +859,10 @@ delegatedProperties.kt: # 65| 0: [ReturnStmt] return ... # 65| 0: [VarAccess] this.memberInt # 65| -1: [ThisAccess] this -# 65| 2: [Method] setMemberInt +# 65| 3: [FieldDeclaration] int memberInt; +# 65| -1: [TypeAccess] int +# 65| 0: [VarAccess] memberInt +# 65| 4: [Method] setMemberInt # 65| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 65| 0: [Parameter] @@ -870,19 +873,57 @@ delegatedProperties.kt: # 65| 0: [VarAccess] this.memberInt # 65| -1: [ThisAccess] this # 65| 1: [VarAccess] -# 65| 2: [FieldDeclaration] int memberInt; -# 65| -1: [TypeAccess] int -# 65| 0: [VarAccess] memberInt -# 65| 5: [Method] getAnotherClassInstance +# 65| 5: [FieldDeclaration] ClassWithDelegate anotherClassInstance; +# 65| -1: [TypeAccess] ClassWithDelegate +# 65| 0: [VarAccess] anotherClassInstance +# 65| 6: [Method] getAnotherClassInstance # 65| 3: [TypeAccess] ClassWithDelegate # 65| 5: [BlockStmt] { ... } # 65| 0: [ReturnStmt] return ... # 65| 0: [VarAccess] this.anotherClassInstance # 65| -1: [ThisAccess] this -# 65| 5: [FieldDeclaration] ClassWithDelegate anotherClassInstance; -# 65| -1: [TypeAccess] ClassWithDelegate -# 65| 0: [VarAccess] anotherClassInstance -# 66| 7: [Method] getDelegatedToMember1 +# 66| 7: [FieldDeclaration] KMutableProperty0 delegatedToMember1$delegate; +# 66| -1: [TypeAccess] KMutableProperty0 +# 66| 0: [TypeAccess] Integer +# 66| 0: [PropertyRefExpr] ...::... +# 66| -4: [AnonymousClass] new KMutableProperty0(...) { ... } +# 66| 1: [Constructor] +#-----| 4: (Parameters) +# 66| 0: [Parameter] +# 66| 5: [BlockStmt] { ... } +# 66| 0: [SuperConstructorInvocationStmt] super(...) +# 66| 1: [ExprStmt] ; +# 66| 0: [AssignExpr] ...=... +# 66| 0: [VarAccess] this. +# 66| -1: [ThisAccess] this +# 66| 1: [VarAccess] +# 66| 2: [FieldDeclaration] MyClass ; +# 66| -1: [TypeAccess] MyClass +# 66| 3: [Method] get +# 66| 5: [BlockStmt] { ... } +# 66| 0: [ReturnStmt] return ... +# 66| 0: [MethodAccess] getMemberInt(...) +# 66| -1: [VarAccess] this. +# 66| -1: [ThisAccess] this +# 66| 4: [Method] invoke +# 66| 5: [BlockStmt] { ... } +# 66| 0: [ReturnStmt] return ... +# 66| 0: [MethodAccess] get(...) +# 66| -1: [ThisAccess] this +# 66| 5: [Method] set +#-----| 4: (Parameters) +# 66| 0: [Parameter] a0 +# 66| 5: [BlockStmt] { ... } +# 66| 0: [ReturnStmt] return ... +# 66| 0: [MethodAccess] setMemberInt(...) +# 66| -1: [VarAccess] this. +# 66| -1: [ThisAccess] this +# 66| 0: [VarAccess] a0 +# 66| -3: [TypeAccess] KMutableProperty0 +# 66| 0: [TypeAccess] Integer +# 66| 0: [ThisAccess] MyClass.this +# 66| 0: [TypeAccess] MyClass +# 66| 8: [Method] getDelegatedToMember1 # 66| 3: [TypeAccess] int # 66| 5: [BlockStmt] { ... } # 66| 0: [ReturnStmt] return ... @@ -897,14 +938,14 @@ delegatedProperties.kt: # 66| 1: [Constructor] # 66| 5: [BlockStmt] { ... } # 66| 0: [SuperConstructorInvocationStmt] super(...) -# 66| 1: [Method] get +# 66| 2: [Method] get #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 5: [BlockStmt] { ... } # 66| 0: [ReturnStmt] return ... # 66| 0: [MethodAccess] getDelegatedToMember1(...) # 66| -1: [VarAccess] a0 -# 66| 1: [Method] invoke +# 66| 3: [Method] invoke #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 5: [BlockStmt] { ... } @@ -912,7 +953,7 @@ delegatedProperties.kt: # 66| 0: [MethodAccess] get(...) # 66| -1: [ThisAccess] this # 66| 0: [VarAccess] a0 -# 66| 1: [Method] set +# 66| 4: [Method] set #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 1: [Parameter] a1 @@ -924,7 +965,7 @@ delegatedProperties.kt: # 66| -3: [TypeAccess] KMutableProperty1 # 66| 0: [TypeAccess] MyClass # 66| 1: [TypeAccess] Integer -# 66| 7: [Method] setDelegatedToMember1 +# 66| 9: [Method] setDelegatedToMember1 # 66| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 66| 0: [Parameter] @@ -942,14 +983,14 @@ delegatedProperties.kt: # 66| 1: [Constructor] # 66| 5: [BlockStmt] { ... } # 66| 0: [SuperConstructorInvocationStmt] super(...) -# 66| 1: [Method] get +# 66| 2: [Method] get #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 5: [BlockStmt] { ... } # 66| 0: [ReturnStmt] return ... # 66| 0: [MethodAccess] getDelegatedToMember1(...) # 66| -1: [VarAccess] a0 -# 66| 1: [Method] invoke +# 66| 3: [Method] invoke #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 5: [BlockStmt] { ... } @@ -957,7 +998,7 @@ delegatedProperties.kt: # 66| 0: [MethodAccess] get(...) # 66| -1: [ThisAccess] this # 66| 0: [VarAccess] a0 -# 66| 1: [Method] set +# 66| 4: [Method] set #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 1: [Parameter] a1 @@ -970,48 +1011,43 @@ delegatedProperties.kt: # 66| 0: [TypeAccess] MyClass # 66| 1: [TypeAccess] Integer # 66| 3: [VarAccess] -# 66| 7: [FieldDeclaration] KMutableProperty0 delegatedToMember1$delegate; -# 66| -1: [TypeAccess] KMutableProperty0 -# 66| 0: [TypeAccess] Integer -# 66| 0: [PropertyRefExpr] ...::... -# 66| -4: [AnonymousClass] new KMutableProperty0(...) { ... } -# 66| 1: [Constructor] +# 67| 10: [FieldDeclaration] KMutableProperty1 delegatedToMember2$delegate; +# 67| -1: [TypeAccess] KMutableProperty1 +# 67| 0: [TypeAccess] MyClass +# 67| 1: [TypeAccess] Integer +# 67| 0: [PropertyRefExpr] ...::... +# 67| -4: [AnonymousClass] new KMutableProperty1(...) { ... } +# 67| 1: [Constructor] +# 67| 5: [BlockStmt] { ... } +# 67| 0: [SuperConstructorInvocationStmt] super(...) +# 67| 2: [Method] get #-----| 4: (Parameters) -# 66| 0: [Parameter] -# 66| 5: [BlockStmt] { ... } -# 66| 0: [SuperConstructorInvocationStmt] super(...) -# 66| 1: [ExprStmt] ; -# 66| 0: [AssignExpr] ...=... -# 66| 0: [VarAccess] this. -# 66| -1: [ThisAccess] this -# 66| 1: [VarAccess] -# 66| 1: [FieldDeclaration] MyClass ; -# 66| -1: [TypeAccess] MyClass -# 66| 1: [Method] get -# 66| 5: [BlockStmt] { ... } -# 66| 0: [ReturnStmt] return ... -# 66| 0: [MethodAccess] getMemberInt(...) -# 66| -1: [VarAccess] this. -# 66| -1: [ThisAccess] this -# 66| 1: [Method] invoke -# 66| 5: [BlockStmt] { ... } -# 66| 0: [ReturnStmt] return ... -# 66| 0: [MethodAccess] get(...) -# 66| -1: [ThisAccess] this -# 66| 1: [Method] set +# 67| 0: [Parameter] a0 +# 67| 5: [BlockStmt] { ... } +# 67| 0: [ReturnStmt] return ... +# 67| 0: [MethodAccess] getMemberInt(...) +# 67| -1: [VarAccess] a0 +# 67| 3: [Method] invoke #-----| 4: (Parameters) -# 66| 0: [Parameter] a0 -# 66| 5: [BlockStmt] { ... } -# 66| 0: [ReturnStmt] return ... -# 66| 0: [MethodAccess] setMemberInt(...) -# 66| -1: [VarAccess] this. -# 66| -1: [ThisAccess] this -# 66| 0: [VarAccess] a0 -# 66| -3: [TypeAccess] KMutableProperty0 -# 66| 0: [TypeAccess] Integer -# 66| 0: [ThisAccess] MyClass.this -# 66| 0: [TypeAccess] MyClass -# 67| 10: [Method] getDelegatedToMember2 +# 67| 0: [Parameter] a0 +# 67| 5: [BlockStmt] { ... } +# 67| 0: [ReturnStmt] return ... +# 67| 0: [MethodAccess] get(...) +# 67| -1: [ThisAccess] this +# 67| 0: [VarAccess] a0 +# 67| 4: [Method] set +#-----| 4: (Parameters) +# 67| 0: [Parameter] a0 +# 67| 1: [Parameter] a1 +# 67| 5: [BlockStmt] { ... } +# 67| 0: [ReturnStmt] return ... +# 67| 0: [MethodAccess] setMemberInt(...) +# 67| -1: [VarAccess] a0 +# 67| 0: [VarAccess] a1 +# 67| -3: [TypeAccess] KMutableProperty1 +# 67| 0: [TypeAccess] MyClass +# 67| 1: [TypeAccess] Integer +# 67| 11: [Method] getDelegatedToMember2 # 67| 3: [TypeAccess] int # 67| 5: [BlockStmt] { ... } # 67| 0: [ReturnStmt] return ... @@ -1027,14 +1063,14 @@ delegatedProperties.kt: # 67| 1: [Constructor] # 67| 5: [BlockStmt] { ... } # 67| 0: [SuperConstructorInvocationStmt] super(...) -# 67| 1: [Method] get +# 67| 2: [Method] get #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } # 67| 0: [ReturnStmt] return ... # 67| 0: [MethodAccess] getDelegatedToMember2(...) # 67| -1: [VarAccess] a0 -# 67| 1: [Method] invoke +# 67| 3: [Method] invoke #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } @@ -1042,7 +1078,7 @@ delegatedProperties.kt: # 67| 0: [MethodAccess] get(...) # 67| -1: [ThisAccess] this # 67| 0: [VarAccess] a0 -# 67| 1: [Method] set +# 67| 4: [Method] set #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 1: [Parameter] a1 @@ -1054,7 +1090,7 @@ delegatedProperties.kt: # 67| -3: [TypeAccess] KMutableProperty1 # 67| 0: [TypeAccess] MyClass # 67| 1: [TypeAccess] Integer -# 67| 10: [Method] setDelegatedToMember2 +# 67| 12: [Method] setDelegatedToMember2 # 67| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 67| 0: [Parameter] @@ -1073,14 +1109,14 @@ delegatedProperties.kt: # 67| 1: [Constructor] # 67| 5: [BlockStmt] { ... } # 67| 0: [SuperConstructorInvocationStmt] super(...) -# 67| 1: [Method] get +# 67| 2: [Method] get #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } # 67| 0: [ReturnStmt] return ... # 67| 0: [MethodAccess] getDelegatedToMember2(...) # 67| -1: [VarAccess] a0 -# 67| 1: [Method] invoke +# 67| 3: [Method] invoke #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } @@ -1088,7 +1124,7 @@ delegatedProperties.kt: # 67| 0: [MethodAccess] get(...) # 67| -1: [ThisAccess] this # 67| 0: [VarAccess] a0 -# 67| 1: [Method] set +# 67| 4: [Method] set #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 1: [Parameter] a1 @@ -1101,43 +1137,50 @@ delegatedProperties.kt: # 67| 0: [TypeAccess] MyClass # 67| 1: [TypeAccess] Integer # 67| 3: [VarAccess] -# 67| 10: [FieldDeclaration] KMutableProperty1 delegatedToMember2$delegate; -# 67| -1: [TypeAccess] KMutableProperty1 -# 67| 0: [TypeAccess] MyClass -# 67| 1: [TypeAccess] Integer -# 67| 0: [PropertyRefExpr] ...::... -# 67| -4: [AnonymousClass] new KMutableProperty1(...) { ... } -# 67| 1: [Constructor] -# 67| 5: [BlockStmt] { ... } -# 67| 0: [SuperConstructorInvocationStmt] super(...) -# 67| 1: [Method] get +# 69| 13: [FieldDeclaration] KMutableProperty0 delegatedToExtMember1$delegate; +# 69| -1: [TypeAccess] KMutableProperty0 +# 69| 0: [TypeAccess] Integer +# 69| 0: [PropertyRefExpr] ...::... +# 69| -4: [AnonymousClass] new KMutableProperty0(...) { ... } +# 69| 1: [Constructor] #-----| 4: (Parameters) -# 67| 0: [Parameter] a0 -# 67| 5: [BlockStmt] { ... } -# 67| 0: [ReturnStmt] return ... -# 67| 0: [MethodAccess] getMemberInt(...) -# 67| -1: [VarAccess] a0 -# 67| 1: [Method] invoke +# 69| 0: [Parameter] +# 69| 5: [BlockStmt] { ... } +# 69| 0: [SuperConstructorInvocationStmt] super(...) +# 69| 1: [ExprStmt] ; +# 69| 0: [AssignExpr] ...=... +# 69| 0: [VarAccess] this. +# 69| -1: [ThisAccess] this +# 69| 1: [VarAccess] +# 69| 2: [FieldDeclaration] MyClass ; +# 69| -1: [TypeAccess] MyClass +# 69| 3: [Method] get +# 69| 5: [BlockStmt] { ... } +# 69| 0: [ReturnStmt] return ... +# 69| 0: [MethodAccess] getExtDelegated(...) +# 69| -1: [TypeAccess] DelegatedPropertiesKt +# 69| 0: [VarAccess] this. +# 69| -1: [ThisAccess] this +# 69| 4: [Method] invoke +# 69| 5: [BlockStmt] { ... } +# 69| 0: [ReturnStmt] return ... +# 69| 0: [MethodAccess] get(...) +# 69| -1: [ThisAccess] this +# 69| 5: [Method] set #-----| 4: (Parameters) -# 67| 0: [Parameter] a0 -# 67| 5: [BlockStmt] { ... } -# 67| 0: [ReturnStmt] return ... -# 67| 0: [MethodAccess] get(...) -# 67| -1: [ThisAccess] this -# 67| 0: [VarAccess] a0 -# 67| 1: [Method] set -#-----| 4: (Parameters) -# 67| 0: [Parameter] a0 -# 67| 1: [Parameter] a1 -# 67| 5: [BlockStmt] { ... } -# 67| 0: [ReturnStmt] return ... -# 67| 0: [MethodAccess] setMemberInt(...) -# 67| -1: [VarAccess] a0 -# 67| 0: [VarAccess] a1 -# 67| -3: [TypeAccess] KMutableProperty1 -# 67| 0: [TypeAccess] MyClass -# 67| 1: [TypeAccess] Integer -# 69| 13: [Method] getDelegatedToExtMember1 +# 69| 0: [Parameter] a0 +# 69| 5: [BlockStmt] { ... } +# 69| 0: [ReturnStmt] return ... +# 69| 0: [MethodAccess] setExtDelegated(...) +# 69| -1: [TypeAccess] DelegatedPropertiesKt +# 69| 0: [VarAccess] this. +# 69| -1: [ThisAccess] this +# 69| 1: [VarAccess] a0 +# 69| -3: [TypeAccess] KMutableProperty0 +# 69| 0: [TypeAccess] Integer +# 69| 0: [ThisAccess] MyClass.this +# 69| 0: [TypeAccess] MyClass +# 69| 14: [Method] getDelegatedToExtMember1 # 69| 3: [TypeAccess] int # 69| 5: [BlockStmt] { ... } # 69| 0: [ReturnStmt] return ... @@ -1152,14 +1195,14 @@ delegatedProperties.kt: # 69| 1: [Constructor] # 69| 5: [BlockStmt] { ... } # 69| 0: [SuperConstructorInvocationStmt] super(...) -# 69| 1: [Method] get +# 69| 2: [Method] get #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 5: [BlockStmt] { ... } # 69| 0: [ReturnStmt] return ... # 69| 0: [MethodAccess] getDelegatedToExtMember1(...) # 69| -1: [VarAccess] a0 -# 69| 1: [Method] invoke +# 69| 3: [Method] invoke #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 5: [BlockStmt] { ... } @@ -1167,7 +1210,7 @@ delegatedProperties.kt: # 69| 0: [MethodAccess] get(...) # 69| -1: [ThisAccess] this # 69| 0: [VarAccess] a0 -# 69| 1: [Method] set +# 69| 4: [Method] set #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 1: [Parameter] a1 @@ -1179,7 +1222,7 @@ delegatedProperties.kt: # 69| -3: [TypeAccess] KMutableProperty1 # 69| 0: [TypeAccess] MyClass # 69| 1: [TypeAccess] Integer -# 69| 13: [Method] setDelegatedToExtMember1 +# 69| 15: [Method] setDelegatedToExtMember1 # 69| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 69| 0: [Parameter] @@ -1197,14 +1240,14 @@ delegatedProperties.kt: # 69| 1: [Constructor] # 69| 5: [BlockStmt] { ... } # 69| 0: [SuperConstructorInvocationStmt] super(...) -# 69| 1: [Method] get +# 69| 2: [Method] get #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 5: [BlockStmt] { ... } # 69| 0: [ReturnStmt] return ... # 69| 0: [MethodAccess] getDelegatedToExtMember1(...) # 69| -1: [VarAccess] a0 -# 69| 1: [Method] invoke +# 69| 3: [Method] invoke #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 5: [BlockStmt] { ... } @@ -1212,7 +1255,7 @@ delegatedProperties.kt: # 69| 0: [MethodAccess] get(...) # 69| -1: [ThisAccess] this # 69| 0: [VarAccess] a0 -# 69| 1: [Method] set +# 69| 4: [Method] set #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 1: [Parameter] a1 @@ -1225,50 +1268,45 @@ delegatedProperties.kt: # 69| 0: [TypeAccess] MyClass # 69| 1: [TypeAccess] Integer # 69| 3: [VarAccess] -# 69| 13: [FieldDeclaration] KMutableProperty0 delegatedToExtMember1$delegate; -# 69| -1: [TypeAccess] KMutableProperty0 -# 69| 0: [TypeAccess] Integer -# 69| 0: [PropertyRefExpr] ...::... -# 69| -4: [AnonymousClass] new KMutableProperty0(...) { ... } -# 69| 1: [Constructor] +# 70| 16: [FieldDeclaration] KMutableProperty1 delegatedToExtMember2$delegate; +# 70| -1: [TypeAccess] KMutableProperty1 +# 70| 0: [TypeAccess] MyClass +# 70| 1: [TypeAccess] Integer +# 70| 0: [PropertyRefExpr] ...::... +# 70| -4: [AnonymousClass] new KMutableProperty1(...) { ... } +# 70| 1: [Constructor] +# 70| 5: [BlockStmt] { ... } +# 70| 0: [SuperConstructorInvocationStmt] super(...) +# 70| 2: [Method] get #-----| 4: (Parameters) -# 69| 0: [Parameter] -# 69| 5: [BlockStmt] { ... } -# 69| 0: [SuperConstructorInvocationStmt] super(...) -# 69| 1: [ExprStmt] ; -# 69| 0: [AssignExpr] ...=... -# 69| 0: [VarAccess] this. -# 69| -1: [ThisAccess] this -# 69| 1: [VarAccess] -# 69| 1: [FieldDeclaration] MyClass ; -# 69| -1: [TypeAccess] MyClass -# 69| 1: [Method] get -# 69| 5: [BlockStmt] { ... } -# 69| 0: [ReturnStmt] return ... -# 69| 0: [MethodAccess] getExtDelegated(...) -# 69| -1: [TypeAccess] DelegatedPropertiesKt -# 69| 0: [VarAccess] this. -# 69| -1: [ThisAccess] this -# 69| 1: [Method] invoke -# 69| 5: [BlockStmt] { ... } -# 69| 0: [ReturnStmt] return ... -# 69| 0: [MethodAccess] get(...) -# 69| -1: [ThisAccess] this -# 69| 1: [Method] set +# 70| 0: [Parameter] a0 +# 70| 5: [BlockStmt] { ... } +# 70| 0: [ReturnStmt] return ... +# 70| 0: [MethodAccess] getExtDelegated(...) +# 70| -1: [TypeAccess] DelegatedPropertiesKt +# 70| 0: [VarAccess] a0 +# 70| 3: [Method] invoke #-----| 4: (Parameters) -# 69| 0: [Parameter] a0 -# 69| 5: [BlockStmt] { ... } -# 69| 0: [ReturnStmt] return ... -# 69| 0: [MethodAccess] setExtDelegated(...) -# 69| -1: [TypeAccess] DelegatedPropertiesKt -# 69| 0: [VarAccess] this. -# 69| -1: [ThisAccess] this -# 69| 1: [VarAccess] a0 -# 69| -3: [TypeAccess] KMutableProperty0 -# 69| 0: [TypeAccess] Integer -# 69| 0: [ThisAccess] MyClass.this -# 69| 0: [TypeAccess] MyClass -# 70| 16: [Method] getDelegatedToExtMember2 +# 70| 0: [Parameter] a0 +# 70| 5: [BlockStmt] { ... } +# 70| 0: [ReturnStmt] return ... +# 70| 0: [MethodAccess] get(...) +# 70| -1: [ThisAccess] this +# 70| 0: [VarAccess] a0 +# 70| 4: [Method] set +#-----| 4: (Parameters) +# 70| 0: [Parameter] a0 +# 70| 1: [Parameter] a1 +# 70| 5: [BlockStmt] { ... } +# 70| 0: [ReturnStmt] return ... +# 70| 0: [MethodAccess] setExtDelegated(...) +# 70| -1: [TypeAccess] DelegatedPropertiesKt +# 70| 0: [VarAccess] a0 +# 70| 1: [VarAccess] a1 +# 70| -3: [TypeAccess] KMutableProperty1 +# 70| 0: [TypeAccess] MyClass +# 70| 1: [TypeAccess] Integer +# 70| 17: [Method] getDelegatedToExtMember2 # 70| 3: [TypeAccess] int # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... @@ -1284,14 +1322,14 @@ delegatedProperties.kt: # 70| 1: [Constructor] # 70| 5: [BlockStmt] { ... } # 70| 0: [SuperConstructorInvocationStmt] super(...) -# 70| 1: [Method] get +# 70| 2: [Method] get #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... # 70| 0: [MethodAccess] getDelegatedToExtMember2(...) # 70| -1: [VarAccess] a0 -# 70| 1: [Method] invoke +# 70| 3: [Method] invoke #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 5: [BlockStmt] { ... } @@ -1299,7 +1337,7 @@ delegatedProperties.kt: # 70| 0: [MethodAccess] get(...) # 70| -1: [ThisAccess] this # 70| 0: [VarAccess] a0 -# 70| 1: [Method] set +# 70| 4: [Method] set #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 1: [Parameter] a1 @@ -1311,7 +1349,7 @@ delegatedProperties.kt: # 70| -3: [TypeAccess] KMutableProperty1 # 70| 0: [TypeAccess] MyClass # 70| 1: [TypeAccess] Integer -# 70| 16: [Method] setDelegatedToExtMember2 +# 70| 18: [Method] setDelegatedToExtMember2 # 70| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 70| 0: [Parameter] @@ -1330,14 +1368,14 @@ delegatedProperties.kt: # 70| 1: [Constructor] # 70| 5: [BlockStmt] { ... } # 70| 0: [SuperConstructorInvocationStmt] super(...) -# 70| 1: [Method] get +# 70| 2: [Method] get #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... # 70| 0: [MethodAccess] getDelegatedToExtMember2(...) # 70| -1: [VarAccess] a0 -# 70| 1: [Method] invoke +# 70| 3: [Method] invoke #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 5: [BlockStmt] { ... } @@ -1345,7 +1383,7 @@ delegatedProperties.kt: # 70| 0: [MethodAccess] get(...) # 70| -1: [ThisAccess] this # 70| 0: [VarAccess] a0 -# 70| 1: [Method] set +# 70| 4: [Method] set #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 1: [Parameter] a1 @@ -1358,77 +1396,6 @@ delegatedProperties.kt: # 70| 0: [TypeAccess] MyClass # 70| 1: [TypeAccess] Integer # 70| 3: [VarAccess] -# 70| 16: [FieldDeclaration] KMutableProperty1 delegatedToExtMember2$delegate; -# 70| -1: [TypeAccess] KMutableProperty1 -# 70| 0: [TypeAccess] MyClass -# 70| 1: [TypeAccess] Integer -# 70| 0: [PropertyRefExpr] ...::... -# 70| -4: [AnonymousClass] new KMutableProperty1(...) { ... } -# 70| 1: [Constructor] -# 70| 5: [BlockStmt] { ... } -# 70| 0: [SuperConstructorInvocationStmt] super(...) -# 70| 1: [Method] get -#-----| 4: (Parameters) -# 70| 0: [Parameter] a0 -# 70| 5: [BlockStmt] { ... } -# 70| 0: [ReturnStmt] return ... -# 70| 0: [MethodAccess] getExtDelegated(...) -# 70| -1: [TypeAccess] DelegatedPropertiesKt -# 70| 0: [VarAccess] a0 -# 70| 1: [Method] invoke -#-----| 4: (Parameters) -# 70| 0: [Parameter] a0 -# 70| 5: [BlockStmt] { ... } -# 70| 0: [ReturnStmt] return ... -# 70| 0: [MethodAccess] get(...) -# 70| -1: [ThisAccess] this -# 70| 0: [VarAccess] a0 -# 70| 1: [Method] set -#-----| 4: (Parameters) -# 70| 0: [Parameter] a0 -# 70| 1: [Parameter] a1 -# 70| 5: [BlockStmt] { ... } -# 70| 0: [ReturnStmt] return ... -# 70| 0: [MethodAccess] setExtDelegated(...) -# 70| -1: [TypeAccess] DelegatedPropertiesKt -# 70| 0: [VarAccess] a0 -# 70| 1: [VarAccess] a1 -# 70| -3: [TypeAccess] KMutableProperty1 -# 70| 0: [TypeAccess] MyClass -# 70| 1: [TypeAccess] Integer -# 72| 19: [Method] getDelegatedToBaseClass1 -# 72| 3: [TypeAccess] int -# 72| 5: [BlockStmt] { ... } -# 72| 0: [ReturnStmt] return ... -# 72| 0: [MethodAccess] getValue(...) -# 72| -2: [TypeAccess] Integer -# 72| -1: [TypeAccess] PropertyReferenceDelegatesKt -# 72| 0: [VarAccess] this.delegatedToBaseClass1$delegate -# 72| -1: [ThisAccess] this -# 1| 1: [ThisAccess] this -# 72| 2: [PropertyRefExpr] ...::... -# 72| -4: [AnonymousClass] new KProperty1(...) { ... } -# 72| 1: [Constructor] -# 72| 5: [BlockStmt] { ... } -# 72| 0: [SuperConstructorInvocationStmt] super(...) -# 72| 1: [Method] get -#-----| 4: (Parameters) -# 72| 0: [Parameter] a0 -# 72| 5: [BlockStmt] { ... } -# 72| 0: [ReturnStmt] return ... -# 72| 0: [MethodAccess] getDelegatedToBaseClass1(...) -# 72| -1: [VarAccess] a0 -# 72| 1: [Method] invoke -#-----| 4: (Parameters) -# 72| 0: [Parameter] a0 -# 72| 5: [BlockStmt] { ... } -# 72| 0: [ReturnStmt] return ... -# 72| 0: [MethodAccess] get(...) -# 72| -1: [ThisAccess] this -# 72| 0: [VarAccess] a0 -# 72| -3: [TypeAccess] KProperty1 -# 72| 0: [TypeAccess] MyClass -# 72| 1: [TypeAccess] Integer # 72| 19: [FieldDeclaration] KProperty0 delegatedToBaseClass1$delegate; # 72| -1: [TypeAccess] KProperty0 # 72| 0: [TypeAccess] Integer @@ -1444,15 +1411,15 @@ delegatedProperties.kt: # 72| 0: [VarAccess] this. # 72| -1: [ThisAccess] this # 72| 1: [VarAccess] -# 72| 1: [FieldDeclaration] MyClass ; +# 72| 2: [FieldDeclaration] MyClass ; # 72| -1: [TypeAccess] MyClass -# 72| 1: [Method] get +# 72| 3: [Method] get # 72| 5: [BlockStmt] { ... } # 72| 0: [ReturnStmt] return ... # 72| 0: [MethodAccess] getBaseClassInt(...) # 72| -1: [VarAccess] this. # 72| -1: [ThisAccess] this -# 72| 1: [Method] invoke +# 72| 4: [Method] invoke # 72| 5: [BlockStmt] { ... } # 72| 0: [ReturnStmt] return ... # 72| 0: [MethodAccess] get(...) @@ -1461,7 +1428,67 @@ delegatedProperties.kt: # 72| 0: [TypeAccess] Integer # 72| 0: [ThisAccess] MyClass.this # 72| 0: [TypeAccess] MyClass -# 73| 21: [Method] getDelegatedToBaseClass2 +# 72| 20: [Method] getDelegatedToBaseClass1 +# 72| 3: [TypeAccess] int +# 72| 5: [BlockStmt] { ... } +# 72| 0: [ReturnStmt] return ... +# 72| 0: [MethodAccess] getValue(...) +# 72| -2: [TypeAccess] Integer +# 72| -1: [TypeAccess] PropertyReferenceDelegatesKt +# 72| 0: [VarAccess] this.delegatedToBaseClass1$delegate +# 72| -1: [ThisAccess] this +# 1| 1: [ThisAccess] this +# 72| 2: [PropertyRefExpr] ...::... +# 72| -4: [AnonymousClass] new KProperty1(...) { ... } +# 72| 1: [Constructor] +# 72| 5: [BlockStmt] { ... } +# 72| 0: [SuperConstructorInvocationStmt] super(...) +# 72| 2: [Method] get +#-----| 4: (Parameters) +# 72| 0: [Parameter] a0 +# 72| 5: [BlockStmt] { ... } +# 72| 0: [ReturnStmt] return ... +# 72| 0: [MethodAccess] getDelegatedToBaseClass1(...) +# 72| -1: [VarAccess] a0 +# 72| 3: [Method] invoke +#-----| 4: (Parameters) +# 72| 0: [Parameter] a0 +# 72| 5: [BlockStmt] { ... } +# 72| 0: [ReturnStmt] return ... +# 72| 0: [MethodAccess] get(...) +# 72| -1: [ThisAccess] this +# 72| 0: [VarAccess] a0 +# 72| -3: [TypeAccess] KProperty1 +# 72| 0: [TypeAccess] MyClass +# 72| 1: [TypeAccess] Integer +# 73| 21: [FieldDeclaration] KProperty1 delegatedToBaseClass2$delegate; +# 73| -1: [TypeAccess] KProperty1 +# 73| 0: [TypeAccess] Base +# 73| 1: [TypeAccess] Integer +# 73| 0: [PropertyRefExpr] ...::... +# 73| -4: [AnonymousClass] new KProperty1(...) { ... } +# 73| 1: [Constructor] +# 73| 5: [BlockStmt] { ... } +# 73| 0: [SuperConstructorInvocationStmt] super(...) +# 73| 2: [Method] get +#-----| 4: (Parameters) +# 73| 0: [Parameter] a0 +# 73| 5: [BlockStmt] { ... } +# 73| 0: [ReturnStmt] return ... +# 73| 0: [MethodAccess] getBaseClassInt(...) +# 73| -1: [VarAccess] a0 +# 73| 3: [Method] invoke +#-----| 4: (Parameters) +# 73| 0: [Parameter] a0 +# 73| 5: [BlockStmt] { ... } +# 73| 0: [ReturnStmt] return ... +# 73| 0: [MethodAccess] get(...) +# 73| -1: [ThisAccess] this +# 73| 0: [VarAccess] a0 +# 73| -3: [TypeAccess] KProperty1 +# 73| 0: [TypeAccess] Base +# 73| 1: [TypeAccess] Integer +# 73| 22: [Method] getDelegatedToBaseClass2 # 73| 3: [TypeAccess] int # 73| 5: [BlockStmt] { ... } # 73| 0: [ReturnStmt] return ... @@ -1477,14 +1504,14 @@ delegatedProperties.kt: # 73| 1: [Constructor] # 73| 5: [BlockStmt] { ... } # 73| 0: [SuperConstructorInvocationStmt] super(...) -# 73| 1: [Method] get +# 73| 2: [Method] get #-----| 4: (Parameters) # 73| 0: [Parameter] a0 # 73| 5: [BlockStmt] { ... } # 73| 0: [ReturnStmt] return ... # 73| 0: [MethodAccess] getDelegatedToBaseClass2(...) # 73| -1: [VarAccess] a0 -# 73| 1: [Method] invoke +# 73| 3: [Method] invoke #-----| 4: (Parameters) # 73| 0: [Parameter] a0 # 73| 5: [BlockStmt] { ... } @@ -1495,66 +1522,6 @@ delegatedProperties.kt: # 73| -3: [TypeAccess] KProperty1 # 73| 0: [TypeAccess] MyClass # 73| 1: [TypeAccess] Integer -# 73| 21: [FieldDeclaration] KProperty1 delegatedToBaseClass2$delegate; -# 73| -1: [TypeAccess] KProperty1 -# 73| 0: [TypeAccess] Base -# 73| 1: [TypeAccess] Integer -# 73| 0: [PropertyRefExpr] ...::... -# 73| -4: [AnonymousClass] new KProperty1(...) { ... } -# 73| 1: [Constructor] -# 73| 5: [BlockStmt] { ... } -# 73| 0: [SuperConstructorInvocationStmt] super(...) -# 73| 1: [Method] get -#-----| 4: (Parameters) -# 73| 0: [Parameter] a0 -# 73| 5: [BlockStmt] { ... } -# 73| 0: [ReturnStmt] return ... -# 73| 0: [MethodAccess] getBaseClassInt(...) -# 73| -1: [VarAccess] a0 -# 73| 1: [Method] invoke -#-----| 4: (Parameters) -# 73| 0: [Parameter] a0 -# 73| 5: [BlockStmt] { ... } -# 73| 0: [ReturnStmt] return ... -# 73| 0: [MethodAccess] get(...) -# 73| -1: [ThisAccess] this -# 73| 0: [VarAccess] a0 -# 73| -3: [TypeAccess] KProperty1 -# 73| 0: [TypeAccess] Base -# 73| 1: [TypeAccess] Integer -# 75| 23: [Method] getDelegatedToAnotherClass1 -# 75| 3: [TypeAccess] int -# 75| 5: [BlockStmt] { ... } -# 75| 0: [ReturnStmt] return ... -# 75| 0: [MethodAccess] getValue(...) -# 75| -2: [TypeAccess] Integer -# 75| -1: [TypeAccess] PropertyReferenceDelegatesKt -# 75| 0: [VarAccess] this.delegatedToAnotherClass1$delegate -# 75| -1: [ThisAccess] this -# 1| 1: [ThisAccess] this -# 75| 2: [PropertyRefExpr] ...::... -# 75| -4: [AnonymousClass] new KProperty1(...) { ... } -# 75| 1: [Constructor] -# 75| 5: [BlockStmt] { ... } -# 75| 0: [SuperConstructorInvocationStmt] super(...) -# 75| 1: [Method] get -#-----| 4: (Parameters) -# 75| 0: [Parameter] a0 -# 75| 5: [BlockStmt] { ... } -# 75| 0: [ReturnStmt] return ... -# 75| 0: [MethodAccess] getDelegatedToAnotherClass1(...) -# 75| -1: [VarAccess] a0 -# 75| 1: [Method] invoke -#-----| 4: (Parameters) -# 75| 0: [Parameter] a0 -# 75| 5: [BlockStmt] { ... } -# 75| 0: [ReturnStmt] return ... -# 75| 0: [MethodAccess] get(...) -# 75| -1: [ThisAccess] this -# 75| 0: [VarAccess] a0 -# 75| -3: [TypeAccess] KProperty1 -# 75| 0: [TypeAccess] MyClass -# 75| 1: [TypeAccess] Integer # 75| 23: [FieldDeclaration] KProperty0 delegatedToAnotherClass1$delegate; # 75| -1: [TypeAccess] KProperty0 # 75| 0: [TypeAccess] Integer @@ -1570,15 +1537,15 @@ delegatedProperties.kt: # 75| 0: [VarAccess] this. # 75| -1: [ThisAccess] this # 75| 1: [VarAccess] -# 75| 1: [FieldDeclaration] ClassWithDelegate ; +# 75| 2: [FieldDeclaration] ClassWithDelegate ; # 75| -1: [TypeAccess] ClassWithDelegate -# 75| 1: [Method] get +# 75| 3: [Method] get # 75| 5: [BlockStmt] { ... } # 75| 0: [ReturnStmt] return ... # 75| 0: [MethodAccess] getAnotherClassInt(...) # 75| -1: [VarAccess] this. # 75| -1: [ThisAccess] this -# 75| 1: [Method] invoke +# 75| 4: [Method] invoke # 75| 5: [BlockStmt] { ... } # 75| 0: [ReturnStmt] return ... # 75| 0: [MethodAccess] get(...) @@ -1588,7 +1555,68 @@ delegatedProperties.kt: # 75| 0: [MethodAccess] getAnotherClassInstance(...) # 75| -1: [ThisAccess] MyClass.this # 75| 0: [TypeAccess] MyClass -# 77| 25: [Method] getDelegatedToTopLevel +# 75| 24: [Method] getDelegatedToAnotherClass1 +# 75| 3: [TypeAccess] int +# 75| 5: [BlockStmt] { ... } +# 75| 0: [ReturnStmt] return ... +# 75| 0: [MethodAccess] getValue(...) +# 75| -2: [TypeAccess] Integer +# 75| -1: [TypeAccess] PropertyReferenceDelegatesKt +# 75| 0: [VarAccess] this.delegatedToAnotherClass1$delegate +# 75| -1: [ThisAccess] this +# 1| 1: [ThisAccess] this +# 75| 2: [PropertyRefExpr] ...::... +# 75| -4: [AnonymousClass] new KProperty1(...) { ... } +# 75| 1: [Constructor] +# 75| 5: [BlockStmt] { ... } +# 75| 0: [SuperConstructorInvocationStmt] super(...) +# 75| 2: [Method] get +#-----| 4: (Parameters) +# 75| 0: [Parameter] a0 +# 75| 5: [BlockStmt] { ... } +# 75| 0: [ReturnStmt] return ... +# 75| 0: [MethodAccess] getDelegatedToAnotherClass1(...) +# 75| -1: [VarAccess] a0 +# 75| 3: [Method] invoke +#-----| 4: (Parameters) +# 75| 0: [Parameter] a0 +# 75| 5: [BlockStmt] { ... } +# 75| 0: [ReturnStmt] return ... +# 75| 0: [MethodAccess] get(...) +# 75| -1: [ThisAccess] this +# 75| 0: [VarAccess] a0 +# 75| -3: [TypeAccess] KProperty1 +# 75| 0: [TypeAccess] MyClass +# 75| 1: [TypeAccess] Integer +# 77| 25: [FieldDeclaration] KMutableProperty0 delegatedToTopLevel$delegate; +# 77| -1: [TypeAccess] KMutableProperty0 +# 77| 0: [TypeAccess] Integer +# 77| 0: [PropertyRefExpr] ...::... +# 77| -4: [AnonymousClass] new KMutableProperty0(...) { ... } +# 77| 1: [Constructor] +# 77| 5: [BlockStmt] { ... } +# 77| 0: [SuperConstructorInvocationStmt] super(...) +# 77| 2: [Method] get +# 77| 5: [BlockStmt] { ... } +# 77| 0: [ReturnStmt] return ... +# 77| 0: [MethodAccess] getTopLevelInt(...) +# 77| -1: [TypeAccess] DelegatedPropertiesKt +# 77| 3: [Method] invoke +# 77| 5: [BlockStmt] { ... } +# 77| 0: [ReturnStmt] return ... +# 77| 0: [MethodAccess] get(...) +# 77| -1: [ThisAccess] this +# 77| 4: [Method] set +#-----| 4: (Parameters) +# 77| 0: [Parameter] a0 +# 77| 5: [BlockStmt] { ... } +# 77| 0: [ReturnStmt] return ... +# 77| 0: [MethodAccess] setTopLevelInt(...) +# 77| -1: [TypeAccess] DelegatedPropertiesKt +# 77| 0: [VarAccess] a0 +# 77| -3: [TypeAccess] KMutableProperty0 +# 77| 0: [TypeAccess] Integer +# 77| 26: [Method] getDelegatedToTopLevel # 77| 3: [TypeAccess] int # 77| 5: [BlockStmt] { ... } # 77| 0: [ReturnStmt] return ... @@ -1603,14 +1631,14 @@ delegatedProperties.kt: # 77| 1: [Constructor] # 77| 5: [BlockStmt] { ... } # 77| 0: [SuperConstructorInvocationStmt] super(...) -# 77| 1: [Method] get +# 77| 2: [Method] get #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 5: [BlockStmt] { ... } # 77| 0: [ReturnStmt] return ... # 77| 0: [MethodAccess] getDelegatedToTopLevel(...) # 77| -1: [VarAccess] a0 -# 77| 1: [Method] invoke +# 77| 3: [Method] invoke #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 5: [BlockStmt] { ... } @@ -1618,7 +1646,7 @@ delegatedProperties.kt: # 77| 0: [MethodAccess] get(...) # 77| -1: [ThisAccess] this # 77| 0: [VarAccess] a0 -# 77| 1: [Method] set +# 77| 4: [Method] set #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 1: [Parameter] a1 @@ -1630,7 +1658,7 @@ delegatedProperties.kt: # 77| -3: [TypeAccess] KMutableProperty1 # 77| 0: [TypeAccess] MyClass # 77| 1: [TypeAccess] Integer -# 77| 25: [Method] setDelegatedToTopLevel +# 77| 27: [Method] setDelegatedToTopLevel # 77| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 77| 0: [Parameter] @@ -1648,14 +1676,14 @@ delegatedProperties.kt: # 77| 1: [Constructor] # 77| 5: [BlockStmt] { ... } # 77| 0: [SuperConstructorInvocationStmt] super(...) -# 77| 1: [Method] get +# 77| 2: [Method] get #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 5: [BlockStmt] { ... } # 77| 0: [ReturnStmt] return ... # 77| 0: [MethodAccess] getDelegatedToTopLevel(...) # 77| -1: [VarAccess] a0 -# 77| 1: [Method] invoke +# 77| 3: [Method] invoke #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 5: [BlockStmt] { ... } @@ -1663,7 +1691,7 @@ delegatedProperties.kt: # 77| 0: [MethodAccess] get(...) # 77| -1: [ThisAccess] this # 77| 0: [VarAccess] a0 -# 77| 1: [Method] set +# 77| 4: [Method] set #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 1: [Parameter] a1 @@ -1676,35 +1704,26 @@ delegatedProperties.kt: # 77| 0: [TypeAccess] MyClass # 77| 1: [TypeAccess] Integer # 77| 3: [VarAccess] -# 77| 25: [FieldDeclaration] KMutableProperty0 delegatedToTopLevel$delegate; -# 77| -1: [TypeAccess] KMutableProperty0 -# 77| 0: [TypeAccess] Integer -# 77| 0: [PropertyRefExpr] ...::... -# 77| -4: [AnonymousClass] new KMutableProperty0(...) { ... } -# 77| 1: [Constructor] -# 77| 5: [BlockStmt] { ... } -# 77| 0: [SuperConstructorInvocationStmt] super(...) -# 77| 1: [Method] get -# 77| 5: [BlockStmt] { ... } -# 77| 0: [ReturnStmt] return ... -# 77| 0: [MethodAccess] getTopLevelInt(...) -# 77| -1: [TypeAccess] DelegatedPropertiesKt -# 77| 1: [Method] invoke -# 77| 5: [BlockStmt] { ... } -# 77| 0: [ReturnStmt] return ... -# 77| 0: [MethodAccess] get(...) -# 77| -1: [ThisAccess] this -# 77| 1: [Method] set -#-----| 4: (Parameters) -# 77| 0: [Parameter] a0 -# 77| 5: [BlockStmt] { ... } -# 77| 0: [ReturnStmt] return ... -# 77| 0: [MethodAccess] setTopLevelInt(...) -# 77| -1: [TypeAccess] DelegatedPropertiesKt -# 77| 0: [VarAccess] a0 -# 77| -3: [TypeAccess] KMutableProperty0 -# 77| 0: [TypeAccess] Integer -# 79| 28: [Method] getMax +# 79| 28: [FieldDeclaration] KProperty0 max$delegate; +# 79| -1: [TypeAccess] KProperty0 +# 79| 0: [TypeAccess] Integer +# 79| 0: [PropertyRefExpr] ...::... +# 79| -4: [AnonymousClass] new KProperty0(...) { ... } +# 79| 1: [Constructor] +# 79| 5: [BlockStmt] { ... } +# 79| 0: [SuperConstructorInvocationStmt] super(...) +# 79| 2: [Method] get +# 79| 5: [BlockStmt] { ... } +# 79| 0: [ReturnStmt] return ... +# 79| 0: [VarAccess] MAX_VALUE +# 79| 3: [Method] invoke +# 79| 5: [BlockStmt] { ... } +# 79| 0: [ReturnStmt] return ... +# 79| 0: [MethodAccess] get(...) +# 79| -1: [ThisAccess] this +# 79| -3: [TypeAccess] KProperty0 +# 79| 0: [TypeAccess] Integer +# 79| 29: [Method] getMax # 79| 3: [TypeAccess] int # 79| 5: [BlockStmt] { ... } # 79| 0: [ReturnStmt] return ... @@ -1719,14 +1738,14 @@ delegatedProperties.kt: # 79| 1: [Constructor] # 79| 5: [BlockStmt] { ... } # 79| 0: [SuperConstructorInvocationStmt] super(...) -# 79| 1: [Method] get +# 79| 2: [Method] get #-----| 4: (Parameters) # 79| 0: [Parameter] a0 # 79| 5: [BlockStmt] { ... } # 79| 0: [ReturnStmt] return ... # 79| 0: [MethodAccess] getMax(...) # 79| -1: [VarAccess] a0 -# 79| 1: [Method] invoke +# 79| 3: [Method] invoke #-----| 4: (Parameters) # 79| 0: [Parameter] a0 # 79| 5: [BlockStmt] { ... } @@ -1737,25 +1756,6 @@ delegatedProperties.kt: # 79| -3: [TypeAccess] KProperty1 # 79| 0: [TypeAccess] MyClass # 79| 1: [TypeAccess] Integer -# 79| 28: [FieldDeclaration] KProperty0 max$delegate; -# 79| -1: [TypeAccess] KProperty0 -# 79| 0: [TypeAccess] Integer -# 79| 0: [PropertyRefExpr] ...::... -# 79| -4: [AnonymousClass] new KProperty0(...) { ... } -# 79| 1: [Constructor] -# 79| 5: [BlockStmt] { ... } -# 79| 0: [SuperConstructorInvocationStmt] super(...) -# 79| 1: [Method] get -# 79| 5: [BlockStmt] { ... } -# 79| 0: [ReturnStmt] return ... -# 79| 0: [VarAccess] MAX_VALUE -# 79| 1: [Method] invoke -# 79| 5: [BlockStmt] { ... } -# 79| 0: [ReturnStmt] return ... -# 79| 0: [MethodAccess] get(...) -# 79| -1: [ThisAccess] this -# 79| -3: [TypeAccess] KProperty0 -# 79| 0: [TypeAccess] Integer # 81| 30: [Method] fn # 81| 3: [TypeAccess] Unit # 81| 5: [BlockStmt] { ... } @@ -1774,20 +1774,20 @@ delegatedProperties.kt: # 82| 0: [VarAccess] this. # 82| -1: [ThisAccess] this # 82| 1: [VarAccess] -# 82| 1: [FieldDeclaration] MyClass ; +# 82| 2: [FieldDeclaration] MyClass ; # 82| -1: [TypeAccess] MyClass -# 82| 1: [Method] get +# 82| 3: [Method] get # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] getMemberInt(...) # 82| -1: [VarAccess] this. # 82| -1: [ThisAccess] this -# 82| 1: [Method] invoke +# 82| 4: [Method] invoke # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] get(...) # 82| -1: [ThisAccess] this -# 82| 1: [Method] set +# 82| 5: [Method] set #-----| 4: (Parameters) # 82| 0: [Parameter] a0 # 82| 5: [BlockStmt] { ... } @@ -1804,7 +1804,7 @@ delegatedProperties.kt: # 82| 1: [Constructor] # 82| 5: [BlockStmt] { ... } # 82| 0: [SuperConstructorInvocationStmt] super(...) -# 82| 1: [Method] +# 82| 2: [Method] # 82| 3: [TypeAccess] int # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... @@ -1818,18 +1818,18 @@ delegatedProperties.kt: # 82| 1: [Constructor] # 82| 5: [BlockStmt] { ... } # 82| 0: [SuperConstructorInvocationStmt] super(...) -# 82| 1: [Method] get +# 82| 2: [Method] get # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] (...) # 82| -1: [ClassInstanceExpr] new (...) # 82| -3: [TypeAccess] Object -# 82| 1: [Method] invoke +# 82| 3: [Method] invoke # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] get(...) # 82| -1: [ThisAccess] this -# 82| 1: [Method] set +# 82| 4: [Method] set #-----| 4: (Parameters) # 82| 0: [Parameter] a0 # 82| 5: [BlockStmt] { ... } @@ -1845,7 +1845,7 @@ delegatedProperties.kt: # 82| 1: [Constructor] # 82| 5: [BlockStmt] { ... } # 82| 0: [SuperConstructorInvocationStmt] super(...) -# 82| 1: [Method] +# 82| 2: [Method] # 82| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 82| 0: [Parameter] value @@ -1862,18 +1862,18 @@ delegatedProperties.kt: # 82| 1: [Constructor] # 82| 5: [BlockStmt] { ... } # 82| 0: [SuperConstructorInvocationStmt] super(...) -# 82| 1: [Method] get +# 82| 2: [Method] get # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] (...) # 82| -1: [ClassInstanceExpr] new (...) # 82| -3: [TypeAccess] Object -# 82| 1: [Method] invoke +# 82| 3: [Method] invoke # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] get(...) # 82| -1: [ThisAccess] this -# 82| 1: [Method] set +# 82| 4: [Method] set #-----| 4: (Parameters) # 82| 0: [Parameter] a0 # 82| 5: [BlockStmt] { ... } @@ -2849,7 +2849,7 @@ exprs.kt: # 142| 0: [ReturnStmt] return ... # 142| 0: [VarAccess] this.n # 142| -1: [ThisAccess] this -# 142| 2: [FieldDeclaration] int n; +# 142| 3: [FieldDeclaration] int n; # 142| -1: [TypeAccess] int # 142| 0: [VarAccess] n # 143| 4: [Method] foo @@ -2875,14 +2875,14 @@ exprs.kt: # 148| 0: [SuperConstructorInvocationStmt] super(...) # 148| 1: [BlockStmt] { ... } # 168| 6: [Class] Direction -# 0| 1: [Method] values -# 0| 3: [TypeAccess] Direction[] -# 0| 0: [TypeAccess] Direction -# 0| 1: [Method] valueOf +# 0| 2: [Method] valueOf # 0| 3: [TypeAccess] Direction #-----| 4: (Parameters) # 0| 0: [Parameter] value # 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Direction[] +# 0| 0: [TypeAccess] Direction # 168| 4: [Constructor] Direction # 168| 5: [BlockStmt] { ... } # 168| 0: [ExprStmt] ; @@ -2907,14 +2907,14 @@ exprs.kt: # 169| 0: [ClassInstanceExpr] new Direction(...) # 169| -3: [TypeAccess] Direction # 172| 7: [Class] Color -# 0| 1: [Method] values -# 0| 3: [TypeAccess] Color[] -# 0| 0: [TypeAccess] Color -# 0| 1: [Method] valueOf +# 0| 2: [Method] valueOf # 0| 3: [TypeAccess] Color #-----| 4: (Parameters) # 0| 0: [Parameter] value # 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Color[] +# 0| 0: [TypeAccess] Color # 172| 4: [Constructor] Color #-----| 4: (Parameters) # 172| 0: [Parameter] rgb @@ -2934,7 +2934,7 @@ exprs.kt: # 172| 0: [ReturnStmt] return ... # 172| 0: [VarAccess] this.rgb # 172| -1: [ThisAccess] this -# 172| 5: [FieldDeclaration] int rgb; +# 172| 6: [FieldDeclaration] int rgb; # 172| -1: [TypeAccess] int # 172| 0: [VarAccess] rgb # 173| 7: [FieldDeclaration] Color RED; @@ -2967,7 +2967,7 @@ exprs.kt: # 186| 0: [ReturnStmt] return ... # 186| 0: [VarAccess] this.a1 # 186| -1: [ThisAccess] this -# 186| 2: [FieldDeclaration] int a1; +# 186| 3: [FieldDeclaration] int a1; # 186| -1: [TypeAccess] int # 186| 0: [IntegerLiteral] 1 # 187| 4: [Method] getObject @@ -2988,12 +2988,6 @@ exprs.kt: # 190| 0: [ExprStmt] ; # 190| 0: [KtInitializerAssignExpr] ...=... # 190| 0: [VarAccess] a3 -# 190| 2: [Method] getA3 -# 190| 3: [TypeAccess] String -# 190| 5: [BlockStmt] { ... } -# 190| 0: [ReturnStmt] return ... -# 190| 0: [VarAccess] this.a3 -# 190| -1: [ThisAccess] this # 190| 2: [FieldDeclaration] String a3; # 190| -1: [TypeAccess] String # 190| 0: [MethodAccess] toString(...) @@ -3001,6 +2995,12 @@ exprs.kt: # 190| 0: [MethodAccess] getA1(...) # 190| -1: [ThisAccess] this # 190| 1: [VarAccess] a2 +# 190| 3: [Method] getA3 +# 190| 3: [TypeAccess] String +# 190| 5: [BlockStmt] { ... } +# 190| 0: [ReturnStmt] return ... +# 190| 0: [VarAccess] this.a3 +# 190| -1: [ThisAccess] this # 189| 1: [ExprStmt] ; # 189| 0: [ClassInstanceExpr] new (...) # 189| -3: [TypeAccess] Interface1 @@ -3494,7 +3494,7 @@ funcExprs.kt: # 22| 1: [Constructor] # 22| 5: [BlockStmt] { ... } # 22| 0: [SuperConstructorInvocationStmt] super(...) -# 22| 1: [Method] invoke +# 22| 2: [Method] invoke # 22| 3: [TypeAccess] int # 22| 5: [BlockStmt] { ... } # 22| 0: [ReturnStmt] return ... @@ -3509,7 +3509,7 @@ funcExprs.kt: # 23| 1: [Constructor] # 23| 5: [BlockStmt] { ... } # 23| 0: [SuperConstructorInvocationStmt] super(...) -# 23| 1: [Method] invoke +# 23| 2: [Method] invoke # 23| 3: [TypeAccess] Object # 23| 5: [BlockStmt] { ... } # 23| 0: [ReturnStmt] return ... @@ -3524,7 +3524,7 @@ funcExprs.kt: # 24| 1: [Constructor] # 24| 5: [BlockStmt] { ... } # 24| 0: [SuperConstructorInvocationStmt] super(...) -# 24| 1: [Method] invoke +# 24| 2: [Method] invoke # 24| 3: [TypeAccess] Object # 24| 5: [BlockStmt] { ... } # 24| 0: [ReturnStmt] return ... @@ -3540,7 +3540,7 @@ funcExprs.kt: # 25| 1: [Constructor] # 25| 5: [BlockStmt] { ... } # 25| 0: [SuperConstructorInvocationStmt] super(...) -# 25| 1: [Method] invoke +# 25| 2: [Method] invoke # 25| 3: [TypeAccess] int #-----| 4: (Parameters) # 25| 0: [Parameter] a @@ -3560,7 +3560,7 @@ funcExprs.kt: # 26| 1: [Constructor] # 26| 5: [BlockStmt] { ... } # 26| 0: [SuperConstructorInvocationStmt] super(...) -# 26| 1: [Method] invoke +# 26| 2: [Method] invoke # 26| 3: [TypeAccess] int #-----| 4: (Parameters) # 26| 0: [Parameter] it @@ -3580,7 +3580,7 @@ funcExprs.kt: # 27| 1: [Constructor] # 27| 5: [BlockStmt] { ... } # 27| 0: [SuperConstructorInvocationStmt] super(...) -# 27| 1: [Method] invoke +# 27| 2: [Method] invoke # 27| 3: [TypeAccess] int #-----| 4: (Parameters) # 27| 0: [Parameter] @@ -3606,7 +3606,7 @@ funcExprs.kt: # 29| 1: [Constructor] # 29| 5: [BlockStmt] { ... } # 29| 0: [SuperConstructorInvocationStmt] super(...) -# 29| 1: [Method] invoke +# 29| 2: [Method] invoke # 29| 3: [TypeAccess] Object #-----| 4: (Parameters) # 29| 0: [Parameter] a @@ -3626,7 +3626,7 @@ funcExprs.kt: # 30| 1: [Constructor] # 30| 5: [BlockStmt] { ... } # 30| 0: [SuperConstructorInvocationStmt] super(...) -# 30| 1: [Method] invoke +# 30| 2: [Method] invoke # 30| 3: [TypeAccess] int #-----| 4: (Parameters) # 30| 0: [Parameter] @@ -3649,7 +3649,7 @@ funcExprs.kt: # 31| 1: [Constructor] # 31| 5: [BlockStmt] { ... } # 31| 0: [SuperConstructorInvocationStmt] super(...) -# 31| 1: [Method] invoke +# 31| 2: [Method] invoke # 31| 3: [TypeAccess] int #-----| 4: (Parameters) # 31| 0: [Parameter] @@ -3672,7 +3672,7 @@ funcExprs.kt: # 32| 1: [Constructor] # 32| 5: [BlockStmt] { ... } # 32| 0: [SuperConstructorInvocationStmt] super(...) -# 32| 1: [ExtensionMethod] invoke +# 32| 2: [ExtensionMethod] invoke # 32| 3: [TypeAccess] int #-----| 4: (Parameters) # 32| 0: [Parameter] $this$functionExpression3 @@ -3697,7 +3697,7 @@ funcExprs.kt: # 33| 1: [Constructor] # 33| 5: [BlockStmt] { ... } # 33| 0: [SuperConstructorInvocationStmt] super(...) -# 33| 1: [Method] invoke +# 33| 2: [Method] invoke # 33| 3: [TypeAccess] Function1 # 33| 0: [TypeAccess] Integer # 33| 1: [TypeAccess] Double @@ -3711,7 +3711,7 @@ funcExprs.kt: # 33| 1: [Constructor] # 33| 5: [BlockStmt] { ... } # 33| 0: [SuperConstructorInvocationStmt] super(...) -# 33| 1: [Method] invoke +# 33| 2: [Method] invoke # 33| 3: [TypeAccess] double #-----| 4: (Parameters) # 33| 0: [Parameter] b @@ -3736,7 +3736,7 @@ funcExprs.kt: # 35| 1: [Constructor] # 35| 5: [BlockStmt] { ... } # 35| 0: [SuperConstructorInvocationStmt] super(...) -# 35| 1: [Method] invoke +# 35| 2: [Method] invoke # 35| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 35| 0: [Parameter] a0 @@ -3821,7 +3821,7 @@ funcExprs.kt: # 36| 1: [Constructor] # 36| 5: [BlockStmt] { ... } # 36| 0: [SuperConstructorInvocationStmt] super(...) -# 36| 1: [Method] invoke +# 36| 2: [Method] invoke # 36| 3: [TypeAccess] String #-----| 4: (Parameters) # 36| 0: [Parameter] a0 @@ -3873,7 +3873,7 @@ funcExprs.kt: # 36| 5: [BlockStmt] { ... } # 36| 0: [ReturnStmt] return ... # 36| 0: [StringLiteral] -# 36| 1: [Method] invoke +# 36| 2: [Method] invoke #-----| 4: (Parameters) # 36| 0: [Parameter] a0 # 36| 5: [BlockStmt] { ... } @@ -4012,14 +4012,14 @@ funcExprs.kt: # 38| 0: [VarAccess] this. # 38| -1: [ThisAccess] this # 38| 1: [VarAccess] -# 38| 1: [Method] invoke +# 38| 2: [FieldDeclaration] FuncRef ; +# 38| -1: [TypeAccess] FuncRef +# 38| 3: [Method] invoke # 38| 5: [BlockStmt] { ... } # 38| 0: [ReturnStmt] return ... # 38| 0: [MethodAccess] f0(...) # 38| -1: [VarAccess] this. # 38| -1: [ThisAccess] this -# 38| 1: [FieldDeclaration] FuncRef ; -# 38| -1: [TypeAccess] FuncRef # 38| -3: [TypeAccess] Function0 # 38| 0: [TypeAccess] Integer # 38| 0: [ClassInstanceExpr] new FuncRef(...) @@ -4039,14 +4039,14 @@ funcExprs.kt: # 39| 0: [VarAccess] this. # 39| -1: [ThisAccess] this # 39| 1: [VarAccess] -# 39| 1: [Method] invoke +# 39| 2: [FieldDeclaration] Companion ; +# 39| -1: [TypeAccess] Companion +# 39| 3: [Method] invoke # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... # 39| 0: [MethodAccess] f0(...) # 39| -1: [VarAccess] this. # 39| -1: [ThisAccess] this -# 39| 1: [FieldDeclaration] Companion ; -# 39| -1: [TypeAccess] Companion # 39| -3: [TypeAccess] Function0 # 39| 0: [TypeAccess] Integer # 39| 0: [VarAccess] Companion @@ -4066,7 +4066,9 @@ funcExprs.kt: # 40| 0: [VarAccess] this. # 40| -1: [ThisAccess] this # 40| 1: [VarAccess] -# 40| 1: [Method] invoke +# 40| 2: [FieldDeclaration] FuncRef ; +# 40| -1: [TypeAccess] FuncRef +# 40| 3: [Method] invoke #-----| 4: (Parameters) # 40| 0: [Parameter] a0 # 40| 5: [BlockStmt] { ... } @@ -4075,8 +4077,6 @@ funcExprs.kt: # 40| -1: [VarAccess] this. # 40| -1: [ThisAccess] this # 40| 0: [VarAccess] a0 -# 40| 1: [FieldDeclaration] FuncRef ; -# 40| -1: [TypeAccess] FuncRef # 40| -3: [TypeAccess] Function1 # 40| 0: [TypeAccess] Integer # 40| 1: [TypeAccess] Integer @@ -4091,7 +4091,7 @@ funcExprs.kt: # 41| 1: [Constructor] # 41| 5: [BlockStmt] { ... } # 41| 0: [SuperConstructorInvocationStmt] super(...) -# 41| 1: [Method] invoke +# 41| 2: [Method] invoke #-----| 4: (Parameters) # 41| 0: [Parameter] a0 # 41| 1: [Parameter] a1 @@ -4120,7 +4120,9 @@ funcExprs.kt: # 42| 0: [VarAccess] this. # 42| -1: [ThisAccess] this # 42| 1: [VarAccess] -# 42| 1: [Method] invoke +# 42| 2: [FieldDeclaration] int ; +# 42| -1: [TypeAccess] int +# 42| 3: [Method] invoke #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 5: [BlockStmt] { ... } @@ -4130,8 +4132,6 @@ funcExprs.kt: # 42| 0: [VarAccess] this. # 42| -1: [ThisAccess] this # 42| 1: [VarAccess] a0 -# 42| 1: [FieldDeclaration] int ; -# 42| -1: [TypeAccess] int # 42| -3: [TypeAccess] Function1 # 42| 0: [TypeAccess] Integer # 42| 1: [TypeAccess] Integer @@ -4145,7 +4145,7 @@ funcExprs.kt: # 43| 1: [Constructor] # 43| 5: [BlockStmt] { ... } # 43| 0: [SuperConstructorInvocationStmt] super(...) -# 43| 1: [Method] invoke +# 43| 2: [Method] invoke #-----| 4: (Parameters) # 43| 0: [Parameter] a0 # 43| 1: [Parameter] a1 @@ -4175,7 +4175,9 @@ funcExprs.kt: # 44| 0: [VarAccess] this. # 44| -1: [ThisAccess] this # 44| 1: [VarAccess] -# 44| 1: [Method] invoke +# 44| 2: [FieldDeclaration] FuncRef ; +# 44| -1: [TypeAccess] FuncRef +# 44| 3: [Method] invoke #-----| 4: (Parameters) # 44| 0: [Parameter] a0 # 44| 1: [Parameter] a1 @@ -4226,8 +4228,6 @@ funcExprs.kt: # 44| 19: [VarAccess] a19 # 44| 20: [VarAccess] a20 # 44| 21: [VarAccess] a21 -# 44| 1: [FieldDeclaration] FuncRef ; -# 44| -1: [TypeAccess] FuncRef # 44| -3: [TypeAccess] Function22 # 44| 0: [TypeAccess] Integer # 44| 1: [TypeAccess] Integer @@ -4270,7 +4270,9 @@ funcExprs.kt: # 45| 0: [VarAccess] this. # 45| -1: [ThisAccess] this # 45| 1: [VarAccess] -# 45| 1: [Method] invoke +# 45| 2: [FieldDeclaration] FuncRef ; +# 45| -1: [TypeAccess] FuncRef +# 45| 3: [Method] invoke #-----| 4: (Parameters) # 45| 0: [Parameter] a0 # 45| 5: [BlockStmt] { ... } @@ -4393,8 +4395,6 @@ funcExprs.kt: # 45| 1: [ArrayAccess] ...[...] # 45| 0: [VarAccess] a0 # 45| 1: [IntegerLiteral] 22 -# 45| 1: [FieldDeclaration] FuncRef ; -# 45| -1: [TypeAccess] FuncRef # 45| -3: [TypeAccess] FunctionN # 45| 0: [TypeAccess] String # 45| 0: [ClassInstanceExpr] new FuncRef(...) @@ -4408,7 +4408,7 @@ funcExprs.kt: # 46| 1: [Constructor] # 46| 5: [BlockStmt] { ... } # 46| 0: [SuperConstructorInvocationStmt] super(...) -# 46| 1: [Method] invoke +# 46| 2: [Method] invoke #-----| 4: (Parameters) # 46| 0: [Parameter] a0 # 46| 5: [BlockStmt] { ... } @@ -4541,7 +4541,7 @@ funcExprs.kt: # 48| 1: [Constructor] # 48| 5: [BlockStmt] { ... } # 48| 0: [SuperConstructorInvocationStmt] super(...) -# 48| 1: [Method] local +# 48| 2: [Method] local # 48| 3: [TypeAccess] int # 48| 5: [BlockStmt] { ... } # 48| 0: [ReturnStmt] return ... @@ -4554,7 +4554,7 @@ funcExprs.kt: # 49| 1: [Constructor] # 49| 5: [BlockStmt] { ... } # 49| 0: [SuperConstructorInvocationStmt] super(...) -# 49| 1: [Method] invoke +# 49| 2: [Method] invoke # 49| 5: [BlockStmt] { ... } # 49| 0: [ReturnStmt] return ... # 49| 0: [MethodAccess] local(...) @@ -4571,7 +4571,7 @@ funcExprs.kt: # 51| 1: [Constructor] # 51| 5: [BlockStmt] { ... } # 51| 0: [SuperConstructorInvocationStmt] super(...) -# 51| 1: [Method] invoke +# 51| 2: [Method] invoke # 51| 5: [BlockStmt] { ... } # 51| 0: [ReturnStmt] return ... # 51| 0: [ClassInstanceExpr] new FuncRef(...) @@ -4755,7 +4755,7 @@ funcExprs.kt: # 75| 1: [Constructor] # 75| 5: [BlockStmt] { ... } # 75| 0: [SuperConstructorInvocationStmt] super(...) -# 75| 1: [Method] invoke +# 75| 2: [Method] invoke # 75| 3: [TypeAccess] String #-----| 4: (Parameters) # 75| 0: [Parameter] a @@ -4813,7 +4813,9 @@ kFunctionInvoke.kt: # 8| 0: [VarAccess] this. # 8| -1: [ThisAccess] this # 8| 1: [VarAccess] -# 8| 1: [Method] invoke +# 8| 2: [FieldDeclaration] A ; +# 8| -1: [TypeAccess] A +# 8| 3: [Method] invoke #-----| 4: (Parameters) # 8| 0: [Parameter] a0 # 8| 5: [BlockStmt] { ... } @@ -4822,8 +4824,6 @@ kFunctionInvoke.kt: # 8| -1: [VarAccess] this. # 8| -1: [ThisAccess] this # 8| 0: [VarAccess] a0 -# 8| 1: [FieldDeclaration] A ; -# 8| -1: [TypeAccess] A # 8| -3: [TypeAccess] Function1 # 8| 0: [TypeAccess] String # 8| 1: [TypeAccess] Unit @@ -4857,7 +4857,7 @@ localFunctionCalls.kt: # 5| 1: [Constructor] # 5| 5: [BlockStmt] { ... } # 5| 0: [SuperConstructorInvocationStmt] super(...) -# 5| 1: [Method] a +# 5| 2: [Method] a #-----| 2: (Generic Parameters) # 5| 0: [TypeVariable] T # 5| 3: [TypeAccess] int @@ -4890,7 +4890,7 @@ localFunctionCalls.kt: # 9| 1: [Constructor] # 9| 5: [BlockStmt] { ... } # 9| 0: [SuperConstructorInvocationStmt] super(...) -# 9| 1: [ExtensionMethod] f1 +# 9| 2: [ExtensionMethod] f1 #-----| 2: (Generic Parameters) # 9| 0: [TypeVariable] T1 # 9| 3: [TypeAccess] int @@ -4957,7 +4957,11 @@ samConversion.kt: # 2| 0: [VarAccess] this. # 2| -1: [ThisAccess] this # 2| 1: [VarAccess] -# 2| 1: [Method] accept +# 2| 2: [FieldDeclaration] Function1 ; +# 2| -1: [TypeAccess] Function1 +# 2| 0: [TypeAccess] Integer +# 2| 1: [TypeAccess] Boolean +# 2| 3: [Method] accept # 2| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 2| 0: [Parameter] i @@ -4967,17 +4971,13 @@ samConversion.kt: # 2| 0: [MethodAccess] invoke(...) # 2| -1: [VarAccess] # 2| 0: [VarAccess] i -# 2| 1: [FieldDeclaration] Function1 ; -# 2| -1: [TypeAccess] Function1 -# 2| 0: [TypeAccess] Integer -# 2| 1: [TypeAccess] Boolean # 2| -3: [TypeAccess] IntPredicate # 2| 0: [LambdaExpr] ...->... # 2| -4: [AnonymousClass] new Function1(...) { ... } # 2| 1: [Constructor] # 2| 5: [BlockStmt] { ... } # 2| 0: [SuperConstructorInvocationStmt] super(...) -# 2| 1: [Method] invoke +# 2| 2: [Method] invoke # 2| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 2| 0: [Parameter] it @@ -5008,7 +5008,12 @@ samConversion.kt: # 4| 0: [VarAccess] this. # 4| -1: [ThisAccess] this # 4| 1: [VarAccess] -# 4| 1: [Method] fn1 +# 4| 2: [FieldDeclaration] Function2 ; +# 4| -1: [TypeAccess] Function2 +# 4| 0: [TypeAccess] Integer +# 4| 1: [TypeAccess] Integer +# 4| 2: [TypeAccess] Unit +# 4| 3: [Method] fn1 # 4| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 4| 0: [Parameter] i @@ -5021,18 +5026,13 @@ samConversion.kt: # 4| -1: [VarAccess] # 4| 0: [VarAccess] i # 4| 1: [VarAccess] j -# 4| 1: [FieldDeclaration] Function2 ; -# 4| -1: [TypeAccess] Function2 -# 4| 0: [TypeAccess] Integer -# 4| 1: [TypeAccess] Integer -# 4| 2: [TypeAccess] Unit # 4| -3: [TypeAccess] InterfaceFn1 # 4| 0: [LambdaExpr] ...->... # 4| -4: [AnonymousClass] new Function2(...) { ... } # 4| 1: [Constructor] # 4| 5: [BlockStmt] { ... } # 4| 0: [SuperConstructorInvocationStmt] super(...) -# 4| 1: [Method] invoke +# 4| 2: [Method] invoke # 4| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 4| 0: [Parameter] a @@ -5062,7 +5062,12 @@ samConversion.kt: # 5| 0: [VarAccess] this. # 5| -1: [ThisAccess] this # 5| 1: [VarAccess] -# 5| 1: [Method] fn1 +# 5| 2: [FieldDeclaration] Function2 ; +# 5| -1: [TypeAccess] Function2 +# 5| 0: [TypeAccess] Integer +# 5| 1: [TypeAccess] Integer +# 5| 2: [TypeAccess] Unit +# 5| 3: [Method] fn1 # 5| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 5| 0: [Parameter] i @@ -5075,18 +5080,13 @@ samConversion.kt: # 5| -1: [VarAccess] # 5| 0: [VarAccess] i # 5| 1: [VarAccess] j -# 5| 1: [FieldDeclaration] Function2 ; -# 5| -1: [TypeAccess] Function2 -# 5| 0: [TypeAccess] Integer -# 5| 1: [TypeAccess] Integer -# 5| 2: [TypeAccess] Unit # 5| -3: [TypeAccess] InterfaceFn1 # 5| 0: [MemberRefExpr] ...::... # 5| -4: [AnonymousClass] new Function2(...) { ... } # 5| 1: [Constructor] # 5| 5: [BlockStmt] { ... } # 5| 0: [SuperConstructorInvocationStmt] super(...) -# 5| 1: [Method] invoke +# 5| 2: [Method] invoke #-----| 4: (Parameters) # 5| 0: [Parameter] a0 # 5| 1: [Parameter] a1 @@ -5116,7 +5116,12 @@ samConversion.kt: # 7| 0: [VarAccess] this. # 7| -1: [ThisAccess] this # 7| 1: [VarAccess] -# 7| 1: [ExtensionMethod] ext +# 7| 2: [FieldDeclaration] Function2 ; +# 7| -1: [TypeAccess] Function2 +# 7| 0: [TypeAccess] String +# 7| 1: [TypeAccess] Integer +# 7| 2: [TypeAccess] Boolean +# 7| 3: [ExtensionMethod] ext # 7| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 7| 0: [Parameter] @@ -5129,18 +5134,13 @@ samConversion.kt: # 7| -1: [VarAccess] # 7| 0: [ExtensionReceiverAccess] this # 7| 1: [VarAccess] i -# 7| 1: [FieldDeclaration] Function2 ; -# 7| -1: [TypeAccess] Function2 -# 7| 0: [TypeAccess] String -# 7| 1: [TypeAccess] Integer -# 7| 2: [TypeAccess] Boolean # 7| -3: [TypeAccess] InterfaceFnExt1 # 7| 0: [LambdaExpr] ...->... # 7| -4: [AnonymousClass] new Function2(...) { ... } # 7| 1: [Constructor] # 7| 5: [BlockStmt] { ... } # 7| 0: [SuperConstructorInvocationStmt] super(...) -# 7| 1: [ExtensionMethod] invoke +# 7| 2: [ExtensionMethod] invoke # 7| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 7| 0: [Parameter] $this$InterfaceFnExt1 @@ -5172,7 +5172,11 @@ samConversion.kt: # 9| 0: [VarAccess] this. # 9| -1: [ThisAccess] this # 9| 1: [VarAccess] -# 9| 1: [Method] accept +# 9| 2: [FieldDeclaration] Function1 ; +# 9| -1: [TypeAccess] Function1 +# 9| 0: [TypeAccess] Integer +# 9| 1: [TypeAccess] Boolean +# 9| 3: [Method] accept # 9| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 9| 0: [Parameter] i @@ -5182,10 +5186,6 @@ samConversion.kt: # 9| 0: [MethodAccess] invoke(...) # 9| -1: [VarAccess] # 9| 0: [VarAccess] i -# 9| 1: [FieldDeclaration] Function1 ; -# 9| -1: [TypeAccess] Function1 -# 9| 0: [TypeAccess] Integer -# 9| 1: [TypeAccess] Boolean # 9| -3: [TypeAccess] IntPredicate # 9| 0: [WhenExpr] when ... # 9| 0: [WhenBranch] ... -> ... @@ -5196,7 +5196,7 @@ samConversion.kt: # 9| 1: [Constructor] # 9| 5: [BlockStmt] { ... } # 9| 0: [SuperConstructorInvocationStmt] super(...) -# 9| 1: [Method] invoke +# 9| 2: [Method] invoke # 9| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 10| 0: [Parameter] j @@ -5219,7 +5219,7 @@ samConversion.kt: # 11| 1: [Constructor] # 11| 5: [BlockStmt] { ... } # 11| 0: [SuperConstructorInvocationStmt] super(...) -# 11| 1: [Method] invoke +# 11| 2: [Method] invoke # 11| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 12| 0: [Parameter] j @@ -5307,7 +5307,7 @@ samConversion.kt: # 41| 1: [Constructor] # 41| 5: [BlockStmt] { ... } # 41| 0: [SuperConstructorInvocationStmt] super(...) -# 41| 1: [Method] invoke +# 41| 2: [Method] invoke #-----| 4: (Parameters) # 41| 0: [Parameter] a0 # 41| 5: [BlockStmt] { ... } @@ -5447,7 +5447,10 @@ samConversion.kt: # 42| 0: [VarAccess] this. # 42| -1: [ThisAccess] this # 42| 1: [VarAccess] -# 42| 1: [Method] accept +# 42| 2: [FieldDeclaration] FunctionN ; +# 42| -1: [TypeAccess] FunctionN +# 42| 0: [TypeAccess] Boolean +# 42| 3: [Method] accept # 42| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 42| 0: [Parameter] i0 @@ -5527,9 +5530,6 @@ samConversion.kt: # 42| 22: [VarAccess] i22 # 42| -1: [TypeAccess] Object # 42| 0: [IntegerLiteral] 23 -# 42| 1: [FieldDeclaration] FunctionN ; -# 42| -1: [TypeAccess] FunctionN -# 42| 0: [TypeAccess] Boolean # 42| -3: [TypeAccess] BigArityPredicate # 42| 0: [VarAccess] a # 43| 2: [LocalVariableDeclStmt] var ...; @@ -5548,7 +5548,10 @@ samConversion.kt: # 43| 0: [VarAccess] this. # 43| -1: [ThisAccess] this # 43| 1: [VarAccess] -# 43| 1: [Method] accept +# 43| 2: [FieldDeclaration] FunctionN ; +# 43| -1: [TypeAccess] FunctionN +# 43| 0: [TypeAccess] Boolean +# 43| 3: [Method] accept # 43| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 43| 0: [Parameter] i0 @@ -5628,16 +5631,13 @@ samConversion.kt: # 43| 22: [VarAccess] i22 # 43| -1: [TypeAccess] Object # 43| 0: [IntegerLiteral] 23 -# 43| 1: [FieldDeclaration] FunctionN ; -# 43| -1: [TypeAccess] FunctionN -# 43| 0: [TypeAccess] Boolean # 43| -3: [TypeAccess] BigArityPredicate # 43| 0: [LambdaExpr] ...->... # 43| -4: [AnonymousClass] new FunctionN(...) { ... } # 43| 1: [Constructor] # 43| 5: [BlockStmt] { ... } # 43| 0: [SuperConstructorInvocationStmt] super(...) -# 43| 1: [Method] invoke +# 43| 2: [Method] invoke # 43| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 43| 0: [Parameter] i0 @@ -5689,7 +5689,7 @@ samConversion.kt: # 45| 5: [BlockStmt] { ... } # 45| 0: [ReturnStmt] return ... # 45| 0: [BooleanLiteral] true -# 43| 1: [Method] invoke +# 43| 2: [Method] invoke #-----| 4: (Parameters) # 43| 0: [Parameter] a0 # 43| 5: [BlockStmt] { ... } @@ -5830,7 +5830,11 @@ samConversion.kt: # 46| 0: [VarAccess] this. # 46| -1: [ThisAccess] this # 46| 1: [VarAccess] -# 46| 1: [Method] fn +# 46| 2: [FieldDeclaration] Function1 ; +# 46| -1: [TypeAccess] Function1 +# 46| 0: [TypeAccess] Integer +# 46| 1: [TypeAccess] Boolean +# 46| 3: [Method] fn # 46| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 46| 0: [Parameter] i @@ -5840,10 +5844,6 @@ samConversion.kt: # 46| 0: [MethodAccess] invoke(...) # 46| -1: [VarAccess] # 46| 0: [VarAccess] i -# 46| 1: [FieldDeclaration] Function1 ; -# 46| -1: [TypeAccess] Function1 -# 46| 0: [TypeAccess] Integer -# 46| 1: [TypeAccess] Boolean # 46| -3: [TypeAccess] SomePredicate # 46| 0: [TypeAccess] Integer # 46| 0: [LambdaExpr] ...->... @@ -5851,7 +5851,7 @@ samConversion.kt: # 46| 1: [Constructor] # 46| 5: [BlockStmt] { ... } # 46| 0: [SuperConstructorInvocationStmt] super(...) -# 46| 1: [Method] invoke +# 46| 2: [Method] invoke # 46| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 46| 0: [Parameter] a 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 ae2d5911e7e..a3ed7a0d3a0 100644 --- a/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected @@ -34,7 +34,7 @@ A.kt: # 13| 0: [ReturnStmt] return ... # 13| 0: [VarAccess] this.prop # 13| -1: [ThisAccess] this -# 13| 6: [FieldDeclaration] int prop; +# 13| 7: [FieldDeclaration] int prop; # 13| -1: [TypeAccess] int # 13| 0: [MethodAccess] fn(...) # 13| -1: [ThisAccess] A.this @@ -74,14 +74,14 @@ A.kt: # 20| 0: [VarAccess] B.x # 20| -1: [TypeAccess] B # 23| 11: [Class] Enu -# 0| 1: [Method] values -# 0| 3: [TypeAccess] Enu[] -# 0| 0: [TypeAccess] Enu -# 0| 1: [Method] valueOf +# 0| 2: [Method] valueOf # 0| 3: [TypeAccess] Enu #-----| 4: (Parameters) # 0| 0: [Parameter] value # 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Enu[] +# 0| 0: [TypeAccess] Enu # 23| 4: [Constructor] Enu # 23| 5: [BlockStmt] { ... } # 23| 0: [ExprStmt] ; diff --git a/java/ql/test/kotlin/library-tests/for-array-iterators/test.expected b/java/ql/test/kotlin/library-tests/for-array-iterators/test.expected new file mode 100644 index 00000000000..ac5821044ff --- /dev/null +++ b/java/ql/test/kotlin/library-tests/for-array-iterators/test.expected @@ -0,0 +1,9 @@ +| test.kt:5:14:5:14 | hasNext(...) | +| test.kt:5:14:5:14 | iterator(...) | +| test.kt:5:14:5:14 | next(...) | +| test.kt:6:14:6:14 | hasNext(...) | +| test.kt:6:14:6:14 | iterator(...) | +| test.kt:6:14:6:14 | next(...) | +| test.kt:7:14:7:14 | hasNext(...) | +| test.kt:7:14:7:14 | iterator(...) | +| test.kt:7:14:7:14 | next(...) | diff --git a/java/ql/test/kotlin/library-tests/for-array-iterators/test.kt b/java/ql/test/kotlin/library-tests/for-array-iterators/test.kt new file mode 100644 index 00000000000..2da3a6e1e0e --- /dev/null +++ b/java/ql/test/kotlin/library-tests/for-array-iterators/test.kt @@ -0,0 +1,11 @@ +fun test(x: Array, y: Array<*>, z: IntArray): Int { + + var ret = 0 + + for (el in x) { ret += 1 } + for (el in y) { ret += 1 } + for (el in z) { ret += 1 } + + return ret + +} diff --git a/java/ql/test/kotlin/library-tests/for-array-iterators/test.ql b/java/ql/test/kotlin/library-tests/for-array-iterators/test.ql new file mode 100644 index 00000000000..ab60ba2525d --- /dev/null +++ b/java/ql/test/kotlin/library-tests/for-array-iterators/test.ql @@ -0,0 +1,4 @@ +import java + +from MethodAccess ma +select ma diff --git a/java/ql/test/kotlin/library-tests/generic-instance-methods/test.expected b/java/ql/test/kotlin/library-tests/generic-instance-methods/test.expected index 13c5c19bd68..b80b1311a64 100644 --- a/java/ql/test/kotlin/library-tests/generic-instance-methods/test.expected +++ b/java/ql/test/kotlin/library-tests/generic-instance-methods/test.expected @@ -14,8 +14,8 @@ calls | test.kt:22:15:22:33 | setter(...) | test.kt:12:1:25:1 | user | test.kt:0:0:0:0 | TestKt | file:///!unknown-binary-location/Generic.class:0:0:0:0 | setter | file:///!unknown-binary-location/Generic.class:0:0:0:0 | Generic | | test.kt:23:15:23:22 | getter(...) | test.kt:12:1:25:1 | user | test.kt:0:0:0:0 | TestKt | file:///!unknown-binary-location/Generic.class:0:0:0:0 | getter | file:///!unknown-binary-location/Generic.class:0:0:0:0 | Generic | constructors -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | Generic2 | Generic2(java.lang.String) | ? extends String | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | Generic2 | Generic2(java.lang.Object) | ? super String | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | Generic2 | Generic2() | | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | Generic2 | Generic2(java.lang.String) | String | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | | Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | Generic2 | Generic2(java.lang.String) | String | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | Generic2(java.lang.Object) | T | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | | Test.java:14:14:14:17 | Test | Test.java:14:14:14:17 | Test | Test() | No parameters | void | Test.java:14:14:14:17 | Test | Test.java:14:14:14:17 | Test | @@ -34,14 +34,14 @@ refTypes | test.kt:1:1:10:1 | Generic | | test.kt:1:15:1:15 | T | #select -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | getter | getter() | No parameters | ? extends String | Test.java:1:7:1:14 | Generic2 | Test.java:9:5:9:10 | getter | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity | identity(java.lang.String) | ? extends String | ? extends String | Test.java:1:7:1:14 | Generic2 | Test.java:8:5:8:12 | identity | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity2 | identity2(java.lang.String) | ? extends String | ? extends String | Test.java:1:7:1:14 | Generic2 | Test.java:7:5:7:13 | identity2 | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | setter | setter(java.lang.String) | ? extends String | void | Test.java:1:7:1:14 | Generic2 | Test.java:10:8:10:13 | setter | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | getter | getter() | No parameters | ? super String | Test.java:1:7:1:14 | Generic2 | Test.java:9:5:9:10 | getter | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity | identity(java.lang.Object) | ? super String | ? super String | Test.java:1:7:1:14 | Generic2 | Test.java:8:5:8:12 | identity | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity2 | identity2(java.lang.Object) | ? super String | ? super String | Test.java:1:7:1:14 | Generic2 | Test.java:7:5:7:13 | identity2 | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | setter | setter(java.lang.Object) | ? super String | void | Test.java:1:7:1:14 | Generic2 | Test.java:10:8:10:13 | setter | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | getter | getter() | No parameters | String | Test.java:1:7:1:14 | Generic2 | Test.java:9:5:9:10 | getter | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity | identity() | | String | Test.java:1:7:1:14 | Generic2 | Test.java:8:5:8:12 | identity | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity2 | identity2() | | String | Test.java:1:7:1:14 | Generic2 | Test.java:7:5:7:13 | identity2 | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | setter | setter() | | void | Test.java:1:7:1:14 | Generic2 | Test.java:10:8:10:13 | setter | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | getter | getter() | No parameters | Object | Test.java:1:7:1:14 | Generic2 | Test.java:9:5:9:10 | getter | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity | identity(java.lang.String) | String | Object | Test.java:1:7:1:14 | Generic2 | Test.java:8:5:8:12 | identity | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity2 | identity2(java.lang.String) | String | Object | Test.java:1:7:1:14 | Generic2 | Test.java:7:5:7:13 | identity2 | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | setter | setter(java.lang.String) | String | void | Test.java:1:7:1:14 | Generic2 | Test.java:10:8:10:13 | setter | | Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | getter | getter() | No parameters | String | Test.java:1:7:1:14 | Generic2 | Test.java:9:5:9:10 | getter | | Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity | identity(java.lang.String) | String | String | Test.java:1:7:1:14 | Generic2 | Test.java:8:5:8:12 | identity | | Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity2 | identity2(java.lang.String) | String | String | Test.java:1:7:1:14 | Generic2 | Test.java:7:5:7:13 | identity2 | diff --git a/java/ql/test/kotlin/library-tests/generics/PrintAst.expected b/java/ql/test/kotlin/library-tests/generics/PrintAst.expected index 37f27bdb483..619ba5f3bcc 100644 --- a/java/ql/test/kotlin/library-tests/generics/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/generics/PrintAst.expected @@ -98,15 +98,15 @@ generics.kt: # 13| 0: [ExprStmt] ; # 13| 0: [KtInitializerAssignExpr] ...=... # 13| 0: [VarAccess] t -# 13| 2: [Method] getT +# 13| 2: [FieldDeclaration] T t; +# 13| -1: [TypeAccess] T +# 13| 0: [VarAccess] t +# 13| 3: [Method] getT # 13| 3: [TypeAccess] T # 13| 5: [BlockStmt] { ... } # 13| 0: [ReturnStmt] return ... # 13| 0: [VarAccess] this.t # 13| -1: [ThisAccess] this -# 13| 2: [FieldDeclaration] T t; -# 13| -1: [TypeAccess] T -# 13| 0: [VarAccess] t # 14| 4: [Method] f1 # 14| 3: [TypeAccess] Unit #-----| 4: (Parameters) diff --git a/java/ql/test/kotlin/library-tests/internal-public-alias/User.java b/java/ql/test/kotlin/library-tests/internal-public-alias/User.java new file mode 100644 index 00000000000..d249e1d36f2 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/internal-public-alias/User.java @@ -0,0 +1,11 @@ +public class User { + + public static int test(Test t) { + + t.setInternalVar$main(t.getInternalVal$main()); + + return t.internalFun$main(); + + } + +} diff --git a/java/ql/test/kotlin/library-tests/internal-public-alias/test.expected b/java/ql/test/kotlin/library-tests/internal-public-alias/test.expected new file mode 100644 index 00000000000..77a06cf7310 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/internal-public-alias/test.expected @@ -0,0 +1,6 @@ +| User.java:3:21:3:24 | test | +| test.kt:3:12:3:30 | getInternalVal$main | +| test.kt:6:3:6:36 | getInternalVal | +| test.kt:8:12:8:30 | getInternalVar$main | +| test.kt:8:12:8:30 | setInternalVar$main | +| test.kt:10:12:10:32 | internalFun$main | 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 new file mode 100644 index 00000000000..e79e6d2f907 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt @@ -0,0 +1,12 @@ +public class Test { + + internal val internalVal = 1 + + // Would clash with the internal val's getter without name mangling and provoke a database inconsistency: + fun getInternalVal() = internalVal + + internal var internalVar = 2 + + internal fun internalFun() = 3 + +} diff --git a/java/ql/test/kotlin/library-tests/internal-public-alias/test.ql b/java/ql/test/kotlin/library-tests/internal-public-alias/test.ql new file mode 100644 index 00000000000..f1355df2e88 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/internal-public-alias/test.ql @@ -0,0 +1,5 @@ +import java + +from Method m +where m.fromSource() +select m diff --git a/java/ql/test/kotlin/library-tests/java-kotlin-collection-type-generic-methods/test.expected b/java/ql/test/kotlin/library-tests/java-kotlin-collection-type-generic-methods/test.expected index 417b8a22399..7995948aa78 100644 --- a/java/ql/test/kotlin/library-tests/java-kotlin-collection-type-generic-methods/test.expected +++ b/java/ql/test/kotlin/library-tests/java-kotlin-collection-type-generic-methods/test.expected @@ -54,7 +54,7 @@ methodWithDuplicate | AbstractList | set | int | | AbstractList | subList | int | | AbstractList | subListRangeCheck | int | -| AbstractMap | containsEntry | Entry | +| AbstractMap | containsEntry$kotlin_stdlib | Entry | | AbstractMap | containsKey | Object | | AbstractMap | containsValue | Object | | AbstractMap | equals | Object | @@ -79,7 +79,7 @@ methodWithDuplicate | AbstractMap | put | V | | AbstractMap | putAll | Map | | AbstractMap | remove | Object | -| AbstractMap | containsEntry | Entry | +| AbstractMap | containsEntry$kotlin_stdlib | Entry | | AbstractMap | containsKey | Object | | AbstractMap | containsValue | Object | | AbstractMap | equals | Object | diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/JavaUser.java b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/JavaUser.java new file mode 100644 index 00000000000..fc079df1ba8 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/JavaUser.java @@ -0,0 +1,22 @@ +public class JavaUser { + + public static void test() { + + HasCompanion.staticMethod("1"); + HasCompanion.Companion.nonStaticMethod("2"); + HasCompanion.setStaticProp(HasCompanion.Companion.getNonStaticProp()); + HasCompanion.Companion.setNonStaticProp(HasCompanion.getStaticProp()); + HasCompanion.Companion.setPropWithStaticGetter(HasCompanion.Companion.getPropWithStaticSetter()); + HasCompanion.setPropWithStaticSetter(HasCompanion.getPropWithStaticGetter()); + + // These extract as static methods, since there is no proxy method in the non-companion object case. + NonCompanion.staticMethod("1"); + NonCompanion.INSTANCE.nonStaticMethod("2"); + NonCompanion.setStaticProp(NonCompanion.INSTANCE.getNonStaticProp()); + NonCompanion.INSTANCE.setNonStaticProp(NonCompanion.getStaticProp()); + NonCompanion.INSTANCE.setPropWithStaticGetter(NonCompanion.INSTANCE.getPropWithStaticSetter()); + NonCompanion.setPropWithStaticSetter(NonCompanion.getPropWithStaticGetter()); + + } + +} diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected new file mode 100644 index 00000000000..1376baa4f1d --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected @@ -0,0 +1,441 @@ +JavaUser.java: +# 0| [CompilationUnit] JavaUser +# 1| 1: [Class] JavaUser +# 3| 2: [Method] test +# 3| 3: [TypeAccess] void +# 3| 5: [BlockStmt] { ... } +# 5| 0: [ExprStmt] ; +# 5| 0: [MethodAccess] staticMethod(...) +# 5| -1: [TypeAccess] HasCompanion +# 5| 0: [StringLiteral] "1" +# 6| 1: [ExprStmt] ; +# 6| 0: [MethodAccess] nonStaticMethod(...) +# 6| -1: [VarAccess] HasCompanion.Companion +# 6| -1: [TypeAccess] HasCompanion +# 6| 0: [StringLiteral] "2" +# 7| 2: [ExprStmt] ; +# 7| 0: [MethodAccess] setStaticProp(...) +# 7| -1: [TypeAccess] HasCompanion +# 7| 0: [MethodAccess] getNonStaticProp(...) +# 7| -1: [VarAccess] HasCompanion.Companion +# 7| -1: [TypeAccess] HasCompanion +# 8| 3: [ExprStmt] ; +# 8| 0: [MethodAccess] setNonStaticProp(...) +# 8| -1: [VarAccess] HasCompanion.Companion +# 8| -1: [TypeAccess] HasCompanion +# 8| 0: [MethodAccess] getStaticProp(...) +# 8| -1: [TypeAccess] HasCompanion +# 9| 4: [ExprStmt] ; +# 9| 0: [MethodAccess] setPropWithStaticGetter(...) +# 9| -1: [VarAccess] HasCompanion.Companion +# 9| -1: [TypeAccess] HasCompanion +# 9| 0: [MethodAccess] getPropWithStaticSetter(...) +# 9| -1: [VarAccess] HasCompanion.Companion +# 9| -1: [TypeAccess] HasCompanion +# 10| 5: [ExprStmt] ; +# 10| 0: [MethodAccess] setPropWithStaticSetter(...) +# 10| -1: [TypeAccess] HasCompanion +# 10| 0: [MethodAccess] getPropWithStaticGetter(...) +# 10| -1: [TypeAccess] HasCompanion +# 13| 6: [ExprStmt] ; +# 13| 0: [MethodAccess] staticMethod(...) +# 13| -1: [TypeAccess] NonCompanion +# 13| 0: [StringLiteral] "1" +# 14| 7: [ExprStmt] ; +# 14| 0: [MethodAccess] nonStaticMethod(...) +# 14| -1: [VarAccess] NonCompanion.INSTANCE +# 14| -1: [TypeAccess] NonCompanion +# 14| 0: [StringLiteral] "2" +# 15| 8: [ExprStmt] ; +# 15| 0: [MethodAccess] setStaticProp(...) +# 15| -1: [TypeAccess] NonCompanion +# 15| 0: [MethodAccess] getNonStaticProp(...) +# 15| -1: [VarAccess] NonCompanion.INSTANCE +# 15| -1: [TypeAccess] NonCompanion +# 16| 9: [ExprStmt] ; +# 16| 0: [MethodAccess] setNonStaticProp(...) +# 16| -1: [VarAccess] NonCompanion.INSTANCE +# 16| -1: [TypeAccess] NonCompanion +# 16| 0: [MethodAccess] getStaticProp(...) +# 16| -1: [TypeAccess] NonCompanion +# 17| 10: [ExprStmt] ; +# 17| 0: [MethodAccess] setPropWithStaticGetter(...) +# 17| -1: [VarAccess] NonCompanion.INSTANCE +# 17| -1: [TypeAccess] NonCompanion +# 17| 0: [MethodAccess] getPropWithStaticSetter(...) +# 17| -1: [VarAccess] NonCompanion.INSTANCE +# 17| -1: [TypeAccess] NonCompanion +# 18| 11: [ExprStmt] ; +# 18| 0: [MethodAccess] setPropWithStaticSetter(...) +# 18| -1: [TypeAccess] NonCompanion +# 18| 0: [MethodAccess] getPropWithStaticGetter(...) +# 18| -1: [TypeAccess] NonCompanion +test.kt: +# 0| [CompilationUnit] test +# 0| 1: [Class] TestKt +# 49| 1: [Method] externalUser +# 49| 3: [TypeAccess] Unit +# 49| 5: [BlockStmt] { ... } +# 52| 0: [ExprStmt] ; +# 52| 0: [ImplicitCoercionToUnitExpr] +# 52| 0: [TypeAccess] Unit +# 52| 1: [MethodAccess] staticMethod(...) +# 52| -1: [VarAccess] Companion +# 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 +# 54| 2: [ExprStmt] ; +# 54| 0: [MethodAccess] setStaticProp(...) +# 54| -1: [VarAccess] Companion +# 54| 0: [MethodAccess] getNonStaticProp(...) +# 54| -1: [VarAccess] Companion +# 55| 3: [ExprStmt] ; +# 55| 0: [MethodAccess] setNonStaticProp(...) +# 55| -1: [VarAccess] Companion +# 55| 0: [MethodAccess] getStaticProp(...) +# 55| -1: [VarAccess] Companion +# 56| 4: [ExprStmt] ; +# 56| 0: [MethodAccess] setPropWithStaticGetter(...) +# 56| -1: [VarAccess] Companion +# 56| 0: [MethodAccess] getPropWithStaticSetter(...) +# 56| -1: [VarAccess] Companion +# 57| 5: [ExprStmt] ; +# 57| 0: [MethodAccess] setPropWithStaticSetter(...) +# 57| -1: [VarAccess] Companion +# 57| 0: [MethodAccess] getPropWithStaticGetter(...) +# 57| -1: [VarAccess] Companion +# 60| 6: [ExprStmt] ; +# 60| 0: [ImplicitCoercionToUnitExpr] +# 60| 0: [TypeAccess] Unit +# 60| 1: [MethodAccess] staticMethod(...) +# 60| -1: [TypeAccess] NonCompanion +# 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 +# 62| 8: [ExprStmt] ; +# 62| 0: [MethodAccess] setStaticProp(...) +# 62| -1: [TypeAccess] NonCompanion +# 62| 0: [MethodAccess] getNonStaticProp(...) +# 62| -1: [VarAccess] INSTANCE +# 63| 9: [ExprStmt] ; +# 63| 0: [MethodAccess] setNonStaticProp(...) +# 63| -1: [VarAccess] INSTANCE +# 63| 0: [MethodAccess] getStaticProp(...) +# 63| -1: [TypeAccess] NonCompanion +# 64| 10: [ExprStmt] ; +# 64| 0: [MethodAccess] setPropWithStaticGetter(...) +# 64| -1: [VarAccess] INSTANCE +# 64| 0: [MethodAccess] getPropWithStaticSetter(...) +# 64| -1: [VarAccess] INSTANCE +# 65| 11: [ExprStmt] ; +# 65| 0: [MethodAccess] setPropWithStaticSetter(...) +# 65| -1: [TypeAccess] NonCompanion +# 65| 0: [MethodAccess] getPropWithStaticGetter(...) +# 65| -1: [TypeAccess] NonCompanion +# 9| 2: [Class] HasCompanion +#-----| -3: (Annotations) +# 9| 2: [Constructor] HasCompanion +# 9| 5: [BlockStmt] { ... } +# 9| 0: [SuperConstructorInvocationStmt] super(...) +# 9| 1: [BlockStmt] { ... } +# 11| 3: [Class] Companion +#-----| -3: (Annotations) +# 11| 1: [Constructor] Companion +# 11| 5: [BlockStmt] { ... } +# 11| 0: [SuperConstructorInvocationStmt] super(...) +# 11| 1: [BlockStmt] { ... } +# 16| 0: [ExprStmt] ; +# 16| 0: [KtInitializerAssignExpr] ...=... +# 16| 0: [VarAccess] staticProp +# 17| 1: [ExprStmt] ; +# 17| 0: [KtInitializerAssignExpr] ...=... +# 17| 0: [VarAccess] nonStaticProp +# 13| 2: [Method] staticMethod +#-----| 1: (Annotations) +# 13| 3: [TypeAccess] String +#-----| 4: (Parameters) +# 13| 0: [Parameter] s +#-----| -1: (Annotations) +# 13| 0: [TypeAccess] String +# 13| 5: [BlockStmt] { ... } +# 13| 0: [ReturnStmt] return ... +# 13| 0: [MethodAccess] nonStaticMethod(...) +# 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 ... +# 14| 0: [MethodAccess] staticMethod(...) +# 14| -1: [ThisAccess] this +# 14| 0: [VarAccess] s +# 16| 4: [FieldDeclaration] String staticProp; +# 16| -1: [TypeAccess] String +# 16| 0: [StringLiteral] a +# 16| 5: [Method] getStaticProp +#-----| 1: (Annotations) +# 16| 3: [TypeAccess] String +# 16| 5: [BlockStmt] { ... } +# 16| 0: [ReturnStmt] return ... +# 16| 0: [VarAccess] this.staticProp +# 16| -1: [ThisAccess] this +# 16| 6: [Method] setStaticProp +# 16| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 16| 0: [Parameter] +#-----| -1: (Annotations) +# 16| 0: [TypeAccess] String +# 16| 5: [BlockStmt] { ... } +# 16| 0: [ExprStmt] ; +# 16| 0: [AssignExpr] ...=... +# 16| 0: [VarAccess] this.staticProp +# 16| -1: [ThisAccess] this +# 16| 1: [VarAccess] +# 17| 7: [FieldDeclaration] String nonStaticProp; +# 17| -1: [TypeAccess] String +# 17| 0: [StringLiteral] b +# 17| 8: [Method] getNonStaticProp +#-----| 1: (Annotations) +# 17| 3: [TypeAccess] String +# 17| 5: [BlockStmt] { ... } +# 17| 0: [ReturnStmt] return ... +# 17| 0: [VarAccess] this.nonStaticProp +# 17| -1: [ThisAccess] this +# 17| 9: [Method] setNonStaticProp +# 17| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 17| 0: [Parameter] +#-----| -1: (Annotations) +# 17| 0: [TypeAccess] String +# 17| 5: [BlockStmt] { ... } +# 17| 0: [ExprStmt] ; +# 17| 0: [AssignExpr] ...=... +# 17| 0: [VarAccess] this.nonStaticProp +# 17| -1: [ThisAccess] this +# 17| 1: [VarAccess] +# 20| 10: [Method] getPropWithStaticGetter +#-----| 1: (Annotations) +# 20| 3: [TypeAccess] String +# 20| 5: [BlockStmt] { ... } +# 20| 0: [ReturnStmt] return ... +# 20| 0: [MethodAccess] getPropWithStaticSetter(...) +# 20| -1: [ThisAccess] this +# 21| 11: [Method] setPropWithStaticGetter +# 21| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 21| 0: [Parameter] s +#-----| -1: (Annotations) +# 21| 0: [TypeAccess] String +# 21| 5: [BlockStmt] { ... } +# 21| 0: [ExprStmt] ; +# 21| 0: [MethodAccess] setPropWithStaticSetter(...) +# 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 ... +# 24| 0: [MethodAccess] getPropWithStaticGetter(...) +# 24| -1: [ThisAccess] this +# 25| 13: [Method] setPropWithStaticSetter +#-----| 1: (Annotations) +# 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: [TypeAccess] String +#-----| 4: (Parameters) +# 13| 0: [Parameter] s +#-----| -1: (Annotations) +# 13| 0: [TypeAccess] String +# 13| 5: [BlockStmt] { ... } +# 13| 0: [ReturnStmt] return ... +# 13| 0: [MethodAccess] staticMethod(...) +# 13| -1: [VarAccess] HasCompanion.Companion +# 13| -1: [TypeAccess] HasCompanion +# 13| 0: [VarAccess] s +# 16| 5: [Method] getStaticProp +#-----| 1: (Annotations) +# 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| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 16| 0: [Parameter] +#-----| -1: (Annotations) +# 16| 0: [TypeAccess] String +# 16| 5: [BlockStmt] { ... } +# 16| 0: [ReturnStmt] return ... +# 16| 0: [MethodAccess] setStaticProp(...) +# 16| -1: [VarAccess] HasCompanion.Companion +# 16| -1: [TypeAccess] HasCompanion +# 16| 0: [VarAccess] +# 20| 7: [Method] getPropWithStaticGetter +#-----| 1: (Annotations) +# 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| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 25| 0: [Parameter] s +#-----| -1: (Annotations) +# 25| 0: [TypeAccess] String +# 25| 5: [BlockStmt] { ... } +# 25| 0: [ReturnStmt] return ... +# 25| 0: [MethodAccess] setPropWithStaticSetter(...) +# 25| -1: [VarAccess] HasCompanion.Companion +# 25| -1: [TypeAccess] HasCompanion +# 25| 0: [VarAccess] s +# 31| 3: [Class] NonCompanion +#-----| -3: (Annotations) +# 31| 2: [Constructor] NonCompanion +# 31| 5: [BlockStmt] { ... } +# 31| 0: [SuperConstructorInvocationStmt] super(...) +# 31| 1: [BlockStmt] { ... } +# 36| 0: [ExprStmt] ; +# 36| 0: [KtInitializerAssignExpr] ...=... +# 36| 0: [VarAccess] staticProp +# 37| 1: [ExprStmt] ; +# 37| 0: [KtInitializerAssignExpr] ...=... +# 37| 0: [VarAccess] nonStaticProp +# 33| 3: [Method] staticMethod +#-----| 1: (Annotations) +# 33| 3: [TypeAccess] String +#-----| 4: (Parameters) +# 33| 0: [Parameter] s +#-----| -1: (Annotations) +# 33| 0: [TypeAccess] String +# 33| 5: [BlockStmt] { ... } +# 33| 0: [ReturnStmt] return ... +# 33| 0: [MethodAccess] nonStaticMethod(...) +# 33| -1: [VarAccess] NonCompanion.INSTANCE +# 33| -1: [TypeAccess] NonCompanion +# 33| 0: [VarAccess] s +# 34| 4: [Method] nonStaticMethod +#-----| 1: (Annotations) +# 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| -1: [TypeAccess] String +# 36| 0: [StringLiteral] a +# 36| 6: [Method] getStaticProp +#-----| 1: (Annotations) +# 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| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 36| 0: [Parameter] +#-----| -1: (Annotations) +# 36| 0: [TypeAccess] String +# 36| 5: [BlockStmt] { ... } +# 36| 0: [ExprStmt] ; +# 36| 0: [AssignExpr] ...=... +# 36| 0: [VarAccess] NonCompanion.INSTANCE.staticProp +# 36| -1: [VarAccess] NonCompanion.INSTANCE +# 36| -1: [TypeAccess] NonCompanion +# 36| 1: [VarAccess] +# 37| 8: [FieldDeclaration] String nonStaticProp; +# 37| -1: [TypeAccess] String +# 37| 0: [StringLiteral] b +# 37| 9: [Method] getNonStaticProp +#-----| 1: (Annotations) +# 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| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 37| 0: [Parameter] +#-----| -1: (Annotations) +# 37| 0: [TypeAccess] String +# 37| 5: [BlockStmt] { ... } +# 37| 0: [ExprStmt] ; +# 37| 0: [AssignExpr] ...=... +# 37| 0: [VarAccess] this.nonStaticProp +# 37| -1: [ThisAccess] this +# 37| 1: [VarAccess] +# 40| 11: [Method] getPropWithStaticGetter +#-----| 1: (Annotations) +# 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| 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| 3: [TypeAccess] String +# 44| 5: [BlockStmt] { ... } +# 44| 0: [ReturnStmt] return ... +# 44| 0: [MethodAccess] getPropWithStaticGetter(...) +# 44| -1: [TypeAccess] NonCompanion +# 45| 14: [Method] setPropWithStaticSetter +#-----| 1: (Annotations) +# 45| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 45| 0: [Parameter] s +#-----| -1: (Annotations) +# 45| 0: [TypeAccess] String +# 45| 5: [BlockStmt] { ... } +# 45| 0: [ExprStmt] ; +# 45| 0: [MethodAccess] setPropWithStaticGetter(...) +# 45| -1: [VarAccess] NonCompanion.INSTANCE +# 45| -1: [TypeAccess] NonCompanion +# 45| 0: [VarAccess] s diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.qlref b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.qlref new file mode 100644 index 00000000000..c7fd5faf239 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/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/jvmstatic-annotation/test.expected b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.expected new file mode 100644 index 00000000000..ae431e80343 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.expected @@ -0,0 +1,74 @@ +staticMembers +| JavaUser.java:1:14:1:21 | JavaUser | JavaUser.java:3:22:3:25 | test | Method | +| test.kt:0:0:0:0 | TestKt | test.kt:49:1:67:1 | externalUser | Method | +| test.kt:9:1:29:1 | HasCompanion | test.kt:11:3:27:3 | Companion | Class | +| test.kt:9:1:29:1 | HasCompanion | test.kt:11:3:27:3 | Companion | Field | +| test.kt:9:1:29:1 | HasCompanion | test.kt:13:16:13:71 | staticMethod | Method | +| test.kt:9:1:29:1 | HasCompanion | test.kt:16:16:16:43 | getStaticProp | Method | +| test.kt:9:1:29:1 | HasCompanion | test.kt:16:16:16:43 | setStaticProp | Method | +| test.kt:9:1:29:1 | HasCompanion | test.kt:20:18:20:45 | getPropWithStaticGetter | Method | +| test.kt:9:1:29:1 | HasCompanion | test.kt:25:18:25:60 | setPropWithStaticSetter | Method | +| test.kt:31:1:47:1 | NonCompanion | test.kt:31:1:47:1 | INSTANCE | Field | +| test.kt:31:1:47:1 | NonCompanion | test.kt:33:14:33:69 | staticMethod | Method | +| test.kt:31:1:47:1 | NonCompanion | test.kt:36:14:36:41 | getStaticProp | Method | +| test.kt:31:1:47:1 | NonCompanion | test.kt:36:14:36:41 | setStaticProp | Method | +| test.kt:31:1:47:1 | NonCompanion | test.kt:40:16:40:43 | getPropWithStaticGetter | Method | +| test.kt:31:1:47:1 | NonCompanion | test.kt:45:16:45:58 | setPropWithStaticSetter | Method | +#select +| test.kt:9:1:29:1 | HasCompanion | JavaUser.java:5:5:5:34 | staticMethod(...) | JavaUser.java:5:5:5:16 | HasCompanion | static | +| test.kt:9:1:29:1 | HasCompanion | JavaUser.java:7:5:7:73 | setStaticProp(...) | JavaUser.java:7:5:7:16 | HasCompanion | static | +| test.kt:9:1:29:1 | HasCompanion | JavaUser.java:8:45:8:72 | getStaticProp(...) | JavaUser.java:8:45:8:56 | HasCompanion | static | +| test.kt:9:1:29:1 | HasCompanion | JavaUser.java:10:5:10:80 | setPropWithStaticSetter(...) | JavaUser.java:10:5:10:16 | HasCompanion | static | +| test.kt:9:1:29:1 | HasCompanion | JavaUser.java:10:42:10:79 | getPropWithStaticGetter(...) | JavaUser.java:10:42:10:53 | HasCompanion | static | +| test.kt:11:3:27:3 | Companion | JavaUser.java:6:5:6:47 | nonStaticMethod(...) | JavaUser.java:6:5:6:26 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | JavaUser.java:7:32:7:72 | getNonStaticProp(...) | JavaUser.java:7:32:7:53 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | JavaUser.java:8:5:8:73 | setNonStaticProp(...) | JavaUser.java:8:5:8:26 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | JavaUser.java:9:5:9:100 | setPropWithStaticGetter(...) | JavaUser.java:9:5:9:26 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | JavaUser.java:9:52:9:99 | getPropWithStaticSetter(...) | JavaUser.java:9:52:9:73 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:13:16:13:71 | staticMethod(...) | test.kt:13:16:13:71 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:13:54:13:71 | nonStaticMethod(...) | test.kt:13:54:13:71 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:14:46:14:60 | staticMethod(...) | test.kt:14:46:14:60 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:16:16:16:43 | getStaticProp(...) | test.kt:16:16:16:43 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:16:16:16:43 | setStaticProp(...) | test.kt:16:16:16:43 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:20:18:20:45 | getPropWithStaticGetter(...) | test.kt:20:18:20:45 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:20:26:20:45 | getPropWithStaticSetter(...) | test.kt:20:26:20:45 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:21:24:21:43 | setPropWithStaticSetter(...) | test.kt:21:24:21:43 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:24:15:24:34 | getPropWithStaticGetter(...) | test.kt:24:15:24:34 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:25:18:25:60 | setPropWithStaticSetter(...) | test.kt:25:18:25:60 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:25:35:25:54 | setPropWithStaticGetter(...) | test.kt:25:35:25:54 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:52:16:52:32 | staticMethod(...) | test.kt:52:3:52:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:53:16:53:35 | nonStaticMethod(...) | test.kt:53:3:53:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:54:3:54:25 | setStaticProp(...) | test.kt:54:3:54:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:54:42:54:54 | getNonStaticProp(...) | test.kt:54:29:54:40 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:55:3:55:28 | setNonStaticProp(...) | test.kt:55:3:55:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:55:45:55:54 | getStaticProp(...) | test.kt:55:32:55:43 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:56:3:56:35 | setPropWithStaticGetter(...) | test.kt:56:3:56:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:56:52:56:71 | getPropWithStaticSetter(...) | test.kt:56:39:56:50 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:57:3:57:35 | setPropWithStaticSetter(...) | test.kt:57:3:57:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:57:52:57:71 | getPropWithStaticGetter(...) | test.kt:57:39:57:50 | Companion | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:13:5:13:34 | staticMethod(...) | JavaUser.java:13:5:13:16 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:14:5:14:46 | nonStaticMethod(...) | JavaUser.java:14:5:14:25 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:15:5:15:72 | setStaticProp(...) | JavaUser.java:15:5:15:16 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:15:32:15:71 | getNonStaticProp(...) | JavaUser.java:15:32:15:52 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:16:5:16:72 | setNonStaticProp(...) | JavaUser.java:16:5:16:25 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:16:44:16:71 | getStaticProp(...) | JavaUser.java:16:44:16:55 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:17:5:17:98 | setPropWithStaticGetter(...) | JavaUser.java:17:5:17:25 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:17:51:17:97 | getPropWithStaticSetter(...) | JavaUser.java:17:51:17:71 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:18:5:18:80 | setPropWithStaticSetter(...) | JavaUser.java:18:5:18:16 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:18:42:18:79 | getPropWithStaticGetter(...) | JavaUser.java:18:42:18:53 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:33:52:33:69 | nonStaticMethod(...) | test.kt:33:52:33:69 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:34:44:34:58 | staticMethod(...) | test.kt:34:44:34:58 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:40:24:40:43 | getPropWithStaticSetter(...) | test.kt:40:24:40:43 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:41:22:41:41 | setPropWithStaticSetter(...) | test.kt:41:22:41:41 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:44:13:44:32 | getPropWithStaticGetter(...) | test.kt:44:13:44:32 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:45:33:45:52 | setPropWithStaticGetter(...) | test.kt:45:33:45:52 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:60:16:60:32 | staticMethod(...) | test.kt:60:16:60:32 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:61:16:61:35 | nonStaticMethod(...) | test.kt:61:3:61:14 | INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:62:3:62:25 | setStaticProp(...) | test.kt:62:3:62:25 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:62:42:62:54 | getNonStaticProp(...) | test.kt:62:29:62:40 | INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:63:3:63:28 | setNonStaticProp(...) | test.kt:63:3:63:14 | INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:63:45:63:54 | getStaticProp(...) | test.kt:63:45:63:54 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:64:3:64:35 | setPropWithStaticGetter(...) | test.kt:64:3:64:14 | INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:64:52:64:71 | getPropWithStaticSetter(...) | test.kt:64:39:64:50 | INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:65:3:65:35 | setPropWithStaticSetter(...) | test.kt:65:3:65:35 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:65:52:65:71 | getPropWithStaticGetter(...) | test.kt:65:52:65:71 | NonCompanion | static | diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt new file mode 100644 index 00000000000..cbf553725b4 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt @@ -0,0 +1,67 @@ +// Test both definining static members, and referring to an object's other static members, in companion object and non-companion object contexts. +// For the companion object all the references to other properties and methods should extract as ordinary instance calls and field read and writes, +// but those methods / getters / setters that are annotated static should get an additional static proxy method defined on the surrounding class-- +// for example, we should see (using Java notation) public static String HasCompanion.staticMethod(String s) { return Companion.staticMethod(s); }. +// For the non-companion object, the static-annotated methods should themselves be extracted as static members, and calls / gets / sets that use them +// should extract as static calls. Static members using non-static ones should extract like staticMethod(...) { INSTANCE.nonStaticMethod(...) }, +// where the reference to INSTANCE replaces what would normally be a `this` reference. + +public class HasCompanion { + + companion object { + + @JvmStatic fun staticMethod(s: String): String = nonStaticMethod(s) + fun nonStaticMethod(s: String): String = staticMethod(s) + + @JvmStatic var staticProp: String = "a" + var nonStaticProp: String = "b" + + var propWithStaticGetter: String + @JvmStatic get() = propWithStaticSetter + set(s: String) { propWithStaticSetter = s } + + var propWithStaticSetter: String + get() = propWithStaticGetter + @JvmStatic set(s: String) { propWithStaticGetter = s } + + } + +} + +object NonCompanion { + + @JvmStatic fun staticMethod(s: String): String = nonStaticMethod(s) + fun nonStaticMethod(s: String): String = staticMethod(s) + + @JvmStatic var staticProp: String = "a" + var nonStaticProp: String = "b" + + var propWithStaticGetter: String + @JvmStatic get() = propWithStaticSetter + set(s: String) { propWithStaticSetter = s } + + var propWithStaticSetter: String + get() = propWithStaticGetter + @JvmStatic set(s: String) { propWithStaticGetter = s } + +} + +fun externalUser() { + + // These all extract as instance calls (to HasCompanion.Companion), since a Kotlin caller won't use the static proxy methods generated by the @JvmStatic annotation. + HasCompanion.staticMethod("1") + HasCompanion.nonStaticMethod("2") + HasCompanion.staticProp = HasCompanion.nonStaticProp + HasCompanion.nonStaticProp = HasCompanion.staticProp + HasCompanion.propWithStaticGetter = HasCompanion.propWithStaticSetter + HasCompanion.propWithStaticSetter = HasCompanion.propWithStaticGetter + + // These extract as static methods, since there is no proxy method in the non-companion object case. + NonCompanion.staticMethod("1") + NonCompanion.nonStaticMethod("2") + NonCompanion.staticProp = NonCompanion.nonStaticProp + NonCompanion.nonStaticProp = NonCompanion.staticProp + NonCompanion.propWithStaticGetter = NonCompanion.propWithStaticSetter + NonCompanion.propWithStaticSetter = NonCompanion.propWithStaticGetter + +} diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql new file mode 100644 index 00000000000..725ba05a106 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql @@ -0,0 +1,16 @@ +import java + +query predicate staticMembers(RefType declType, Member m, string kind) { + m.fromSource() and + m.isStatic() and + m.getDeclaringType() = declType and + kind = m.getAPrimaryQlClass() +} + +from Call call, Callable callable, RefType declType, Expr qualifier, string callType +where + call.getCallee() = callable and + declType = callable.getDeclaringType() and + qualifier = call.getQualifier() and + if callable.isStatic() then callType = "static" else callType = "instance" +select declType, call, qualifier, callType diff --git a/java/ql/test/kotlin/library-tests/methods/delegates.kt b/java/ql/test/kotlin/library-tests/methods/delegates.kt new file mode 100644 index 00000000000..cd475a51cec --- /dev/null +++ b/java/ql/test/kotlin/library-tests/methods/delegates.kt @@ -0,0 +1,12 @@ +import kotlin.properties.Delegates + +class MyClass { + val lazyProp by lazy { + 5 + } + + var observableProp: String by Delegates.observable("") { + prop, old, new -> + println("Was $old, now $new") + } +} diff --git a/java/ql/test/kotlin/library-tests/methods/exprs.expected b/java/ql/test/kotlin/library-tests/methods/exprs.expected index abad65d5f83..b0a7e618de8 100644 --- a/java/ql/test/kotlin/library-tests/methods/exprs.expected +++ b/java/ql/test/kotlin/library-tests/methods/exprs.expected @@ -104,6 +104,97 @@ | dataClass.kt:1:34:1:46 | this.y | VarAccess | | dataClass.kt:1:34:1:46 | y | VarAccess | | dataClass.kt:1:34:1:46 | y | VarAccess | +| delegates.kt:1:9:1:12 | this | ThisAccess | +| delegates.kt:1:9:1:12 | this | ThisAccess | +| delegates.kt:1:9:1:12 | this | ThisAccess | +| delegates.kt:4:18:6:5 | ...::... | PropertyRefExpr | +| delegates.kt:4:18:6:5 | ...=... | KtInitializerAssignExpr | +| delegates.kt:4:18:6:5 | Integer | TypeAccess | +| delegates.kt:4:18:6:5 | Integer | TypeAccess | +| delegates.kt:4:18:6:5 | KProperty1 | TypeAccess | +| delegates.kt:4:18:6:5 | Lazy | TypeAccess | +| delegates.kt:4:18:6:5 | MyClass | TypeAccess | +| delegates.kt:4:18:6:5 | a0 | VarAccess | +| delegates.kt:4:18:6:5 | a0 | VarAccess | +| delegates.kt:4:18:6:5 | get(...) | MethodAccess | +| delegates.kt:4:18:6:5 | getLazyProp(...) | MethodAccess | +| delegates.kt:4:18:6:5 | int | TypeAccess | +| delegates.kt:4:18:6:5 | lazyProp$delegate | VarAccess | +| delegates.kt:4:18:6:5 | this | ThisAccess | +| delegates.kt:4:18:6:5 | this | ThisAccess | +| delegates.kt:4:18:6:5 | this.lazyProp$delegate | VarAccess | +| delegates.kt:4:21:6:5 | Integer | TypeAccess | +| delegates.kt:4:21:6:5 | Integer | TypeAccess | +| delegates.kt:4:21:6:5 | LazyKt | TypeAccess | +| delegates.kt:4:21:6:5 | LazyKt | TypeAccess | +| delegates.kt:4:21:6:5 | getValue(...) | MethodAccess | +| delegates.kt:4:21:6:5 | lazy(...) | MethodAccess | +| delegates.kt:4:26:6:5 | ...->... | LambdaExpr | +| delegates.kt:4:26:6:5 | Function0 | TypeAccess | +| delegates.kt:4:26:6:5 | Integer | TypeAccess | +| delegates.kt:4:26:6:5 | int | TypeAccess | +| delegates.kt:5:9:5:9 | 5 | IntegerLiteral | +| delegates.kt:8:32:11:5 | ...::... | PropertyRefExpr | +| delegates.kt:8:32:11:5 | ...::... | PropertyRefExpr | +| delegates.kt:8:32:11:5 | ...=... | KtInitializerAssignExpr | +| delegates.kt:8:32:11:5 | KMutableProperty1 | TypeAccess | +| delegates.kt:8:32:11:5 | KMutableProperty1 | TypeAccess | +| delegates.kt:8:32:11:5 | MyClass | TypeAccess | +| delegates.kt:8:32:11:5 | MyClass | TypeAccess | +| delegates.kt:8:32:11:5 | Object | TypeAccess | +| delegates.kt:8:32:11:5 | ReadWriteProperty | TypeAccess | +| delegates.kt:8:32:11:5 | String | TypeAccess | +| delegates.kt:8:32:11:5 | String | TypeAccess | +| delegates.kt:8:32:11:5 | String | TypeAccess | +| delegates.kt:8:32:11:5 | String | TypeAccess | +| delegates.kt:8:32:11:5 | String | TypeAccess | +| delegates.kt:8:32:11:5 | Unit | TypeAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a1 | VarAccess | +| delegates.kt:8:32:11:5 | a1 | VarAccess | +| delegates.kt:8:32:11:5 | get(...) | MethodAccess | +| delegates.kt:8:32:11:5 | get(...) | MethodAccess | +| delegates.kt:8:32:11:5 | getObservableProp(...) | MethodAccess | +| delegates.kt:8:32:11:5 | getObservableProp(...) | MethodAccess | +| delegates.kt:8:32:11:5 | observableProp$delegate | VarAccess | +| delegates.kt:8:32:11:5 | setObservableProp(...) | MethodAccess | +| delegates.kt:8:32:11:5 | setObservableProp(...) | MethodAccess | +| delegates.kt:8:32:11:5 | this | ThisAccess | +| delegates.kt:8:32:11:5 | this | ThisAccess | +| delegates.kt:8:32:11:5 | this | ThisAccess | +| delegates.kt:8:32:11:5 | this | ThisAccess | +| delegates.kt:8:32:11:5 | this.observableProp$delegate | VarAccess | +| delegates.kt:8:32:11:5 | this.observableProp$delegate | VarAccess | +| delegates.kt:8:35:8:43 | INSTANCE | VarAccess | +| delegates.kt:8:35:11:5 | | VarAccess | +| delegates.kt:8:35:11:5 | getValue(...) | MethodAccess | +| delegates.kt:8:35:11:5 | setValue(...) | MethodAccess | +| delegates.kt:8:45:11:5 | String | TypeAccess | +| delegates.kt:8:45:11:5 | observable(...) | MethodAccess | +| 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 | +| delegates.kt:8:66:11:5 | String | TypeAccess | +| delegates.kt:8:66:11:5 | String | TypeAccess | +| delegates.kt:8:66:11:5 | Unit | TypeAccess | +| delegates.kt:8:66:11:5 | Unit | TypeAccess | +| delegates.kt:9:9:9:12 | ? ... | WildcardTypeAccess | +| delegates.kt:9:9:9:12 | KProperty | TypeAccess | +| delegates.kt:9:15:9:17 | String | TypeAccess | +| delegates.kt:9:20:9:22 | String | TypeAccess | +| 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:23:10:25 | old | VarAccess | +| 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 | | enumClass.kt:0:0:0:0 | EnumClass[] | TypeAccess | @@ -205,3 +296,4 @@ | methods.kt:16:13:16:31 | Unit | TypeAccess | | methods.kt:17:14:17:33 | Unit | TypeAccess | | methods.kt:18:5:18:36 | Unit | TypeAccess | +| methods.kt:19:12:19:29 | Unit | TypeAccess | diff --git a/java/ql/test/kotlin/library-tests/methods/methods.expected b/java/ql/test/kotlin/library-tests/methods/methods.expected index 144e71e5d48..8067838d889 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods.expected +++ b/java/ql/test/kotlin/library-tests/methods/methods.expected @@ -11,6 +11,19 @@ methods | 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 | +| 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: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 | | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | | () | | 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 | @@ -24,15 +37,22 @@ methods | 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 | | | methods.kt:0:0:0:0 | MethodsKt | methods.kt:2:1:3:1 | topLevelMethod | topLevelMethod(int,int) | public, static | | -| methods.kt:5:1:19:1 | Class | methods.kt:6:5:7:5 | classMethod | classMethod(int,int) | public | | -| methods.kt:5:1:19:1 | Class | methods.kt:9:5:12:5 | anotherClassMethod | anotherClassMethod(int,int) | public | | -| methods.kt:5:1:19:1 | Class | methods.kt:14:12:14:29 | publicFun | publicFun() | public | | -| methods.kt:5:1:19:1 | Class | methods.kt:15:15:15:35 | protectedFun | protectedFun() | protected | | -| methods.kt:5:1:19:1 | Class | methods.kt:16:13:16:31 | privateFun | privateFun() | private | | -| methods.kt:5:1:19:1 | Class | methods.kt:17:14:17:33 | internalFun | internalFun() | internal | | -| methods.kt:5:1:19:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | public | | +| 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 | | 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() | +| delegates.kt:4:18:6:5 | new KProperty1(...) { ... } | delegates.kt:4:18:6:5 | | | +| delegates.kt:4:26:6:5 | new Function0(...) { ... } | delegates.kt:4:26:6:5 | | | +| delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | | | +| delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | | | +| delegates.kt:8:66:11:5 | new Function3,String,String,Unit>(...) { ... } | delegates.kt:8:66:11:5 | | | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:6:4:1 | EnumClass | EnumClass(int) | | methods2.kt:7:1:10:1 | Class2 | methods2.kt:7:1:10:1 | Class2 | Class2() | | methods3.kt:5:1:7:1 | Class3 | methods3.kt:5:1:7:1 | Class3 | Class3() | @@ -41,7 +61,7 @@ constructors | methods5.kt:5:3:5:27 | | methods5.kt:5:3:5:27 | | | | methods5.kt:9:3:9:32 | | methods5.kt:9:3:9:32 | | | | methods5.kt:13:1:13:14 | C1 | methods5.kt:13:1:13:14 | C1 | C1() | -| methods.kt:5:1:19:1 | Class | methods.kt:5:1:19:1 | Class | Class() | +| 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 | diff --git a/java/ql/test/kotlin/library-tests/methods/methods.kt b/java/ql/test/kotlin/library-tests/methods/methods.kt index b59937bc861..48f480f8748 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods.kt +++ b/java/ql/test/kotlin/library-tests/methods/methods.kt @@ -16,5 +16,6 @@ class Class { private fun privateFun() {} internal fun internalFun() {} fun noExplicitVisibilityFun() {} + inline fun inlineFun() {} } diff --git a/java/ql/test/kotlin/library-tests/methods/parameters.expected b/java/ql/test/kotlin/library-tests/methods/parameters.expected index 8a1ee3fa42f..2b35e69e502 100644 --- a/java/ql/test/kotlin/library-tests/methods/parameters.expected +++ b/java/ql/test/kotlin/library-tests/methods/parameters.expected @@ -3,6 +3,20 @@ | dataClass.kt:0:0:0:0 | copy | dataClass.kt:1:34:1:46 | y | 1 | | dataClass.kt:0:0:0:0 | equals | dataClass.kt:0:0:0:0 | other | 0 | | dataClass.kt:1:34:1:46 | setY | dataClass.kt:1:34:1:46 | | 0 | +| delegates.kt:4:18:6:5 | get | delegates.kt:4:18:6:5 | a0 | 0 | +| delegates.kt:4:18:6:5 | invoke | delegates.kt:4:18:6:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | get | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | get | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | invoke | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | invoke | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | set | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | set | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | set | delegates.kt:8:32:11:5 | a1 | 1 | +| delegates.kt:8:32:11:5 | set | delegates.kt:8:32:11:5 | a1 | 1 | +| delegates.kt:8:32:11:5 | setObservableProp | delegates.kt:8:32:11:5 | | 0 | +| delegates.kt:8:66:11:5 | invoke | delegates.kt:9:9:9:12 | prop | 0 | +| delegates.kt:8:66:11:5 | invoke | delegates.kt:9:15:9:17 | old | 1 | +| delegates.kt:8:66:11:5 | invoke | delegates.kt:9:20:9:22 | new | 2 | | enumClass.kt:0:0:0:0 | valueOf | enumClass.kt:0:0:0:0 | value | 0 | | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | methods2.kt:4:26:4:31 | x | 0 | | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | methods2.kt:4:34:4:39 | y | 1 | diff --git a/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected b/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected index 70345c576b0..14b5124b7ae 100644 --- a/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected +++ b/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected @@ -11,7 +11,7 @@ | 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 | Method | internal | +| 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 | diff --git a/java/ql/test/kotlin/library-tests/properties/properties.expected b/java/ql/test/kotlin/library-tests/properties/properties.expected index 05870c7b6e1..7bbe706923c 100644 --- a/java/ql/test/kotlin/library-tests/properties/properties.expected +++ b/java/ql/test/kotlin/library-tests/properties/properties.expected @@ -45,7 +45,7 @@ fieldDeclarations | properties.kt:35:5:35:32 | privateProp | properties.kt:35:13:35:32 | getPrivateProp$private | file://:0:0:0:0 | | properties.kt:35:5:35:32 | privateProp | private | | properties.kt:36:5:36:36 | protectedProp | properties.kt:36:15:36:36 | getProtectedProp | file://:0:0:0:0 | | properties.kt:36:5:36:36 | protectedProp | protected | | properties.kt:37:5:37:30 | publicProp | properties.kt:37:12:37:30 | getPublicProp | file://:0:0:0:0 | | properties.kt:37:5:37:30 | publicProp | public | -| properties.kt:38:5:38:34 | internalProp | properties.kt:38:14:38:34 | getInternalProp | file://:0:0:0:0 | | properties.kt:38:5:38:34 | internalProp | internal | +| properties.kt:38:5:38:34 | internalProp | properties.kt:38:14:38:34 | getInternalProp$main | file://:0:0:0:0 | | properties.kt:38:5:38:34 | internalProp | internal | | properties.kt:67:1:67:23 | constVal | properties.kt:67:7:67:23 | getConstVal | file://:0:0:0:0 | | properties.kt:67:1:67:23 | constVal | public | | properties.kt:70:5:70:16 | prop | properties.kt:70:5:70:16 | getProp | file://:0:0:0:0 | | properties.kt:70:5:70:16 | prop | public | | properties.kt:78:1:79:13 | x | properties.kt:79:5:79:13 | getX | file://:0:0:0:0 | | file://:0:0:0:0 | | public | diff --git a/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected b/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected index c29df0de6ef..b1da7cdcee2 100644 --- a/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected @@ -8,7 +8,7 @@ reflection.kt: # 46| 0: [TypeAccess] String # 47| 5: [BlockStmt] { ... } # 47| 0: [ReturnStmt] return ... -# 47| 0: [MethodAccess] get(...) +# 47| 0: [MethodAccess] charAt(...) # 47| -1: [ExtensionReceiverAccess] this # 47| 0: [SubExpr] ... - ... # 47| 0: [MethodAccess] length(...) @@ -26,7 +26,7 @@ reflection.kt: # 50| 1: [Constructor] # 50| 5: [BlockStmt] { ... } # 50| 0: [SuperConstructorInvocationStmt] super(...) -# 50| 1: [Method] get +# 50| 2: [Method] get #-----| 4: (Parameters) # 50| 0: [Parameter] a0 # 50| 5: [BlockStmt] { ... } @@ -34,7 +34,7 @@ reflection.kt: # 50| 0: [MethodAccess] getLastChar(...) # 50| -1: [TypeAccess] ReflectionKt # 50| 0: [VarAccess] a0 -# 50| 1: [Method] invoke +# 50| 3: [Method] invoke #-----| 4: (Parameters) # 50| 0: [Parameter] a0 # 50| 5: [BlockStmt] { ... } @@ -62,16 +62,16 @@ reflection.kt: # 51| 0: [VarAccess] this. # 51| -1: [ThisAccess] this # 51| 1: [VarAccess] -# 51| 1: [FieldDeclaration] String ; +# 51| 2: [FieldDeclaration] String ; # 51| -1: [TypeAccess] String -# 51| 1: [Method] get +# 51| 3: [Method] get # 51| 5: [BlockStmt] { ... } # 51| 0: [ReturnStmt] return ... # 51| 0: [MethodAccess] getLastChar(...) # 51| -1: [TypeAccess] ReflectionKt # 51| 0: [VarAccess] this. # 51| -1: [ThisAccess] this -# 51| 1: [Method] invoke +# 51| 4: [Method] invoke # 51| 5: [BlockStmt] { ... } # 51| 0: [ReturnStmt] return ... # 51| 0: [MethodAccess] get(...) @@ -124,7 +124,7 @@ reflection.kt: # 97| 1: [Constructor] # 97| 5: [BlockStmt] { ... } # 97| 0: [SuperConstructorInvocationStmt] super(...) -# 97| 1: [Method] invoke +# 97| 2: [Method] invoke #-----| 4: (Parameters) # 97| 0: [Parameter] a0 # 97| 5: [BlockStmt] { ... } @@ -148,7 +148,7 @@ reflection.kt: # 98| 1: [Constructor] # 98| 5: [BlockStmt] { ... } # 98| 0: [SuperConstructorInvocationStmt] super(...) -# 98| 1: [Method] invoke +# 98| 2: [Method] invoke #-----| 4: (Parameters) # 98| 0: [Parameter] a0 # 98| 5: [BlockStmt] { ... } @@ -180,7 +180,10 @@ reflection.kt: # 99| 0: [VarAccess] this. # 99| -1: [ThisAccess] this # 99| 1: [VarAccess] -# 99| 1: [Method] invoke +# 99| 2: [FieldDeclaration] Class2 ; +# 99| -1: [TypeAccess] Class2 +# 99| 0: [TypeAccess] Integer +# 99| 3: [Method] invoke #-----| 4: (Parameters) # 99| 0: [Parameter] a0 # 99| 5: [BlockStmt] { ... } @@ -191,9 +194,6 @@ reflection.kt: # 99| -2: [VarAccess] this. # 99| -1: [ThisAccess] this # 99| 0: [VarAccess] a0 -# 99| 1: [FieldDeclaration] Class2 ; -# 99| -1: [TypeAccess] Class2 -# 99| 0: [TypeAccess] Integer # 99| -3: [TypeAccess] Function1> # 99| 0: [TypeAccess] String # 99| 1: [TypeAccess] Inner @@ -260,7 +260,7 @@ reflection.kt: # 126| 1: [Constructor] # 126| 5: [BlockStmt] { ... } # 126| 0: [SuperConstructorInvocationStmt] super(...) -# 126| 1: [Method] fn1 +# 126| 2: [Method] fn1 # 126| 3: [TypeAccess] Unit # 126| 5: [BlockStmt] { ... } # 126| 0: [ExprStmt] ; @@ -274,7 +274,7 @@ reflection.kt: # 126| 1: [Constructor] # 126| 5: [BlockStmt] { ... } # 126| 0: [SuperConstructorInvocationStmt] super(...) -# 126| 1: [Method] invoke +# 126| 2: [Method] invoke # 126| 5: [BlockStmt] { ... } # 126| 0: [ReturnStmt] return ... # 126| 0: [MethodAccess] fn1(...) @@ -296,7 +296,7 @@ reflection.kt: # 7| 1: [Constructor] # 7| 5: [BlockStmt] { ... } # 7| 0: [SuperConstructorInvocationStmt] super(...) -# 7| 1: [Method] invoke +# 7| 2: [Method] invoke #-----| 4: (Parameters) # 7| 0: [Parameter] a0 # 7| 1: [Parameter] a1 @@ -321,14 +321,14 @@ reflection.kt: # 10| 1: [Constructor] # 10| 5: [BlockStmt] { ... } # 10| 0: [SuperConstructorInvocationStmt] super(...) -# 10| 1: [Method] get +# 10| 2: [Method] get #-----| 4: (Parameters) # 10| 0: [Parameter] a0 # 10| 5: [BlockStmt] { ... } # 10| 0: [ReturnStmt] return ... # 10| 0: [MethodAccess] getP0(...) # 10| -1: [VarAccess] a0 -# 10| 1: [Method] invoke +# 10| 3: [Method] invoke #-----| 4: (Parameters) # 10| 0: [Parameter] a0 # 10| 5: [BlockStmt] { ... } @@ -367,7 +367,11 @@ reflection.kt: # 14| 0: [VarAccess] this. # 14| -1: [ThisAccess] this # 14| 1: [VarAccess] -# 14| 1: [Method] invoke +# 14| 2: [FieldDeclaration] KProperty1 ; +# 14| -1: [TypeAccess] KProperty1 +# 14| 0: [TypeAccess] C +# 14| 1: [TypeAccess] Integer +# 14| 3: [Method] invoke #-----| 4: (Parameters) # 14| 0: [Parameter] a0 # 14| 5: [BlockStmt] { ... } @@ -376,10 +380,6 @@ reflection.kt: # 14| -1: [VarAccess] this. # 14| -1: [ThisAccess] this # 14| 0: [VarAccess] a0 -# 14| 1: [FieldDeclaration] KProperty1 ; -# 14| -1: [TypeAccess] KProperty1 -# 14| 0: [TypeAccess] C -# 14| 1: [TypeAccess] Integer # 14| -3: [TypeAccess] Function1 # 14| 0: [TypeAccess] C # 14| 1: [TypeAccess] Integer @@ -398,15 +398,15 @@ reflection.kt: # 15| 0: [VarAccess] this. # 15| -1: [ThisAccess] this # 15| 1: [VarAccess] -# 15| 1: [FieldDeclaration] C ; +# 15| 2: [FieldDeclaration] C ; # 15| -1: [TypeAccess] C -# 15| 1: [Method] get +# 15| 3: [Method] get # 15| 5: [BlockStmt] { ... } # 15| 0: [ReturnStmt] return ... # 15| 0: [MethodAccess] getP0(...) # 15| -1: [VarAccess] this. # 15| -1: [ThisAccess] this -# 15| 1: [Method] invoke +# 15| 4: [Method] invoke # 15| 5: [BlockStmt] { ... } # 15| 0: [ReturnStmt] return ... # 15| 0: [MethodAccess] get(...) @@ -422,14 +422,14 @@ reflection.kt: # 17| 1: [Constructor] # 17| 5: [BlockStmt] { ... } # 17| 0: [SuperConstructorInvocationStmt] super(...) -# 17| 1: [Method] get +# 17| 2: [Method] get #-----| 4: (Parameters) # 17| 0: [Parameter] a0 # 17| 5: [BlockStmt] { ... } # 17| 0: [ReturnStmt] return ... # 17| 0: [MethodAccess] getP1(...) # 17| -1: [VarAccess] a0 -# 17| 1: [Method] invoke +# 17| 3: [Method] invoke #-----| 4: (Parameters) # 17| 0: [Parameter] a0 # 17| 5: [BlockStmt] { ... } @@ -437,7 +437,7 @@ reflection.kt: # 17| 0: [MethodAccess] get(...) # 17| -1: [ThisAccess] this # 17| 0: [VarAccess] a0 -# 17| 1: [Method] set +# 17| 4: [Method] set #-----| 4: (Parameters) # 17| 0: [Parameter] a0 # 17| 1: [Parameter] a1 @@ -478,7 +478,11 @@ reflection.kt: # 21| 0: [VarAccess] this. # 21| -1: [ThisAccess] this # 21| 1: [VarAccess] -# 21| 1: [Method] invoke +# 21| 2: [FieldDeclaration] KMutableProperty1 ; +# 21| -1: [TypeAccess] KMutableProperty1 +# 21| 0: [TypeAccess] C +# 21| 1: [TypeAccess] Integer +# 21| 3: [Method] invoke #-----| 4: (Parameters) # 21| 0: [Parameter] a0 # 21| 1: [Parameter] a1 @@ -489,10 +493,6 @@ reflection.kt: # 21| -1: [ThisAccess] this # 21| 0: [VarAccess] a0 # 21| 1: [VarAccess] a1 -# 21| 1: [FieldDeclaration] KMutableProperty1 ; -# 21| -1: [TypeAccess] KMutableProperty1 -# 21| 0: [TypeAccess] C -# 21| 1: [TypeAccess] Integer # 21| -3: [TypeAccess] Function2 # 21| 0: [TypeAccess] C # 21| 1: [TypeAccess] Integer @@ -512,20 +512,20 @@ reflection.kt: # 22| 0: [VarAccess] this. # 22| -1: [ThisAccess] this # 22| 1: [VarAccess] -# 22| 1: [FieldDeclaration] C ; +# 22| 2: [FieldDeclaration] C ; # 22| -1: [TypeAccess] C -# 22| 1: [Method] get +# 22| 3: [Method] get # 22| 5: [BlockStmt] { ... } # 22| 0: [ReturnStmt] return ... # 22| 0: [MethodAccess] getP1(...) # 22| -1: [VarAccess] this. # 22| -1: [ThisAccess] this -# 22| 1: [Method] invoke +# 22| 4: [Method] invoke # 22| 5: [BlockStmt] { ... } # 22| 0: [ReturnStmt] return ... # 22| 0: [MethodAccess] get(...) # 22| -1: [ThisAccess] this -# 22| 1: [Method] set +# 22| 5: [Method] set #-----| 4: (Parameters) # 22| 0: [Parameter] a0 # 22| 5: [BlockStmt] { ... } @@ -556,7 +556,7 @@ reflection.kt: # 24| 1: [Constructor] # 24| 5: [BlockStmt] { ... } # 24| 0: [SuperConstructorInvocationStmt] super(...) -# 24| 1: [Method] invoke +# 24| 2: [Method] invoke # 24| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 24| 0: [Parameter] it @@ -608,7 +608,7 @@ reflection.kt: # 33| 0: [ReturnStmt] return ... # 33| 0: [VarAccess] this.p0 # 33| -1: [ThisAccess] this -# 33| 2: [FieldDeclaration] int p0; +# 33| 3: [FieldDeclaration] int p0; # 33| -1: [TypeAccess] int # 33| 0: [IntegerLiteral] 1 # 34| 4: [Method] getP1 @@ -617,7 +617,10 @@ reflection.kt: # 34| 0: [ReturnStmt] return ... # 34| 0: [VarAccess] this.p1 # 34| -1: [ThisAccess] this -# 34| 4: [Method] setP1 +# 34| 5: [FieldDeclaration] int p1; +# 34| -1: [TypeAccess] int +# 34| 0: [IntegerLiteral] 2 +# 34| 6: [Method] setP1 # 34| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 34| 0: [Parameter] @@ -628,9 +631,6 @@ reflection.kt: # 34| 0: [VarAccess] this.p1 # 34| -1: [ThisAccess] this # 34| 1: [VarAccess] -# 34| 4: [FieldDeclaration] int p1; -# 34| -1: [TypeAccess] int -# 34| 0: [IntegerLiteral] 2 # 36| 7: [Method] getP2 # 36| 3: [TypeAccess] int # 36| 5: [BlockStmt] { ... } @@ -678,7 +678,7 @@ reflection.kt: # 60| 1: [Constructor] # 60| 5: [BlockStmt] { ... } # 60| 0: [SuperConstructorInvocationStmt] super(...) -# 60| 1: [Method] invoke +# 60| 2: [Method] invoke #-----| 4: (Parameters) # 60| 0: [Parameter] a0 # 60| 1: [Parameter] a1 @@ -707,7 +707,10 @@ reflection.kt: # 61| 0: [VarAccess] this. # 61| -1: [ThisAccess] this # 61| 1: [VarAccess] -# 61| 1: [Method] invoke +# 61| 2: [FieldDeclaration] Generic ; +# 61| -1: [TypeAccess] Generic +# 61| 0: [TypeAccess] Integer +# 61| 3: [Method] invoke #-----| 4: (Parameters) # 61| 0: [Parameter] a0 # 61| 5: [BlockStmt] { ... } @@ -716,9 +719,6 @@ reflection.kt: # 61| -1: [VarAccess] this. # 61| -1: [ThisAccess] this # 61| 0: [VarAccess] a0 -# 61| 1: [FieldDeclaration] Generic ; -# 61| -1: [TypeAccess] Generic -# 61| 0: [TypeAccess] Integer # 61| -3: [TypeAccess] Function1 # 61| 0: [TypeAccess] Integer # 61| 1: [TypeAccess] String @@ -733,7 +733,7 @@ reflection.kt: # 62| 1: [Constructor] # 62| 5: [BlockStmt] { ... } # 62| 0: [SuperConstructorInvocationStmt] super(...) -# 62| 1: [Method] invoke +# 62| 2: [Method] invoke #-----| 4: (Parameters) # 62| 0: [Parameter] a0 # 62| 5: [BlockStmt] { ... } @@ -761,7 +761,10 @@ reflection.kt: # 63| 0: [VarAccess] this. # 63| -1: [ThisAccess] this # 63| 1: [VarAccess] -# 63| 1: [Method] invoke +# 63| 2: [FieldDeclaration] Generic ; +# 63| -1: [TypeAccess] Generic +# 63| 0: [TypeAccess] Integer +# 63| 3: [Method] invoke # 63| 5: [BlockStmt] { ... } # 63| 0: [ReturnStmt] return ... # 63| 0: [MethodAccess] ext1(...) @@ -769,9 +772,6 @@ reflection.kt: # 63| -1: [TypeAccess] ReflectionKt # 63| 0: [VarAccess] this. # 63| -1: [ThisAccess] this -# 63| 1: [FieldDeclaration] Generic ; -# 63| -1: [TypeAccess] Generic -# 63| 0: [TypeAccess] Integer # 63| -3: [TypeAccess] Function0 # 63| 0: [TypeAccess] String # 63| 0: [ClassInstanceExpr] new Generic(...) @@ -785,7 +785,7 @@ reflection.kt: # 64| 1: [Constructor] # 64| 5: [BlockStmt] { ... } # 64| 0: [SuperConstructorInvocationStmt] super(...) -# 64| 1: [Method] invoke +# 64| 2: [Method] invoke #-----| 4: (Parameters) # 64| 0: [Parameter] a0 # 64| 5: [BlockStmt] { ... } @@ -812,16 +812,16 @@ reflection.kt: # 65| 0: [VarAccess] this. # 65| -1: [ThisAccess] this # 65| 1: [VarAccess] -# 65| 1: [Method] invoke +# 65| 2: [FieldDeclaration] Generic ; +# 65| -1: [TypeAccess] Generic +# 65| 0: [TypeAccess] Integer +# 65| 3: [Method] invoke # 65| 5: [BlockStmt] { ... } # 65| 0: [ReturnStmt] return ... # 65| 0: [MethodAccess] ext2(...) # 65| -1: [TypeAccess] ReflectionKt # 65| 0: [VarAccess] this. # 65| -1: [ThisAccess] this -# 65| 1: [FieldDeclaration] Generic ; -# 65| -1: [TypeAccess] Generic -# 65| 0: [TypeAccess] Integer # 65| -3: [TypeAccess] Function0 # 65| 0: [TypeAccess] String # 65| 0: [ClassInstanceExpr] new Generic(...) @@ -835,14 +835,14 @@ reflection.kt: # 67| 1: [Constructor] # 67| 5: [BlockStmt] { ... } # 67| 0: [SuperConstructorInvocationStmt] super(...) -# 67| 1: [Method] get +# 67| 2: [Method] get #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } # 67| 0: [ReturnStmt] return ... # 67| 0: [MethodAccess] getP2(...) # 67| -1: [VarAccess] a0 -# 67| 1: [Method] invoke +# 67| 3: [Method] invoke #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } @@ -850,7 +850,7 @@ reflection.kt: # 67| 0: [MethodAccess] get(...) # 67| -1: [ThisAccess] this # 67| 0: [VarAccess] a0 -# 67| 1: [Method] set +# 67| 4: [Method] set #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 1: [Parameter] a1 @@ -878,21 +878,21 @@ reflection.kt: # 68| 0: [VarAccess] this. # 68| -1: [ThisAccess] this # 68| 1: [VarAccess] -# 68| 1: [FieldDeclaration] Generic ; +# 68| 2: [FieldDeclaration] Generic ; # 68| -1: [TypeAccess] Generic # 68| 0: [TypeAccess] Integer -# 68| 1: [Method] get +# 68| 3: [Method] get # 68| 5: [BlockStmt] { ... } # 68| 0: [ReturnStmt] return ... # 68| 0: [MethodAccess] getP2(...) # 68| -1: [VarAccess] this. # 68| -1: [ThisAccess] this -# 68| 1: [Method] invoke +# 68| 4: [Method] invoke # 68| 5: [BlockStmt] { ... } # 68| 0: [ReturnStmt] return ... # 68| 0: [MethodAccess] get(...) # 68| -1: [ThisAccess] this -# 68| 1: [Method] set +# 68| 5: [Method] set #-----| 4: (Parameters) # 68| 0: [Parameter] a0 # 68| 5: [BlockStmt] { ... } @@ -921,15 +921,15 @@ reflection.kt: # 70| 0: [VarAccess] this. # 70| -1: [ThisAccess] this # 70| 1: [VarAccess] -# 70| 1: [FieldDeclaration] IntCompanionObject ; +# 70| 2: [FieldDeclaration] IntCompanionObject ; # 70| -1: [TypeAccess] IntCompanionObject -# 70| 1: [Method] get +# 70| 3: [Method] get # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... # 70| 0: [MethodAccess] getMAX_VALUE(...) # 70| -1: [VarAccess] this. # 70| -1: [ThisAccess] this -# 70| 1: [Method] invoke +# 70| 4: [Method] invoke # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... # 70| 0: [MethodAccess] get(...) @@ -945,11 +945,11 @@ reflection.kt: # 71| 1: [Constructor] # 71| 5: [BlockStmt] { ... } # 71| 0: [SuperConstructorInvocationStmt] super(...) -# 71| 1: [Method] get +# 71| 2: [Method] get # 71| 5: [BlockStmt] { ... } # 71| 0: [ReturnStmt] return ... # 71| 0: [VarAccess] MAX_VALUE -# 71| 1: [Method] invoke +# 71| 3: [Method] invoke # 71| 5: [BlockStmt] { ... } # 71| 0: [ReturnStmt] return ... # 71| 0: [MethodAccess] get(...) @@ -971,20 +971,20 @@ reflection.kt: # 72| 0: [VarAccess] this. # 72| -1: [ThisAccess] this # 72| 1: [VarAccess] -# 72| 1: [FieldDeclaration] Rectangle ; +# 72| 2: [FieldDeclaration] Rectangle ; # 72| -1: [TypeAccess] Rectangle -# 72| 1: [Method] get +# 72| 3: [Method] get # 72| 5: [BlockStmt] { ... } # 72| 0: [ReturnStmt] return ... # 72| 0: [VarAccess] this..height # 72| -1: [VarAccess] this. # 72| -1: [ThisAccess] this -# 72| 1: [Method] invoke +# 72| 4: [Method] invoke # 72| 5: [BlockStmt] { ... } # 72| 0: [ReturnStmt] return ... # 72| 0: [MethodAccess] get(...) # 72| -1: [ThisAccess] this -# 72| 1: [Method] set +# 72| 5: [Method] set #-----| 4: (Parameters) # 72| 0: [Parameter] a0 # 72| 5: [BlockStmt] { ... } @@ -1040,15 +1040,15 @@ reflection.kt: # 83| 0: [ExprStmt] ; # 83| 0: [KtInitializerAssignExpr] ...=... # 83| 0: [VarAccess] value -# 83| 4: [Method] getValue +# 83| 4: [FieldDeclaration] T value; +# 83| -1: [TypeAccess] T +# 83| 0: [VarAccess] value +# 83| 5: [Method] getValue # 83| 3: [TypeAccess] T # 83| 5: [BlockStmt] { ... } # 83| 0: [ReturnStmt] return ... # 83| 0: [VarAccess] this.value # 83| -1: [ThisAccess] this -# 83| 4: [FieldDeclaration] T value; -# 83| -1: [TypeAccess] T -# 83| 0: [VarAccess] value # 85| 6: [Class,GenericType,ParameterizedType] Inner #-----| -2: (Generic Parameters) # 85| 0: [TypeVariable] T1 @@ -1082,7 +1082,10 @@ reflection.kt: # 90| 0: [VarAccess] this. # 90| -1: [ThisAccess] this # 90| 1: [VarAccess] -# 90| 1: [Method] invoke +# 90| 2: [FieldDeclaration] Class2 ; +# 90| -1: [TypeAccess] Class2 +# 90| 0: [TypeAccess] T +# 90| 3: [Method] invoke #-----| 4: (Parameters) # 90| 0: [Parameter] a0 # 90| 5: [BlockStmt] { ... } @@ -1093,9 +1096,6 @@ reflection.kt: # 90| -2: [VarAccess] this. # 90| -1: [ThisAccess] this # 90| 0: [VarAccess] a0 -# 90| 1: [FieldDeclaration] Class2 ; -# 90| -1: [TypeAccess] Class2 -# 90| 0: [TypeAccess] T # 90| -3: [TypeAccess] Function1> # 90| 0: [TypeAccess] String # 90| 1: [TypeAccess] Inner @@ -1118,7 +1118,10 @@ reflection.kt: # 105| 0: [ReturnStmt] return ... # 105| 0: [VarAccess] this.prop1 # 105| -1: [ThisAccess] this -# 105| 2: [Method] setProp1 +# 105| 3: [FieldDeclaration] int prop1; +# 105| -1: [TypeAccess] int +# 105| 0: [VarAccess] prop1 +# 105| 4: [Method] setProp1 # 105| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 105| 0: [Parameter] @@ -1129,9 +1132,6 @@ reflection.kt: # 105| 0: [VarAccess] this.prop1 # 105| -1: [ThisAccess] this # 105| 1: [VarAccess] -# 105| 2: [FieldDeclaration] int prop1; -# 105| -1: [TypeAccess] int -# 105| 0: [VarAccess] prop1 # 107| 7: [Class] Derived1 # 107| 1: [Constructor] Derived1 #-----| 4: (Parameters) @@ -1159,20 +1159,20 @@ reflection.kt: # 109| 0: [VarAccess] this. # 109| -1: [ThisAccess] this # 109| 1: [VarAccess] -# 109| 1: [FieldDeclaration] Derived1 ; +# 109| 2: [FieldDeclaration] Derived1 ; # 109| -1: [TypeAccess] Derived1 -# 109| 1: [Method] get +# 109| 3: [Method] get # 109| 5: [BlockStmt] { ... } # 109| 0: [ReturnStmt] return ... # 109| 0: [MethodAccess] getProp1(...) # 109| -1: [VarAccess] this. # 109| -1: [ThisAccess] this -# 109| 1: [Method] invoke +# 109| 4: [Method] invoke # 109| 5: [BlockStmt] { ... } # 109| 0: [ReturnStmt] return ... # 109| 0: [MethodAccess] get(...) # 109| -1: [ThisAccess] this -# 109| 1: [Method] set +# 109| 5: [Method] set #-----| 4: (Parameters) # 109| 0: [Parameter] a0 # 109| 5: [BlockStmt] { ... } @@ -1197,7 +1197,7 @@ reflection.kt: # 115| 1: [Constructor] # 115| 5: [BlockStmt] { ... } # 115| 0: [SuperConstructorInvocationStmt] super(...) -# 115| 1: [Method] fn1 +# 115| 2: [Method] fn1 # 115| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 115| 0: [Parameter] i @@ -1210,7 +1210,7 @@ reflection.kt: # 116| 1: [Constructor] # 116| 5: [BlockStmt] { ... } # 116| 0: [SuperConstructorInvocationStmt] super(...) -# 116| 1: [Method] invoke +# 116| 2: [Method] invoke #-----| 4: (Parameters) # 116| 0: [Parameter] a0 # 116| 5: [BlockStmt] { ... } diff --git a/java/ql/test/kotlin/library-tests/reflection/reflection.expected b/java/ql/test/kotlin/library-tests/reflection/reflection.expected index 1e249da402d..9b6899f4b6e 100644 --- a/java/ql/test/kotlin/library-tests/reflection/reflection.expected +++ b/java/ql/test/kotlin/library-tests/reflection/reflection.expected @@ -232,6 +232,9 @@ modifiers compGenerated | file:///Class2.class:0:0:0:0 | getValue | 3 | | file:///Class2.class:0:0:0:0 | getValue | 3 | +| file:///KTypeProjection.class:0:0:0:0 | contravariant | 8 | +| file:///KTypeProjection.class:0:0:0:0 | covariant | 8 | +| file:///KTypeProjection.class:0:0:0:0 | invariant | 8 | | reflection.kt:33:9:33:23 | getP0 | 3 | | reflection.kt:34:9:34:23 | getP1 | 3 | | reflection.kt:34:9:34:23 | setP1 | 3 | diff --git a/java/ql/test/kotlin/library-tests/string-charat/Test.java b/java/ql/test/kotlin/library-tests/string-charat/Test.java new file mode 100644 index 00000000000..22f553216b7 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/string-charat/Test.java @@ -0,0 +1,5 @@ +public class Test { + + public char f(String s) { return s.charAt(0); } + +} diff --git a/java/ql/test/kotlin/library-tests/string-charat/test.expected b/java/ql/test/kotlin/library-tests/string-charat/test.expected new file mode 100644 index 00000000000..ab1ff9b6d5f --- /dev/null +++ b/java/ql/test/kotlin/library-tests/string-charat/test.expected @@ -0,0 +1,2 @@ +| Test.java:3:36:3:46 | charAt(...) | +| test.kt:2:20:2:23 | charAt(...) | diff --git a/java/ql/test/kotlin/library-tests/string-charat/test.kt b/java/ql/test/kotlin/library-tests/string-charat/test.kt new file mode 100644 index 00000000000..c586f3d0171 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/string-charat/test.kt @@ -0,0 +1,2 @@ + +fun f(x: String) = x[0] diff --git a/java/ql/test/kotlin/library-tests/string-charat/test.ql b/java/ql/test/kotlin/library-tests/string-charat/test.ql new file mode 100644 index 00000000000..ab60ba2525d --- /dev/null +++ b/java/ql/test/kotlin/library-tests/string-charat/test.ql @@ -0,0 +1,4 @@ +import java + +from MethodAccess ma +select ma diff --git a/java/ql/test/kotlin/library-tests/super-method-calls/test.expected b/java/ql/test/kotlin/library-tests/super-method-calls/test.expected new file mode 100644 index 00000000000..841eb6298c7 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/super-method-calls/test.expected @@ -0,0 +1,2 @@ +| test.kt:31:17:31:24 | source(...) | test.kt:31:15:31:25 | f(...) | +| test.kt:32:17:32:24 | source(...) | test.kt:32:15:32:25 | g(...) | diff --git a/java/ql/test/kotlin/library-tests/super-method-calls/test.kt b/java/ql/test/kotlin/library-tests/super-method-calls/test.kt new file mode 100644 index 00000000000..7b3e90d7359 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/super-method-calls/test.kt @@ -0,0 +1,36 @@ +open class A { + + open fun f(x: String) = x + +} + +interface B { + + fun g(x: String) = x + +} + +interface C { + + fun g(x: String) = x + +} + +class User : A(), B, C { + + override fun f(x: String) = super.f(x) + + override fun g(x: String) = super.g(x) + + fun source() = "tainted" + + fun sink(s: String) { } + + fun test() { + + sink(this.f(source())) + sink(this.g(source())) + + } + +} diff --git a/java/ql/test/kotlin/library-tests/super-method-calls/test.ql b/java/ql/test/kotlin/library-tests/super-method-calls/test.ql new file mode 100644 index 00000000000..9a628624c91 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/super-method-calls/test.ql @@ -0,0 +1,18 @@ +import java +import semmle.code.java.dataflow.DataFlow + +class Config extends DataFlow::Configuration { + Config() { this = "abc" } + + override predicate isSource(DataFlow::Node n) { + n.asExpr().(MethodAccess).getMethod().getName() = "source" + } + + override predicate isSink(DataFlow::Node n) { + n.asExpr().(Argument).getCall().getCallee().getName() = "sink" + } +} + +from Config c, DataFlow::Node n1, DataFlow::Node n2 +where c.hasFlow(n1, n2) +select n1, n2 diff --git a/java/ql/test/library-tests/dataflow/collections/Test.java b/java/ql/test/library-tests/dataflow/collections/Test.java index 216f373ca8c..9836070f42c 100644 --- a/java/ql/test/library-tests/dataflow/collections/Test.java +++ b/java/ql/test/library-tests/dataflow/collections/Test.java @@ -78,4 +78,14 @@ public class Test { sink(x18); // Flow }); } + + public void run4() { + Properties p = new Properties(); + p.put("key", tainted); + sink(p.getProperty("key")); // Flow + sink(p.getProperty("key", "defaultValue")); // Flow + + Properties clean = new Properties(); + sink(clean.getProperty("key", tainted)); // Flow + } } diff --git a/java/ql/test/library-tests/dataflow/collections/flow.expected b/java/ql/test/library-tests/dataflow/collections/flow.expected index 1a4bed0a6e7..875a4191722 100644 --- a/java/ql/test/library-tests/dataflow/collections/flow.expected +++ b/java/ql/test/library-tests/dataflow/collections/flow.expected @@ -11,3 +11,6 @@ | Test.java:49:20:49:26 | tainted | Test.java:60:12:60:14 | x14 | | Test.java:73:11:73:17 | tainted | Test.java:75:10:75:12 | x17 | | Test.java:73:11:73:17 | tainted | Test.java:78:12:78:14 | x18 | +| Test.java:84:18:84:24 | tainted | Test.java:85:10:85:29 | getProperty(...) | +| Test.java:84:18:84:24 | tainted | Test.java:86:10:86:45 | getProperty(...) | +| Test.java:89:35:89:41 | tainted | Test.java:89:10:89:42 | getProperty(...) | diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/Test.java b/java/ql/test/library-tests/frameworks/android/external-storage/Test.java new file mode 100644 index 00000000000..2b4aec0c86a --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/external-storage/Test.java @@ -0,0 +1,59 @@ +import java.io.File; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.FileReader; +import java.io.RandomAccessFile; +import android.content.Context; +import android.os.Environment; + +class Test { + void sink(Object o) {} + + void test1(Context ctx) throws IOException { + File f = new File(ctx.getExternalFilesDir(null), "file.txt"); + InputStream is = new FileInputStream(f); + byte[] data = new byte[is.available()]; + is.read(data); + sink(data); // $ hasTaintFlow + is.close(); + } + + void test2(Context ctx) throws IOException { + File f = new File(new File(new File(ctx.getExternalFilesDirs(null)[0], "things"), "stuff"), "file.txt"); + sink(new FileInputStream(f)); // $ hasTaintFlow + } + + void test3(Context ctx) throws IOException { + File f = new File(ctx.getExternalCacheDir(), "file.txt"); + sink(new FileInputStream(f)); // $ hasTaintFlow + } + + void test4(Context ctx) throws IOException { + File f = new File(ctx.getExternalCacheDirs()[0], "file.txt"); + sink(new FileInputStream(f)); // $ hasTaintFlow + } + + void test5(Context ctx) throws IOException { + File f = new File(Environment.getExternalStorageDirectory(), "file.txt"); + sink(new FileInputStream(f)); // $ hasTaintFlow + } + + void test6(Context ctx) throws IOException { + File f = new File(Environment.getExternalStoragePublicDirectory(null), "file.txt"); + sink(new FileInputStream(f)); // $ hasTaintFlow + } + + static final File dir = Environment.getExternalStorageDirectory(); + + void test7(Context ctx) throws IOException { + File f = new File(dir, "file.txt"); + sink(new FileInputStream(f)); // $ hasTaintFlow + } + + void test8() throws IOException { + File f = new File(dir, "file.txt"); + sink(new FileReader(f)); // $ hasTaintFlow + sink(new RandomAccessFile(f, "r")); // $ hasTaintFlow + } + } \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/options b/java/ql/test/library-tests/frameworks/android/external-storage/options new file mode 100644 index 00000000000..33cdc1ea940 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/external-storage/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/google-android-9.0.0 diff --git a/swift/integration-tests/frontend-invocations/A.swift b/java/ql/test/library-tests/frameworks/android/external-storage/test.expected similarity index 100% rename from swift/integration-tests/frontend-invocations/A.swift rename to java/ql/test/library-tests/frameworks/android/external-storage/test.expected diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/test.ql b/java/ql/test/library-tests/frameworks/android/external-storage/test.ql new file mode 100644 index 00000000000..03509c2d46d --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/external-storage/test.ql @@ -0,0 +1,20 @@ +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSources +import TestUtilities.InlineFlowTest + +class Conf extends TaintTracking::Configuration { + Conf() { this = "test:AndroidExternalFlowConf" } + + override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr().(Argument).getCall().getCallee().hasName("sink") + } +} + +class ExternalStorageTest extends InlineFlowTest { + override DataFlow::Configuration getValueFlowConfig() { none() } + + override DataFlow::Configuration getTaintFlowConfig() { result instanceof Conf } +} diff --git a/java/ql/test/library-tests/scanner/Test.java b/java/ql/test/library-tests/scanner/Test.java new file mode 100644 index 00000000000..05f5b497215 --- /dev/null +++ b/java/ql/test/library-tests/scanner/Test.java @@ -0,0 +1,328 @@ +package generatedtest; + +import java.io.File; +import java.io.InputStream; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.channels.ReadableByteChannel; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.util.Scanner; +import java.util.regex.Pattern; + +// Test case generated by GenerateFlowTestCase.ql +public class Test { + + Object source() { + return null; + } + + void sink(Object o) {} + + public void test() throws Exception { + + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + File in = (File) source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + File in = (File) source(); + out = new Scanner(in, (Charset) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + File in = (File) source(); + out = new Scanner(in, (String) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + InputStream in = (InputStream) source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + InputStream in = (InputStream) source(); + out = new Scanner(in, (Charset) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + InputStream in = (InputStream) source(); + out = new Scanner(in, (String) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Path in = (Path) source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Path in = (Path) source(); + out = new Scanner(in, (Charset) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Path in = (Path) source(); + out = new Scanner(in, (String) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Readable in = (Readable) source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + ReadableByteChannel in = (ReadableByteChannel) source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + ReadableByteChannel in = (ReadableByteChannel) source(); + out = new Scanner(in, (Charset) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + ReadableByteChannel in = (ReadableByteChannel) source(); + out = new Scanner(in, (String) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + String in = (String) source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;findInLine;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.findInLine((Pattern) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;findInLine;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.findInLine((String) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.findWithinHorizon((Pattern) null, 0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.findWithinHorizon((String) null, 0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.next((Pattern) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.next((String) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.next(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextBigDecimal;;;Argument[-1];ReturnValue;taint;manual" + BigDecimal out = null; + Scanner in = (Scanner) source(); + out = in.nextBigDecimal(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextBigInteger;;;Argument[-1];ReturnValue;taint;manual" + BigInteger out = null; + Scanner in = (Scanner) source(); + out = in.nextBigInteger(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextBigInteger;;;Argument[-1];ReturnValue;taint;manual" + BigInteger out = null; + Scanner in = (Scanner) source(); + out = in.nextBigInteger(0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextBoolean;;;Argument[-1];ReturnValue;taint;manual" + boolean out = false; + Scanner in = (Scanner) source(); + out = in.nextBoolean(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = 0; + Scanner in = (Scanner) source(); + out = in.nextByte(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = 0; + Scanner in = (Scanner) source(); + out = in.nextByte(0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextDouble;;;Argument[-1];ReturnValue;taint;manual" + double out = 0; + Scanner in = (Scanner) source(); + out = in.nextDouble(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextFloat;;;Argument[-1];ReturnValue;taint;manual" + float out = 0; + Scanner in = (Scanner) source(); + out = in.nextFloat(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextInt;;;Argument[-1];ReturnValue;taint;manual" + int out = 0; + Scanner in = (Scanner) source(); + out = in.nextInt(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextInt;;;Argument[-1];ReturnValue;taint;manual" + int out = 0; + Scanner in = (Scanner) source(); + out = in.nextInt(0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextLine;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.nextLine(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextLong;;;Argument[-1];ReturnValue;taint;manual" + long out = 0; + Scanner in = (Scanner) source(); + out = in.nextLong(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextLong;;;Argument[-1];ReturnValue;taint;manual" + long out = 0; + Scanner in = (Scanner) source(); + out = in.nextLong(0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextShort;;;Argument[-1];ReturnValue;taint;manual" + short out = 0; + Scanner in = (Scanner) source(); + out = in.nextShort(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextShort;;;Argument[-1];ReturnValue;taint;manual" + short out = 0; + Scanner in = (Scanner) source(); + out = in.nextShort(0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;reset;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner) source(); + out = in.reset(); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner) source(); + out = in.skip((Pattern) null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner) source(); + out = in.skip((String) null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner) source(); + out = in.useDelimiter((Pattern) null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner) source(); + out = in.useDelimiter((String) null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useLocale;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner) source(); + out = in.useLocale(null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useRadix;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner) source(); + out = in.useRadix(0); + sink(out); // $ hasValueFlow + } + + } + +} diff --git a/swift/integration-tests/frontend-invocations/B.swift b/java/ql/test/library-tests/scanner/test.expected similarity index 100% rename from swift/integration-tests/frontend-invocations/B.swift rename to java/ql/test/library-tests/scanner/test.expected diff --git a/java/ql/test/library-tests/scanner/test.ql b/java/ql/test/library-tests/scanner/test.ql new file mode 100644 index 00000000000..5d91e4e8e26 --- /dev/null +++ b/java/ql/test/library-tests/scanner/test.ql @@ -0,0 +1,2 @@ +import java +import TestUtilities.InlineFlowTest diff --git a/java/ql/test/library-tests/types/cycles/Test.java b/java/ql/test/library-tests/types/cycles/Test.java new file mode 100644 index 00000000000..a06540728b9 --- /dev/null +++ b/java/ql/test/library-tests/types/cycles/Test.java @@ -0,0 +1,2 @@ +public class Test { +} diff --git a/java/ql/test/library-tests/types/cycles/cycles.expected b/java/ql/test/library-tests/types/cycles/cycles.expected new file mode 100644 index 00000000000..7c0e79d7252 --- /dev/null +++ b/java/ql/test/library-tests/types/cycles/cycles.expected @@ -0,0 +1,6 @@ +| BiFunction | +| BiFunction | +| Function | +| Function | +| Map | +| Map | diff --git a/java/ql/test/library-tests/types/cycles/cycles.ql b/java/ql/test/library-tests/types/cycles/cycles.ql new file mode 100644 index 00000000000..dd4d6e1f757 --- /dev/null +++ b/java/ql/test/library-tests/types/cycles/cycles.ql @@ -0,0 +1,5 @@ +import java + +from RefType t +where t = t.getAStrictAncestor() +select t.toString() diff --git a/java/ql/test/library-tests/wildcard-substitution/Lib.java b/java/ql/test/library-tests/wildcard-substitution/Lib.java new file mode 100644 index 00000000000..0647410b692 --- /dev/null +++ b/java/ql/test/library-tests/wildcard-substitution/Lib.java @@ -0,0 +1,20 @@ +import java.util.List; + +public class Lib { + + public void takesVar(T t) { } + public void takesInvar(List lt) { } + public void takesUnbound(List lt) { } + public void takesExtends(List lt) { } + public void takesSuper(List lt) { } + + public T returnsVar() { return null; } + public List returnsInvar() { return null; } + public List returnsUnbound() { return null; } + public List returnsExtends() { return null; } + public List returnsSuper() { return null; } + + public void takesArray(T[] ts) { } + public T[] returnsArray() { return null; } + +} diff --git a/java/ql/test/library-tests/wildcard-substitution/User.java b/java/ql/test/library-tests/wildcard-substitution/User.java new file mode 100644 index 00000000000..5f4b7fac21a --- /dev/null +++ b/java/ql/test/library-tests/wildcard-substitution/User.java @@ -0,0 +1,12 @@ +public class User { + + public static void test(Lib invarLib, Lib extendsLib, Lib superLib, Lib unboundLib) { + + invarLib.takesVar(null); + extendsLib.takesVar(null); + superLib.takesVar(null); + unboundLib.takesVar(null); + + } + +} diff --git a/java/ql/test/library-tests/wildcard-substitution/test.expected b/java/ql/test/library-tests/wildcard-substitution/test.expected new file mode 100644 index 00000000000..91a1cc43cb0 --- /dev/null +++ b/java/ql/test/library-tests/wildcard-substitution/test.expected @@ -0,0 +1,64 @@ +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsArray | CharSequence[] | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | CharSequence | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesArray | [] | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsArray | Object[] | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | Object | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesArray | CharSequence[] | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | CharSequence | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsArray | Object[] | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | Object | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesArray | [] | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsArray | CharSequence[] | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | CharSequence | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesArray | CharSequence[] | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | CharSequence | +| Lib.java:3:14:3:16 | Lib | Lib.java:5:15:5:22 | takesVar | T | +| Lib.java:3:14:3:16 | Lib | Lib.java:6:15:6:24 | takesInvar | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:7:15:7:26 | takesUnbound | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:8:15:8:26 | takesExtends | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:9:15:9:24 | takesSuper | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:11:12:11:21 | returnsVar | T | +| Lib.java:3:14:3:16 | Lib | Lib.java:12:18:12:29 | returnsInvar | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:13:18:13:31 | returnsUnbound | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:14:28:14:41 | returnsExtends | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:15:26:15:37 | returnsSuper | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:17:15:17:24 | takesArray | T[] | +| Lib.java:3:14:3:16 | Lib | Lib.java:18:14:18:25 | returnsArray | T[] | +| User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | +| User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | +| User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | +| User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | diff --git a/java/ql/test/library-tests/wildcard-substitution/test.ql b/java/ql/test/library-tests/wildcard-substitution/test.ql new file mode 100644 index 00000000000..3fdf1c00a55 --- /dev/null +++ b/java/ql/test/library-tests/wildcard-substitution/test.ql @@ -0,0 +1,7 @@ +import java + +Type notVoid(Type t) { result = t and not result instanceof VoidType } + +from Callable c +where c.getSourceDeclaration().fromSource() +select c.getDeclaringType(), c, notVoid([c.getAParamType(), c.getReturnType()]).toString() diff --git a/java/ql/test/library-tests/xml/Test.java b/java/ql/test/library-tests/xml/Test.java new file mode 100644 index 00000000000..4566fbca2ad --- /dev/null +++ b/java/ql/test/library-tests/xml/Test.java @@ -0,0 +1,3 @@ +public class Test { + +} diff --git a/java/ql/test/library-tests/xml/XMLTest.expected b/java/ql/test/library-tests/xml/XMLTest.expected new file mode 100644 index 00000000000..61d3c801963 --- /dev/null +++ b/java/ql/test/library-tests/xml/XMLTest.expected @@ -0,0 +1,2 @@ +| test.xml:4:5:4:32 | attribute=value | Unexpected result: hasXmlResult= | +| test.xml:5:29:5:52 | $ hasXmlResult | Missing result:hasXmlResult= | \ No newline at end of file diff --git a/java/ql/test/library-tests/xml/XMLTest.ql b/java/ql/test/library-tests/xml/XMLTest.ql new file mode 100644 index 00000000000..fb51e0a1506 --- /dev/null +++ b/java/ql/test/library-tests/xml/XMLTest.ql @@ -0,0 +1,17 @@ +import semmle.code.xml.XML +import TestUtilities.InlineExpectationsTest + +class XmlTest extends InlineExpectationsTest { + XmlTest() { this = "XmlTest" } + + override string getARelevantTag() { result = "hasXmlResult" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasXmlResult" and + exists(XMLAttribute a | + a.getLocation() = location and + element = a.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/library-tests/xml/test.xml b/java/ql/test/library-tests/xml/test.xml new file mode 100644 index 00000000000..f0d9262f09f --- /dev/null +++ b/java/ql/test/library-tests/xml/test.xml @@ -0,0 +1,6 @@ + + + Text + Text + Text + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt b/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt new file mode 100644 index 00000000000..f2f18eaeb0a --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt @@ -0,0 +1,11 @@ +import android.app.Activity +import android.content.Context +import android.content.SharedPreferences + +class CleartextStorageSharedPrefsTestKt : Activity() { + fun testSetSharedPrefs1(context: Context, name: String, password: String) { + val sharedPrefs = context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE); + sharedPrefs.edit().putString("name", name).apply(); // Safe + sharedPrefs.edit().putString("password", password).apply(); // $ hasCleartextStorageSharedPrefs + } +} diff --git a/java/ql/test/query-tests/security/CWE-312/options b/java/ql/test/query-tests/security/CWE-312/options index f017f81ff2f..93845c4b2a8 100644 --- a/java/ql/test/query-tests/security/CWE-312/options +++ b/java/ql/test/query-tests/security/CWE-312/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/query-tests/security/CWE-749/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml index b215e4d3466..79d79d0cd10 100755 --- a/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml +++ b/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml @@ -44,6 +44,7 @@ + diff --git a/java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt b/java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt new file mode 100644 index 00000000000..d20845f5c77 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt @@ -0,0 +1,20 @@ +package com.example.app + +import android.app.Activity +import android.os.Bundle +import android.webkit.WebSettings +import android.webkit.WebView +import android.webkit.WebViewClient + +class UnsafeActivityKt : Activity() { + override fun onCreate(savedInstanceState : Bundle) { + + val wv = findViewById(-1) + // Implicit not-nulls happening here + wv.settings.setJavaScriptEnabled(true) + wv.settings.setAllowFileAccessFromFileURLs(true) + + val thisUrl : String = intent.extras.getString("url") + wv.loadUrl(thisUrl) // $ hasUnsafeAndroidAccess + } +} diff --git a/java/ql/test/query-tests/security/CWE-749/options b/java/ql/test/query-tests/security/CWE-749/options index d6a9adcece3..49f527db1db 100644 --- a/java/ql/test/query-tests/security/CWE-749/options +++ b/java/ql/test/query-tests/security/CWE-749/options @@ -1 +1,2 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/android +//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/query-tests/security/CWE-925/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-925/AndroidManifest.xml new file mode 100644 index 00000000000..f9e11a1ee81 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-925/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java b/java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java new file mode 100644 index 00000000000..3a9f8498396 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java @@ -0,0 +1,13 @@ +package test; +import android.content.Intent; +import android.content.Context; +import android.content.BroadcastReceiver; + +class BootReceiverXml extends BroadcastReceiver { + void doStuff(Intent intent) {} + + @Override + public void onReceive(Context ctx, Intent intent) { // $hasResult + doStuff(intent); + } +} \ No newline at end of file diff --git a/swift/integration-tests/frontend-invocations/C.swift b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected similarity index 100% rename from swift/integration-tests/frontend-invocations/C.swift rename to java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql new file mode 100644 index 00000000000..30ced62b2ed --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql @@ -0,0 +1,18 @@ +import java +import semmle.code.java.security.ImproperIntentVerificationQuery +import TestUtilities.InlineExpectationsTest + +class HasFlowTest extends InlineExpectationsTest { + HasFlowTest() { this = "HasFlowTest" } + + override string getARelevantTag() { result = "hasResult" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasResult" and + exists(Method orm | unverifiedSystemReceiver(_, orm, _) | + orm.getLocation() = location and + element = orm.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-925/options b/java/ql/test/query-tests/security/CWE-925/options new file mode 100644 index 00000000000..5a47a1d8fd3 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-925/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/stubs/google-android-9.0.0/android/os/Environment.java b/java/ql/test/stubs/google-android-9.0.0/android/os/Environment.java new file mode 100644 index 00000000000..1d7b49061e7 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/os/Environment.java @@ -0,0 +1,50 @@ +// Generated automatically from android.os.Environment for testing purposes + +package android.os; + +import java.io.File; + +public class Environment +{ + public Environment(){} + public static File getDataDirectory(){ return null; } + public static File getDownloadCacheDirectory(){ return null; } + public static File getExternalStorageDirectory(){ return null; } + public static File getExternalStoragePublicDirectory(String p0){ return null; } + public static File getRootDirectory(){ return null; } + public static File getStorageDirectory(){ return null; } + public static String DIRECTORY_ALARMS = null; + public static String DIRECTORY_AUDIOBOOKS = null; + public static String DIRECTORY_DCIM = null; + public static String DIRECTORY_DOCUMENTS = null; + public static String DIRECTORY_DOWNLOADS = null; + public static String DIRECTORY_MOVIES = null; + public static String DIRECTORY_MUSIC = null; + public static String DIRECTORY_NOTIFICATIONS = null; + public static String DIRECTORY_PICTURES = null; + public static String DIRECTORY_PODCASTS = null; + public static String DIRECTORY_RINGTONES = null; + public static String DIRECTORY_SCREENSHOTS = null; + public static String MEDIA_BAD_REMOVAL = null; + public static String MEDIA_CHECKING = null; + public static String MEDIA_EJECTING = null; + public static String MEDIA_MOUNTED = null; + public static String MEDIA_MOUNTED_READ_ONLY = null; + public static String MEDIA_NOFS = null; + public static String MEDIA_REMOVED = null; + public static String MEDIA_SHARED = null; + public static String MEDIA_UNKNOWN = null; + public static String MEDIA_UNMOUNTABLE = null; + public static String MEDIA_UNMOUNTED = null; + public static String getExternalStorageState(){ return null; } + public static String getExternalStorageState(File p0){ return null; } + public static String getStorageState(File p0){ return null; } + public static boolean isExternalStorageEmulated(){ return false; } + public static boolean isExternalStorageEmulated(File p0){ return false; } + public static boolean isExternalStorageLegacy(){ return false; } + public static boolean isExternalStorageLegacy(File p0){ return false; } + public static boolean isExternalStorageManager(){ return false; } + public static boolean isExternalStorageManager(File p0){ return false; } + public static boolean isExternalStorageRemovable(){ return false; } + public static boolean isExternalStorageRemovable(File p0){ return false; } +} diff --git a/javascript/externs/nodejs/fs.js b/javascript/externs/nodejs/fs.js index a1ce1f83a7e..1afdf83bcd0 100644 --- a/javascript/externs/nodejs/fs.js +++ b/javascript/externs/nodejs/fs.js @@ -1696,4 +1696,3 @@ module.exports.R_OK = fs.R_OK; module.exports.W_OK = fs.W_OK; module.exports.X_OK = fs.X_OK; - diff --git a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql index 2286fdc2121..b146b19e54d 100644 --- a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql +++ b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql @@ -14,7 +14,7 @@ import DataFlow::PathGraph /** * Gets the name of an unescaped placeholder in a lodash template. * - * For example, the string `

    <%= title %>

    ` contains the placeholder `title`. + * For example, the string `"

    <%= title %>

    "` contains the placeholder "title". */ bindingset[s] string getAPlaceholderInString(string s) { diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index a3699882eab..23d54f955a7 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,21 @@ +## 0.2.1 + +### Minor Analysis Improvements + +* The `chownr` library is now modeled as a sink for the `js/path-injection` query. +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). +* The `gray-matter` library is now modeled as a sink for the `js/code-injection` query. + +## 0.2.0 + +### Major Analysis Improvements + +* Added support for TypeScript 4.7. + +### Minor Analysis Improvements + +* All new ECMAScript 2022 features are now supported. + ## 0.1.4 ## 0.1.3 diff --git a/javascript/ql/src/Declarations/Declarations.qll b/javascript/ql/lib/Declarations/Declarations.qll similarity index 100% rename from javascript/ql/src/Declarations/Declarations.qll rename to javascript/ql/lib/Declarations/Declarations.qll diff --git a/javascript/ql/src/IDEContextual.qll b/javascript/ql/lib/IDEContextual.qll similarity index 100% rename from javascript/ql/src/IDEContextual.qll rename to javascript/ql/lib/IDEContextual.qll diff --git a/javascript/ql/lib/change-notes/2022-05-24-ecmascript-2022.md b/javascript/ql/lib/change-notes/2022-05-24-ecmascript-2022.md deleted file mode 100644 index 389b7c9044b..00000000000 --- a/javascript/ql/lib/change-notes/2022-05-24-ecmascript-2022.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* All new ECMAScript 2022 features are now supported. diff --git a/javascript/ql/lib/change-notes/2022-05-24-typescript-4-7.md b/javascript/ql/lib/change-notes/2022-05-24-typescript-4-7.md deleted file mode 100644 index 16fe46c675f..00000000000 --- a/javascript/ql/lib/change-notes/2022-05-24-typescript-4-7.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Added support for TypeScript 4.7. diff --git a/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words.md b/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words.md deleted file mode 100644 index 9102d58abdb..00000000000 --- a/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). diff --git a/javascript/ql/lib/change-notes/released/0.2.0.md b/javascript/ql/lib/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..6656adbcab5 --- /dev/null +++ b/javascript/ql/lib/change-notes/released/0.2.0.md @@ -0,0 +1,9 @@ +## 0.2.0 + +### Major Analysis Improvements + +* Added support for TypeScript 4.7. + +### Minor Analysis Improvements + +* All new ECMAScript 2022 features are now supported. diff --git a/javascript/ql/lib/change-notes/released/0.2.1.md b/javascript/ql/lib/change-notes/released/0.2.1.md new file mode 100644 index 00000000000..3548bd5ad69 --- /dev/null +++ b/javascript/ql/lib/change-notes/released/0.2.1.md @@ -0,0 +1,7 @@ +## 0.2.1 + +### Minor Analysis Improvements + +* The `chownr` library is now modeled as a sink for the `js/path-injection` query. +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). +* The `gray-matter` library is now modeled as a sink for the `js/code-injection` query. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index e8ee3af8ef9..df29a726bcc 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.1 diff --git a/javascript/ql/src/definitions.qll b/javascript/ql/lib/definitions.qll similarity index 99% rename from javascript/ql/src/definitions.qll rename to javascript/ql/lib/definitions.qll index 4d0c0d50176..7b4806b1478 100644 --- a/javascript/ql/src/definitions.qll +++ b/javascript/ql/lib/definitions.qll @@ -45,7 +45,7 @@ private predicate variableDefLookup(VarAccess va, AstNode def, string kind) { /** * Holds if variable access `va` is of kind `kind` and refers to the - * variable declaration. + * variable declaration `decl`. * * For example, in the statement `var x = 42, y = x;`, the initializing * expression of `y` is a variable access `x` of kind `"V"` that refers to diff --git a/javascript/ql/src/localDefinitions.ql b/javascript/ql/lib/localDefinitions.ql similarity index 100% rename from javascript/ql/src/localDefinitions.ql rename to javascript/ql/lib/localDefinitions.ql diff --git a/javascript/ql/src/localReferences.ql b/javascript/ql/lib/localReferences.ql similarity index 100% rename from javascript/ql/src/localReferences.ql rename to javascript/ql/lib/localReferences.ql diff --git a/javascript/ql/src/printAst.ql b/javascript/ql/lib/printAst.ql similarity index 100% rename from javascript/ql/src/printAst.ql rename to javascript/ql/lib/printAst.ql diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 7c558ea66e8..9a05a09e0b6 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.2.0-dev +version: 0.2.2-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/lib/semmle/javascript/Actions.qll b/javascript/ql/lib/semmle/javascript/Actions.qll index f5b2c39b064..8ea789c96e0 100644 --- a/javascript/ql/lib/semmle/javascript/Actions.qll +++ b/javascript/ql/lib/semmle/javascript/Actions.qll @@ -28,6 +28,9 @@ module Actions { /** Gets the `jobs` mapping from job IDs to job definitions in this workflow. */ YAMLMapping getJobs() { result = this.lookup("jobs") } + /** Gets the name of the workflow. */ + string getName() { result = this.lookup("name").(YAMLString).getValue() } + /** Gets the name of the workflow file. */ string getFileName() { result = this.getFile().getBaseName() } @@ -129,6 +132,9 @@ module Actions { /** Gets the value of the `if` field in this step, if any. */ StepIf getIf() { result.getStep() = this } + + /** Gets the ID of this step, if any. */ + string getId() { result = this.lookup("id").(YAMLString).getValue() } } /** diff --git a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll index 2b02b6b6486..6e6579d6f7e 100644 --- a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll +++ b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll @@ -146,7 +146,7 @@ class BasicBlock extends @cfg_node, NodeInStmtContainer { /** Holds if this basic block uses variable `v` in its `i`th node `u`. */ predicate useAt(int i, Variable v, VarUse u) { useAt(this, i, v, u) } - /** Holds if this basic block defines variable `v` in its `i`th node `u`. */ + /** Holds if this basic block defines variable `v` in its `i`th node `d`. */ predicate defAt(int i, Variable v, VarDef d) { defAt(this, i, v, d) } /** diff --git a/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll b/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll index 1a19112cee3..5c8dd2bdd06 100644 --- a/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll +++ b/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll @@ -75,7 +75,7 @@ module CharacterEscapes { } /** - * Gets a character in `n` that is preceded by a single useless backslash, resulting in a likely regular expression mistake explained by `mistake`. + * Gets a character in `src` that is preceded by a single useless backslash, resulting in a likely regular expression mistake explained by `mistake`. * * The character is the `i`th character of the raw string value of `rawStringNode`. */ diff --git a/javascript/ql/lib/semmle/javascript/Classes.qll b/javascript/ql/lib/semmle/javascript/Classes.qll index 5004ccc9b5f..23dc738345d 100644 --- a/javascript/ql/lib/semmle/javascript/Classes.qll +++ b/javascript/ql/lib/semmle/javascript/Classes.qll @@ -172,7 +172,7 @@ class ClassDefinition extends @class_definition, ClassOrInterface, AST::ValueNod /** Gets the expression denoting the super class of the defined class, if any. */ override Expr getSuperClass() { result = this.getChildExpr(1) } - /** Gets the `n`th type from the `implements` clause of this class, starting at 0. */ + /** Gets the `i`th type from the `implements` clause of this class, starting at 0. */ override TypeExpr getSuperInterface(int i) { // AST indices for super interfaces: -1, -4, -7, ... exists(int astIndex | typeexprs(result, _, this, astIndex, _) | diff --git a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll index 6e1be383362..f6e759b87e7 100644 --- a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll +++ b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll @@ -54,7 +54,7 @@ private predicate hasNamedExports(ES2015Module mod) { } /** - * Holds if this module contains a `default` export. + * Holds if this module contains a default export. */ private predicate hasDefaultExport(ES2015Module mod) { // export default foo; @@ -337,7 +337,7 @@ class BulkReExportDeclaration extends ReExportDeclaration, @export_all_declarati } /** - * Holds if the given bulk export should not re-export `name` because there is an explicit export + * Holds if the given bulk export `reExport` should not re-export `name` because there is an explicit export * of that name in the same module. * * At compile time, shadowing works across declaration spaces. diff --git a/javascript/ql/lib/semmle/javascript/Paths.qll b/javascript/ql/lib/semmle/javascript/Paths.qll index e22d5ad6132..7574fe1e301 100644 --- a/javascript/ql/lib/semmle/javascript/Paths.qll +++ b/javascript/ql/lib/semmle/javascript/Paths.qll @@ -180,7 +180,7 @@ private Path resolveUpTo(PathString p, int n, Folder root, boolean inTS) { } /** - * Gets the `i`th component of the path `str`, where `base` is the resolved path one level up. + * Gets the `n`th component of the path `str`, where `base` is the resolved path one level up. * Supports that the root directory might be compiled output from TypeScript. * `inTS` is true if the result is TypeScript that is compiled into the path specified by `str`. */ @@ -227,7 +227,7 @@ private module TypeScriptOutDir { } /** - * Gets the `outDir` option from a tsconfig file from the folder `parent`. + * Gets the "outDir" option from a `tsconfig` file from the folder `parent`. */ private string getOutDir(JsonObject tsconfig, Folder parent) { tsconfig.getFile().getBaseName().regexpMatch("tsconfig.*\\.json") and diff --git a/javascript/ql/lib/semmle/javascript/PrintAst.qll b/javascript/ql/lib/semmle/javascript/PrintAst.qll index 3da7eac2de2..672c2ab5a9e 100644 --- a/javascript/ql/lib/semmle/javascript/PrintAst.qll +++ b/javascript/ql/lib/semmle/javascript/PrintAst.qll @@ -195,7 +195,7 @@ private module PrintJavaScript { * Gets the `i`th child of `element`. * Can be overridden in subclasses to get more specific behavior for `getChild()`. */ - AstNode getChildNode(int childIndex) { result = getLocationSortedChild(element, childIndex) } + AstNode getChildNode(int i) { result = getLocationSortedChild(element, i) } } /** Provides predicates for pretty printing `AstNode`s. */ diff --git a/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll b/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll index 5c15ea3d3aa..9d8b3967b1c 100644 --- a/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll +++ b/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll @@ -260,7 +260,7 @@ module RangeAnalysis { } /** - * Holds if the given comparison can be modeled as `A B + bias` where `` is the comparison operator, + * Holds if the given `comparison` can be modeled as `A B + bias` where `` is the comparison operator, * and `A` is `a * asign` and likewise `B` is `b * bsign`. */ predicate linearComparison( @@ -310,18 +310,18 @@ module RangeAnalysis { * Holds if `guard` asserts that the outcome of `A B + bias` is true, where `` is a comparison operator. */ predicate linearComparisonGuard( - ConditionGuardNode guard, DataFlow::Node a, int asign, string operator, DataFlow::Node b, - int bsign, Bias bias + ConditionGuardNode guard, DataFlow::Node a, int asign, string op, DataFlow::Node b, int bsign, + Bias bias ) { exists(Comparison compare | compare = guard.getTest().flow().getImmediatePredecessor*().asExpr() and linearComparison(compare, a, asign, b, bsign, bias) and ( - guard.getOutcome() = true and operator = compare.getOperator() + guard.getOutcome() = true and op = compare.getOperator() or not hasNaNIndicator(guard.getContainer()) and guard.getOutcome() = false and - operator = negateOperator(compare.getOperator()) + op = negateOperator(compare.getOperator()) ) ) } @@ -657,13 +657,13 @@ module RangeAnalysis { */ pragma[noopt] private predicate reachableByNegativeEdges( - DataFlow::Node a, int asign, DataFlow::Node b, int bsign, ControlFlowNode cfg + DataFlow::Node src, int asign, DataFlow::Node dst, int bsign, ControlFlowNode cfg ) { - negativeEdge(a, asign, b, bsign, cfg) + negativeEdge(src, asign, dst, bsign, cfg) or exists(DataFlow::Node mid, int midx, ControlFlowNode midcfg | - reachableByNegativeEdges(a, asign, mid, midx, cfg) and - negativeEdge(mid, midx, b, bsign, midcfg) and + reachableByNegativeEdges(src, asign, mid, midx, cfg) and + negativeEdge(mid, midx, dst, bsign, midcfg) and exists(BasicBlock bb, int i, int j | bb.getNode(i) = midcfg and bb.getNode(j) = cfg and @@ -676,8 +676,8 @@ module RangeAnalysis { DataFlow::Node mid, int midx, ControlFlowNode midcfg, BasicBlock midBB, ReachableBasicBlock midRBB, BasicBlock cfgBB | - reachableByNegativeEdges(a, asign, mid, midx, cfg) and - negativeEdge(mid, midx, b, bsign, midcfg) and + reachableByNegativeEdges(src, asign, mid, midx, cfg) and + negativeEdge(mid, midx, dst, bsign, midcfg) and midBB = midcfg.getBasicBlock() and midRBB = midBB.(ReachableBasicBlock) and cfgBB = cfg.getBasicBlock() and diff --git a/javascript/ql/lib/semmle/javascript/Routing.qll b/javascript/ql/lib/semmle/javascript/Routing.qll index 858ec1ad238..b89a2e257a8 100644 --- a/javascript/ql/lib/semmle/javascript/Routing.qll +++ b/javascript/ql/lib/semmle/javascript/Routing.qll @@ -148,6 +148,18 @@ module Routing { this instanceof MkRouter } + /** + * Like `mayResumeDispatch` but without the assumption that functions with an unknown + * implementation invoke their continuation. + */ + predicate definitelyResumesDispatch() { + this.getLastChild().definitelyResumesDispatch() + or + exists(this.(RouteHandler).getAContinuationInvocation()) + or + this instanceof MkRouter + } + /** Gets the parent of this node, provided that this node may invoke its continuation. */ private Node getContinuationParent() { result = this.getParent() and @@ -229,7 +241,7 @@ module Routing { } /** - * Holds if `node` has processed the incoming request strictly prior to this node. + * Holds if `guard` has processed the incoming request strictly prior to this node. */ pragma[inline] private predicate isGuardedByNodeInternal(Node guard) { diff --git a/javascript/ql/lib/semmle/javascript/SSA.qll b/javascript/ql/lib/semmle/javascript/SSA.qll index 41831a282ac..8e60fb0c3e4 100644 --- a/javascript/ql/lib/semmle/javascript/SSA.qll +++ b/javascript/ql/lib/semmle/javascript/SSA.qll @@ -501,7 +501,7 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef { } /** This SSA definition corresponds to the definition of `v` at `def`. */ - predicate defines(VarDef d, SsaSourceVariable v) { this = TExplicitDef(_, _, d, v) } + predicate defines(VarDef def, SsaSourceVariable v) { this = TExplicitDef(_, _, def, v) } /** Gets the variable definition wrapped by this SSA definition. */ VarDef getDef() { this = TExplicitDef(_, _, result, _) } diff --git a/javascript/ql/lib/semmle/javascript/TypeScript.qll b/javascript/ql/lib/semmle/javascript/TypeScript.qll index 3f27fc0bd7c..51b68220a9e 100644 --- a/javascript/ql/lib/semmle/javascript/TypeScript.qll +++ b/javascript/ql/lib/semmle/javascript/TypeScript.qll @@ -751,7 +751,7 @@ class TypeAccess extends @typeaccess, TypeExpr, TypeRef { } /** - * Gets a suitable name for the library imported by `import`. + * Gets a suitable name for the library imported by `imprt`. * * For relative imports, this is the snapshot-relative path to the imported module. * For non-relative imports, it is the import path itself. diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index f8625afd25f..19153304811 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -353,7 +353,7 @@ abstract class BarrierGuardNode extends DataFlow::Node { } /** - * Holds if data flow node `nd` acts as a barrier for data flow. + * Holds if data flow node `guard` acts as a barrier for data flow. * * `label` is bound to the blocked label, or the empty string if all labels should be blocked. */ @@ -382,7 +382,7 @@ private predicate barrierGuardIsRelevant(BarrierGuardNode guard) { } /** - * Holds if data flow node `nd` acts as a barrier for data flow due to aliasing through + * Holds if data flow node `guard` acts as a barrier for data flow due to aliasing through * an access path. * * `label` is bound to the blocked label, or the empty string if all labels should be blocked. @@ -1155,7 +1155,7 @@ private predicate appendStep( } /** - * Holds if a function invoked at `invk` may return an expression into which `input`, + * Holds if a function invoked at `output` may return an expression into which `input`, * which is either an argument or a definition captured by the function, flows under * configuration `cfg`, possibly through callees. */ @@ -1395,7 +1395,7 @@ private predicate reachableFromStoreBase( } /** - * Holds if `base` is the base of a write to property `prop`, and `nd` is reachable + * Holds if `base` is the base of a write to property `endProp`, and `nd` is reachable * from `base` under configuration `cfg` (possibly through callees) along a path whose * last step is summarized by `newSummary`, and the previous steps are summarized * by `oldSummary`. @@ -1758,7 +1758,7 @@ class PathNode extends TPathNode { this = MkSinkNode(nd, cfg) } - /** Holds if this path node wraps data-flow node `nd` and configuration `c`. */ + /** Holds if this path node wraps data-flow node `n` and configuration `c`. */ predicate wraps(DataFlow::Node n, DataFlow::Configuration c) { nd = n and cfg = c } /** Gets the underlying configuration of this path node. */ @@ -1873,7 +1873,7 @@ class MidPathNode extends PathNode, MkMidNode { MidPathNode() { this = MkMidNode(nd, cfg, summary) } - /** Holds if this path node wraps data-flow node `nd`, configuration `c` and summary `s`. */ + /** Holds if this path node wraps data-flow node `n`, configuration `c` and summary `s`. */ predicate wraps(DataFlow::Node n, DataFlow::Configuration c, PathSummary s) { nd = n and cfg = c and summary = s } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index 36cacb1d7d7..bad3c47ef89 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1653,7 +1653,7 @@ module DataFlow { } /** - * Holds if the flow information for this node is incomplete. + * Holds if the flow information for the node `nd`. * * This predicate holds if there may be a source flow node from which data flows into * this node, but that node is not a result of `getALocalSource()` due to analysis incompleteness. diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll b/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll index 299819de4cd..3a8e0b477fb 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll @@ -498,7 +498,7 @@ private module ReturnPortal { invk = callee.getAnExitNode(isRemote).getAnInvocation() } - /** Holds if `ret` is a return node of a function flowing through `callee`. */ + /** Holds if `ret` is a return node of a function flowing through `base`. */ predicate returns(Portal base, DataFlow::Node ret, boolean escapes) { ret = base.getAnEntryNode(escapes).getALocalSource().(DataFlow::FunctionNode).getAReturn() } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 0f82ec2e8e6..86fc96a79cc 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -831,7 +831,7 @@ module TaintTracking { } /** - * Holds if the property `loadStep` should be copied from the object `pred` to the property `storeStep` of object `succ`. + * Holds if the property `loadProp` should be copied from the object `pred` to the property `storeProp` of object `succ`. * * This step is used to copy the value of our pseudo-property that can later be accessed using a `get` or `getAll` call. * For an expression `url.searchParams`, the property `hiddenUrlPseudoProperty()` from the `url` object is stored in the property `getableUrlPseudoProperty()` on `url.searchParams`. @@ -1126,6 +1126,19 @@ module TaintTracking { ) } + /** A test for the value of `typeof x`, restricting the potential types of `x`. */ + predicate isStringTypeGuard(EqualityTest test, Expr operand, boolean polarity) { + exists(TypeofTag tag | TaintTracking::isTypeofGuard(test, operand, tag) | + // typeof x === "string" sanitizes `x` when it evaluates to false + tag = "string" and + polarity = test.getPolarity().booleanNot() + or + // typeof x === "object" sanitizes `x` when it evaluates to true + tag != "string" and + polarity = test.getPolarity() + ) + } + /** Holds if `guard` is a test that checks if `operand` is a number. */ predicate isNumberGuard(DataFlow::Node guard, Expr operand, boolean polarity) { exists(DataFlow::CallNode isNaN | diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TypeTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TypeTracking.qll index 896f0177ec3..12aa8d09ed1 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TypeTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TypeTracking.qll @@ -312,7 +312,7 @@ class TypeBackTracker extends TTypeBackTracker { * result = < some API call >.getArgument(< n >) * or * exists (DataFlow::TypeBackTracker t2 | - * t = t2.smallstep(result, myType(t2)) + * t2 = t.smallstep(result, myType(t2)) * ) * } * diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll index 56fca49cd10..050c123e30a 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll @@ -15,11 +15,11 @@ import javascript abstract class NgSourceProvider extends Locatable { /** * Holds if this element provides the source as `src` for an AngularJS expression at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. + * The location spans column `startColumn` of line `startLine` to + * column `endColumn` of line `endLine` in file `filepath`. */ abstract predicate providesSourceAt( - string src, string path, int startLine, int startColumn, int endLine, int endColumn + string src, string filepath, int startLine, int startColumn, int endLine, int endColumn ); /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll index dcce784cd1a..6d421de851c 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll @@ -278,11 +278,11 @@ abstract private class CustomSpecialServiceDefinition extends CustomServiceDefin bindingset[moduleMethodName] private predicate isCustomServiceDefinitionOnModule( DataFlow::CallNode mce, string moduleMethodName, string serviceName, - DataFlow::Node factoryArgument + DataFlow::Node factoryFunction ) { mce = moduleRef(_).getAMethodCall(moduleMethodName) and mce.getArgument(0).asExpr().mayHaveStringValue(serviceName) and - factoryArgument = mce.getArgument(1) + factoryFunction = mce.getArgument(1) } pragma[inline] diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll b/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll index d7fd51c1b82..1315ac651d5 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll @@ -102,9 +102,9 @@ private predicate isBrowserifyDependencyMap(ObjectExpr deps) { * Holds if `m` is a function that looks like a bundled module created * by Webpack. * - * Parameters must be named either `module` or `exports`, - * or their name must contain the substring `webpack_require` - * or `webpack_module_template_argument`. + * Parameters must be named either "module" or "exports", + * or their name must contain the substring "webpack_require" + * or "webpack_module_template_argument". */ private predicate isWebpackModule(FunctionExpr m) { forex(Parameter parm | parm = m.getAParameter() | diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll b/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll index 9da7c959cb0..489fcf550c4 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll @@ -50,7 +50,7 @@ module ConnectExpressShared { } /** - * Holds if `fun` appears to match the given signature based on parameter naming. + * Holds if `function` appears to match the given signature based on parameter naming. */ private predicate matchesSignature(Function function, RouteHandlerSignature sig) { function.getNumParameter() = sig.getArity() and diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll index ca9a151e3c6..19616530763 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll @@ -33,6 +33,11 @@ module Express { or // `app = [new] express.Router()` result = DataFlow::moduleMember("express", "Router").getAnInvocation() + or + exists(DataFlow::SourceNode app | + app.hasUnderlyingType("probot/lib/application", "Application") and + result = app.getAMethodCall("route") + ) } /** @@ -1043,4 +1048,22 @@ module Express { override DataFlow::SourceNode getOutput() { result = this.getCallback(2).getParameter(1) } } + + private class ResumeDispatchRefinement extends Routing::RouteHandler { + ResumeDispatchRefinement() { this.getFunction() instanceof RouteHandler } + + override predicate mayResumeDispatch() { this.getAParameter().getName() = "next" } + + override predicate definitelyResumesDispatch() { this.getAParameter().getName() = "next" } + } + + private class ExpressStaticResumeDispatchRefinement extends Routing::Node { + ExpressStaticResumeDispatchRefinement() { + this = Routing::getNode(DataFlow::moduleMember("express", "static").getACall()) + } + + override predicate mayResumeDispatch() { none() } + + override predicate definitelyResumesDispatch() { none() } + } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll b/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll index 431007cd944..000015191f8 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll @@ -299,7 +299,7 @@ module Fastify { } /** - * Holds if `rh` uses `plugin`. + * Holds if `rh` uses `middleware`. */ private predicate usesMiddleware(RouteHandler rh, DataFlow::SourceNode middleware) { exists(RouteSetup setup | diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Files.qll b/javascript/ql/lib/semmle/javascript/frameworks/Files.qll index f03f5ee1458..244c9c502c2 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Files.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Files.qll @@ -192,6 +192,18 @@ private class WriteFileAtomic extends FileSystemWriteAccess, DataFlow::CallNode override DataFlow::Node getADataNode() { result = this.getArgument(1) } } +/** + * A call to the library `chownr`. + * The library changes the owner of a file or directory recursively. + */ +private class Chownr extends FileSystemWriteAccess, DataFlow::CallNode { + Chownr() { this = DataFlow::moduleImport("chownr").getACall() } + + override DataFlow::Node getAPathArgument() { result = this.getArgument(0) } + + override DataFlow::Node getADataNode() { none() } +} + /** * A call to the library `recursive-readdir`. */ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll index 0d2da4b10bb..45146fd6b9f 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll @@ -583,11 +583,11 @@ private module Minimongo { */ module CollectionMethodSignatures { /** - * Holds if Collection method `name` interprets parameter `n` as a query. + * Holds if Collection method `name` interprets parameter `queryArgIdx` as a query. */ - predicate interpretsArgumentAsQuery(string m, int queryArgIdx) { + predicate interpretsArgumentAsQuery(string name, int queryArgIdx) { // implements most of the MongoDB interface - MongoDB::CollectionMethodSignatures::interpretsArgumentAsQuery(m, queryArgIdx) + MongoDB::CollectionMethodSignatures::interpretsArgumentAsQuery(name, queryArgIdx) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index 75e222730cc..5bd92e3ec5c 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -474,17 +474,17 @@ module NodeJSLib { * that receives the data. * * We determine this by looking for an externs declaration for - * `fs.methodName` where the `i`th parameter's name is `data` or + * `fs.methodName` where the `i`th parameter's name (`paramName`) is `data` or * `buffer` or a `callback`. */ - private predicate fsDataParam(string methodName, int i, string n) { + private predicate fsDataParam(string methodName, int i, string paramName) { exists(ExternalMemberDecl decl, Function f, JSDocParamTag p | decl.hasQualifiedName("fs", methodName) and f = decl.getInit() and p.getDocumentedParameter() = f.getParameter(i).getAVariable() and - n = p.getName().toLowerCase() + paramName = p.getName().toLowerCase() | - n = "data" or n = "buffer" or n = "callback" + paramName = ["data", "buffer", "callback"] ) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll b/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll index e48d674fa74..238bcae482a 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll @@ -55,7 +55,7 @@ module SocketIO { /** Gets the namespace with the given path of this server. */ NamespaceObject getNamespace(string path) { result = MkNamespace(this, path) } - /** Gets a api node that may refer to the socket.io server created at `srv`. */ + /** Gets a api node that may refer to a socket.io server. */ private API::Node server() { result = node or @@ -144,7 +144,7 @@ module SocketIO { override NamespaceObject getNamespace() { result = ns } /** - * Gets a data flow node that may refer to the socket.io namespace created at `ns`. + * Gets a data flow node that may refer a the socket.io namespace. */ private API::Node namespace() { result = node diff --git a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll index cc94c966c32..0f2b36216c9 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll @@ -309,12 +309,13 @@ private module JQueryClientRequest { /** * Gets a node referring to the response contained in an `jqXHR` object. */ - private DataFlow::SourceNode getAResponseNodeFromAnXHRObject(DataFlow::SourceNode obj) { + private DataFlow::SourceNode getAResponseNodeFromAnXHRObject(DataFlow::SourceNode jqXHR) { result = - obj.getAPropertyRead(any(string s | - s = "responseText" or - s = "responseXML" - )) + jqXHR + .getAPropertyRead(any(string s | + s = "responseText" or + s = "responseXML" + )) } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll index e643387c5e4..1884496fff9 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll @@ -106,6 +106,10 @@ module ClientSideUrlRedirect { ) and xss = true or + // A call to `navigation.navigate` + this = DataFlow::globalVarRef("navigation").getAMethodCall("navigate").getArgument(0) and + xss = true + or // An assignment to `location` exists(Assignment assgn | isLocation(assgn.getTarget()) and astNode = assgn.getRhs()) and xss = true diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll index 69427e12d7b..9e72cc9ee82 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll @@ -51,6 +51,18 @@ module CodeInjection { } } + /** An expression parsed by the `gray-matter` library. */ + class GrayMatterSink extends Sink { + GrayMatterSink() { + exists(API::CallNode call | + call = DataFlow::moduleImport("gray-matter").getACall() and + this = call.getArgument(0) and + // if the js/javascript engine is set, then we assume they are set to something safe. + not exists(call.getParameter(1).getMember("engines").getMember(["js", "javascript"])) + ) + } + } + /** * A template tag occurring in JS code, viewed as a code injection sink. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll index 6ee16daa78f..fd549429e4a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll @@ -80,7 +80,7 @@ module UnsafeHtmlConstruction { t.start() and result = sink or - exists(DataFlow::TypeBackTracker t2 | t = t2.smallstep(result, isUsedInXssSink(t2, sink))) + exists(DataFlow::TypeBackTracker t2 | t2 = t.smallstep(result, isUsedInXssSink(t2, sink))) or exists(DataFlow::TypeBackTracker t2 | t.continue() = t2 and @@ -180,4 +180,18 @@ module UnsafeHtmlConstruction { override string describe() { result = "Markdown rendering" } } + + /** A test for the value of `typeof x`, restricting the potential types of `x`. */ + class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { + override EqualityTest astNode; + Expr operand; + boolean polarity; + + TypeTestGuard() { TaintTracking::isStringTypeGuard(astNode, operand, polarity) } + + override predicate sanitizes(boolean outcome, Expr e) { + polarity = outcome and + e = operand + } + } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll index 767bd66f61c..38246762c49 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll @@ -4,7 +4,6 @@ */ import javascript -private import semmle.javascript.dataflow.InferredTypes private import XssThroughDomCustomizations::XssThroughDom private import semmle.javascript.security.dataflow.DomBasedXssCustomizations private import semmle.javascript.security.dataflow.UnsafeJQueryPluginCustomizations::UnsafeJQueryPlugin as UnsafeJQuery @@ -52,27 +51,13 @@ class Configuration extends TaintTracking::Configuration { } } -/** - * 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. - */ +/** A test for the value of `typeof x`, restricting the potential types of `x`. */ 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() - ) - } + TypeTestGuard() { TaintTracking::isStringTypeGuard(astNode, operand, polarity) } override predicate sanitizes(boolean outcome, Expr e) { polarity = outcome and diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index d9daf9a44e1..baf7f9b85e0 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/javascript-all` package. + +## 0.2.0 + +### Minor Analysis Improvements + +* The `js/resource-exhaustion` query no longer treats the 3-argument version of `Buffer.from` as a sink, + since it does not allocate a new buffer. + ## 0.1.4 ## 0.1.3 diff --git a/javascript/ql/src/Declarations/DeadStoreOfProperty.ql b/javascript/ql/src/Declarations/DeadStoreOfProperty.ql index 48b574f8cd1..c8cb0d8536e 100644 --- a/javascript/ql/src/Declarations/DeadStoreOfProperty.ql +++ b/javascript/ql/src/Declarations/DeadStoreOfProperty.ql @@ -154,7 +154,7 @@ predicate maybeAssignsAccessedPropInBlock(DataFlow::PropWrite assign, boolean af */ private module PurityCheck { /** - * Holds if a ControlFlowNode `c` is before an impure expression inside `bb`. + * Holds if `write` is before an impure expression inside `bb`. */ predicate isBeforeImpure(DataFlow::PropWrite write, ReachableBasicBlock bb) { getANodeAfterWrite(write, bb).(Expr).isImpure() @@ -181,7 +181,7 @@ private module PurityCheck { } /** - * Holds if a ControlFlowNode `c` is after an impure expression inside `bb`. + * Holds if `write` is after an impure expression inside `bb`. */ predicate isAfterImpure(DataFlow::PropWrite write, ReachableBasicBlock bb) { getANodeBeforeWrite(write, bb).(Expr).isImpure() diff --git a/javascript/ql/src/Declarations/DeclBeforeUse.ql b/javascript/ql/src/Declarations/DeclBeforeUse.ql index 49a7a3f01c8..b58fab9e465 100644 --- a/javascript/ql/src/Declarations/DeclBeforeUse.ql +++ b/javascript/ql/src/Declarations/DeclBeforeUse.ql @@ -10,7 +10,7 @@ */ import javascript -private import Declarations +private import Declarations.Declarations from VarAccess acc, VarDecl decl, Variable var, StmtContainer sc where diff --git a/javascript/ql/src/Declarations/RedeclaredVariable.ql b/javascript/ql/src/Declarations/RedeclaredVariable.ql index cdce959e66d..7f07378cef7 100644 --- a/javascript/ql/src/Declarations/RedeclaredVariable.ql +++ b/javascript/ql/src/Declarations/RedeclaredVariable.ql @@ -10,7 +10,7 @@ */ import javascript -private import Declarations +private import Declarations.Declarations from Variable v, TopLevel tl, VarDecl decl, VarDecl redecl where diff --git a/javascript/ql/src/Declarations/UnusedVariable.ql b/javascript/ql/src/Declarations/UnusedVariable.ql index 254c8c206b1..f678c7d5b19 100644 --- a/javascript/ql/src/Declarations/UnusedVariable.ql +++ b/javascript/ql/src/Declarations/UnusedVariable.ql @@ -144,6 +144,9 @@ predicate whitelisted(UnusedLocal v) { // exclude variables mentioned in JSDoc comments in externs mentionedInJSDocComment(v) or + // the attributes in .vue files are not extracted, so we can get false positives in those. + v.getADeclaration().getFile().getExtension() = "vue" + or // exclude variables used to filter out unwanted properties isPropertyFilter(v) or diff --git a/javascript/ql/src/Expressions/TypoDatabase.qll b/javascript/ql/src/Expressions/TypoDatabase.qll index aad43d9d0cc..fadc1b8af75 100644 --- a/javascript/ql/src/Expressions/TypoDatabase.qll +++ b/javascript/ql/src/Expressions/TypoDatabase.qll @@ -5793,6 +5793,8 @@ predicate typos(string wrong, string right) { or wrong = "paramters" and right = "parameters" or + wrong = "parametarized" and right = "parameterized" + or wrong = "paranthesis" and right = "parenthesis" or wrong = "paraphenalia" and right = "paraphernalia" diff --git a/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql b/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql index daa34825939..f22b9779560 100644 --- a/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql +++ b/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql @@ -84,10 +84,10 @@ predicate hasObjectProvidingTemplateVariables(CandidateStringLiteral lit) { * Gets a declaration of variable `v` in `tl`, where `v` has the given `name` and * belongs to `scope`. */ -VarDecl getDeclIn(Variable v, Scope s, string name, CandidateTopLevel tl) { +VarDecl getDeclIn(Variable v, Scope scope, string name, CandidateTopLevel tl) { v.getName() = name and v.getADeclaration() = result and - v.getScope() = s and + v.getScope() = scope and result.getTopLevel() = tl } diff --git a/javascript/ql/src/Metrics/ES20xxFeatures.qll b/javascript/ql/src/Metrics/ES20xxFeatures.qll index 8069ba5e50f..4aaed2d0fda 100644 --- a/javascript/ql/src/Metrics/ES20xxFeatures.qll +++ b/javascript/ql/src/Metrics/ES20xxFeatures.qll @@ -6,7 +6,7 @@ import javascript /** - * Holds if `nd` is a use of a feature introduced in ECMAScript version `ver` + * Holds if `nd` is a use of a feature introduced in ECMAScript `version` * from the given category. * * Categories are taken from Kangax' [ECMAScript 6 compatibility table] diff --git a/javascript/ql/src/NodeJS/InvalidExport.ql b/javascript/ql/src/NodeJS/InvalidExport.ql index 9daa363e888..e0b4a73fd69 100644 --- a/javascript/ql/src/NodeJS/InvalidExport.ql +++ b/javascript/ql/src/NodeJS/InvalidExport.ql @@ -16,14 +16,14 @@ import javascript /** * Holds if `assign` assigns the value of `nd` to `exportsVar`, which is an `exports` variable */ -predicate exportsAssign(Assignment assgn, Variable exportsVar, DataFlow::Node nd) { +predicate exportsAssign(Assignment assign, Variable exportsVar, DataFlow::Node nd) { exists(NodeModule m | exportsVar = m.getScope().getVariable("exports") and - assgn.getLhs() = exportsVar.getAnAccess() and - nd = assgn.getRhs().flow() + assign.getLhs() = exportsVar.getAnAccess() and + nd = assign.getRhs().flow() ) or - exportsAssign(assgn, exportsVar, nd.getASuccessor()) + exportsAssign(assign, exportsVar, nd.getASuccessor()) } /** diff --git a/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql b/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql index e352617337f..06e0a8146ef 100644 --- a/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql +++ b/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql @@ -39,10 +39,10 @@ RegExpTerm getEffectiveRoot(RegExpTerm actualRoot) { /** * Holds if `term` contains an anchor on both ends. */ -predicate isPossiblyAnchoredOnBothEnds(RegExpSequence node) { - node.getAChild*() instanceof RegExpCaret and - node.getAChild*() instanceof RegExpDollar and - node.getNumChild() >= 2 +predicate isPossiblyAnchoredOnBothEnds(RegExpSequence term) { + term.getAChild*() instanceof RegExpCaret and + term.getAChild*() instanceof RegExpDollar and + term.getNumChild() >= 2 } /** diff --git a/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll b/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll index 2192951f76d..5e9bc406512 100644 --- a/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll +++ b/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll @@ -53,7 +53,7 @@ predicate matchesBeginningOfString(RegExpTerm term) { } /** - * Holds if the given sequence contains top-level domain preceded by a dot, such as `.com`, + * Holds if the given sequence `seq` contains top-level domain preceded by a dot, such as `.com`, * excluding cases where this is at the very beginning of the regexp. * * `i` is bound to the index of the last child in the top-level domain part. diff --git a/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql b/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql index 90ae904097b..109e63b45b1 100644 --- a/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql +++ b/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql @@ -109,8 +109,8 @@ DataFlow::Node schemeCheck(DataFlow::Node nd, DangerousScheme scheme) { } /** Gets a data-flow node that checks an instance of `ap` against the given `scheme`. */ -DataFlow::Node schemeCheckOn(DataFlow::SourceNode root, string path, DangerousScheme scheme) { - result = schemeCheck(AccessPath::getAReferenceTo(root, path), scheme) +DataFlow::Node schemeCheckOn(DataFlow::SourceNode root, string ap, DangerousScheme scheme) { + result = schemeCheck(AccessPath::getAReferenceTo(root, ap), scheme) } from DataFlow::SourceNode root, string path, int n diff --git a/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql b/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql index 03a7a75828b..650b71dd62f 100644 --- a/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql +++ b/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql @@ -84,7 +84,7 @@ class LiteralLengthExpr extends DotExpr { } /** - * Holds if `length` is derived from the length of the given `indexOf`-operand. + * Holds if `length` is derived from the length of the given indexOf `operand`. */ predicate isDerivedFromLength(DataFlow::Node length, DataFlow::Node operand) { exists(IndexOfCall call | operand = call.getAnOperand() | diff --git a/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql b/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql index 886c78b0161..694e827ba41 100644 --- a/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql +++ b/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql @@ -50,7 +50,7 @@ private DataFlow::Node endsInCodeInjectionSink(DataFlow::TypeBackTracker t) { not result instanceof StringOps::ConcatenationRoot // the heuristic CodeInjection sink looks for string-concats, we are not interrested in those here. ) or - exists(DataFlow::TypeBackTracker t2 | t = t2.smallstep(result, endsInCodeInjectionSink(t2))) + exists(DataFlow::TypeBackTracker t2 | t2 = t.smallstep(result, endsInCodeInjectionSink(t2))) } /** diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp new file mode 100644 index 00000000000..96bf1c18c94 --- /dev/null +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp @@ -0,0 +1,44 @@ + + + + +

    +Using a case-sensitive regular expression path in a middleware route enables an attacker to bypass that middleware +when accessing an endpoint with a case-insensitive path. +Paths specified using a string are case-insensitive, whereas regular expressions are case-sensitive by default. +

    +
    + + +

    +When using a regular expression as a middleware path, make sure the regular expression is +case-insensitive by adding the i flag. +

    +
    + + +

    +The following example restricts access to paths in the /admin path to users logged in as +administrators: +

    + +

    +A path such as /admin/users/45 can only be accessed by an administrator. However, the path +/ADMIN/USERS/45 can be accessed by anyone because the upper-case path doesn't match the case-sensitive regular expression, whereas +Express considers it to match the path string /admin/users. +

    +

    +The issue can be fixed by adding the i flag to the regular expression: +

    + +
    + + +
  • +MDN +Regular Expression Flags. +
  • +
    +
    diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql new file mode 100644 index 00000000000..ccf659bf024 --- /dev/null +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -0,0 +1,121 @@ +/** + * @name Case-sensitive middleware path + * @description Middleware with case-sensitive paths do not protect endpoints with case-insensitive paths. + * @kind problem + * @problem.severity warning + * @security-severity 7.3 + * @precision high + * @id js/case-sensitive-middleware-path + * @tags security + * external/cwe/cwe-178 + */ + +import javascript + +/** + * Converts `s` to upper case, or to lower-case if it was already upper case. + */ +bindingset[s] +string toOtherCase(string s) { + if s.regexpMatch(".*[a-z].*") then result = s.toUpperCase() else result = s.toLowerCase() +} + +RegExpCharacterClass getEnclosingClass(RegExpTerm term) { + term = result.getAChild() + or + term = result.getAChild().(RegExpRange).getAChild() +} + +/** + * Holds if `term` seems to distinguish between upper and lower case letters, assuming the `i` flag is not present. + */ +pragma[inline] +predicate isLikelyCaseSensitiveRegExp(RegExpTerm term) { + exists(RegExpConstant const | + const = term.getAChild*() and + const.getValue().regexpMatch(".*[a-zA-Z].*") and + not getEnclosingClass(const).getAChild().(RegExpConstant).getValue() = + toOtherCase(const.getValue()) and + not const.getParent*() instanceof RegExpNegativeLookahead and + not const.getParent*() instanceof RegExpNegativeLookbehind + ) +} + +/** + * Gets a string matched by `term`, or part of such a string. + */ +string getExampleString(RegExpTerm term) { + result = term.getAMatchedString() + or + // getAMatchedString does not recurse into sequences. Perform one step manually. + exists(RegExpSequence seq | seq = term | + result = + strictconcat(RegExpTerm child, int i, string text | + child = seq.getChild(i) and + ( + text = child.getAMatchedString() + or + not exists(child.getAMatchedString()) and + text = "" + ) + | + text order by i + ) + ) +} + +string getCaseSensitiveBypassExample(RegExpTerm term) { + exists(string example | + example = getExampleString(term) and + result = toOtherCase(example) and + result != example // getting an example string is approximate; ensure we got a proper case-change example + ) +} + +/** + * Holds if `setup` has a path-argument `arg` referring to the given case-sensitive `regexp`. + */ +predicate isCaseSensitiveMiddleware( + Routing::RouteSetup setup, DataFlow::RegExpCreationNode regexp, DataFlow::Node arg +) { + exists(DataFlow::MethodCallNode call | + setup = Routing::getRouteSetupNode(call) and + ( + setup.definitelyResumesDispatch() + or + // If applied to all HTTP methods, be a bit more lenient in detecting middleware + setup.mayResumeDispatch() and + not exists(setup.getOwnHttpMethod()) + ) and + arg = call.getArgument(0) and + regexp.getAReference().flowsTo(arg) and + isLikelyCaseSensitiveRegExp(regexp.getRoot()) and + exists(string flags | + flags = regexp.getFlags() and + not RegExp::isIgnoreCase(flags) + ) + ) +} + +predicate isGuardedCaseInsensitiveEndpoint( + Routing::RouteSetup endpoint, Routing::RouteSetup middleware +) { + isCaseSensitiveMiddleware(middleware, _, _) and + exists(DataFlow::MethodCallNode call | + endpoint = Routing::getRouteSetupNode(call) and + endpoint.isGuardedByNode(middleware) and + call.getArgument(0).mayHaveStringValue(_) + ) +} + +from + DataFlow::RegExpCreationNode regexp, Routing::RouteSetup middleware, Routing::RouteSetup endpoint, + DataFlow::Node arg, string example +where + isCaseSensitiveMiddleware(middleware, regexp, arg) and + example = getCaseSensitiveBypassExample(regexp.getRoot()) and + isGuardedCaseInsensitiveEndpoint(endpoint, middleware) and + exists(endpoint.getRelativePath().toLowerCase().indexOf(example.toLowerCase())) +select arg, + "This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '" + + example + "' will bypass the middleware.", regexp, "pattern", endpoint, "here" diff --git a/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePath.js b/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePath.js new file mode 100644 index 00000000000..3ae6e071bdd --- /dev/null +++ b/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePath.js @@ -0,0 +1,13 @@ +const app = require('express')(); + +app.use(/\/admin\/.*/, (req, res, next) => { + if (!req.user.isAdmin) { + res.status(401).send('Unauthorized'); + } else { + next(); + } +}); + +app.get('/admin/users/:id', (req, res) => { + res.send(app.database.users[req.params.id]); +}); diff --git a/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePathGood.js b/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePathGood.js new file mode 100644 index 00000000000..1c803bf795d --- /dev/null +++ b/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePathGood.js @@ -0,0 +1,13 @@ +const app = require('express')(); + +app.use(/\/admin\/.*/i, (req, res, next) => { + if (!req.user.isAdmin) { + res.status(401).send('Unauthorized'); + } else { + next(); + } +}); + +app.get('/admin/users/:id', (req, res) => { + res.send(app.database.users[req.params.id]); +}); diff --git a/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql b/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql index 99ca8cba8a7..add8679dee7 100644 --- a/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql +++ b/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql @@ -72,11 +72,11 @@ pragma[noinline] Folder getAPackageJsonFolder() { result = any(PackageJson json).getFile().getParentContainer() } /** - * Gets a reference to `dirname`, the home folder, the current working folder, or the root folder. + * Gets a reference to a directory that has a `package.json` in the same folder, the home folder, + * the current working folder, or the root folder. * All of these might cause information to be leaked. * - * For `dirname` that can happen if there is a `package.json` file in the same folder. - * It is assumed that the presence of a `package.json` file means that a `node_modules` folder can also exist. + * For the first case it is assumed that the presence of a `package.json` file means that a `node_modules` folder can also exist. * * For the root/home/working folder, they contain so much information that they must leak information somehow (e.g. ssh keys in the `~/.ssh` folder). */ @@ -108,7 +108,7 @@ DataFlow::Node getALeakingFolder(string description) { } /** - * Gets a data-flow node that represents a path to the private folder `path`. + * Gets a data-flow node that represents the private folder descriped by `description`. */ DataFlow::Node getAPrivateFolderPath(string description) { exists(string path | @@ -119,7 +119,7 @@ DataFlow::Node getAPrivateFolderPath(string description) { } /** - * Gest a call that serves the folder `path` to the public. + * Gest a call that serves the folder descriped by `description` to the public. */ DataFlow::CallNode servesAPrivateFolder(string description) { result = DataFlow::moduleMember(["express", "connect"], "static").getACall() and diff --git a/javascript/ql/src/Security/CWE-384/SessionFixation.ql b/javascript/ql/src/Security/CWE-384/SessionFixation.ql index 85d6e69a02f..aca8fbe9e6b 100644 --- a/javascript/ql/src/Security/CWE-384/SessionFixation.ql +++ b/javascript/ql/src/Security/CWE-384/SessionFixation.ql @@ -34,7 +34,7 @@ predicate isLoginSetup(Express::RouteSetup setup) { } /** - * Holds if `handler` regenerates its session using `req.session.regenerate`. + * Holds if `setup` regenerates its session using `req.session.regenerate`. */ pragma[inline] predicate regeneratesSession(Express::RouteSetup setup) { diff --git a/javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md b/javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md new file mode 100644 index 00000000000..09895db1e2c --- /dev/null +++ b/javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md @@ -0,0 +1,6 @@ +--- +category: newQuery +--- + +- A new query "Case-sensitive middleware path" (`js/case-sensitive-middleware-path`) has been added. + It highlights middleware routes that can be bypassed due to having a case-sensitive regular expression path. diff --git a/javascript/ql/src/change-notes/2022-05-24-resource-exhaustion-no-buffer.from.md b/javascript/ql/src/change-notes/released/0.2.0.md similarity index 77% rename from javascript/ql/src/change-notes/2022-05-24-resource-exhaustion-no-buffer.from.md rename to javascript/ql/src/change-notes/released/0.2.0.md index 8dadbdb4c93..3663154efb6 100644 --- a/javascript/ql/src/change-notes/2022-05-24-resource-exhaustion-no-buffer.from.md +++ b/javascript/ql/src/change-notes/released/0.2.0.md @@ -1,5 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.2.0 + +### Minor Analysis Improvements + * The `js/resource-exhaustion` query no longer treats the 3-argument version of `Buffer.from` as a sink, since it does not allocate a new buffer. diff --git a/javascript/ql/src/change-notes/released/0.3.0.md b/javascript/ql/src/change-notes/released/0.3.0.md new file mode 100644 index 00000000000..13b4541cd4b --- /dev/null +++ b/javascript/ql/src/change-notes/released/0.3.0.md @@ -0,0 +1,5 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/javascript-all` package. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index e8ee3af8ef9..95f6e3a0ba6 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.3.0 diff --git a/javascript/ql/src/external/DefectFilter.qll b/javascript/ql/src/external/DefectFilter.qll index 40c9527e96d..558d5ef77b6 100644 --- a/javascript/ql/src/external/DefectFilter.qll +++ b/javascript/ql/src/external/DefectFilter.qll @@ -5,8 +5,8 @@ import semmle.javascript.Files /** * Holds if `id` in the opaque identifier of a result reported by query `queryPath`, * such that `message` is the associated message and the location of the result spans - * column `startcolumn` of line `startline` to column `endcolumn` of line `endline` - * in file `filepath`. + * column `startcol` of line `startline` to column `endcol` of line `endline` + * in `file`. * * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ diff --git a/javascript/ql/src/external/MetricFilter.qll b/javascript/ql/src/external/MetricFilter.qll index a857a4fad3e..f195060b60c 100644 --- a/javascript/ql/src/external/MetricFilter.qll +++ b/javascript/ql/src/external/MetricFilter.qll @@ -5,8 +5,8 @@ import javascript /** * Holds if `id` in the opaque identifier of a result reported by query `queryPath`, * such that `value` is the reported metric value and the location of the result spans - * column `startcolumn` of line `startline` to column `endcolumn` of line `endline` - * in file `filepath`. + * column `startcol` of line `startline` to column `endcol` of line `endline` + * in `file`. * * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 0b8615cb8e8..5525fe8b54b 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.2.0-dev +version: 0.3.1-dev groups: - javascript - queries diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index e8ca5f0f5ff..887b95b2b96 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -3235,6 +3235,92 @@ nodes | tainted-access-paths.js:40:23:40:26 | path | | tainted-access-paths.js:40:23:40:26 | path | | tainted-access-paths.js:40:23:40:26 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:24:48:30 | req.url | +| tainted-access-paths.js:48:24:48:30 | req.url | +| tainted-access-paths.js:48:24:48:30 | req.url | +| tainted-access-paths.js:48:24:48:30 | req.url | +| tainted-access-paths.js:48:24:48:30 | req.url | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-require.js:7:19:7:37 | req.param("module") | @@ -8759,6 +8845,118 @@ edges | tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | | tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | | tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-require.js:12:29:12:47 | req.param("module") | tainted-require.js:12:29:12:47 | req.param("module") | | tainted-require.js:14:11:14:29 | req.param("module") | tainted-require.js:14:11:14:29 | req.param("module") | @@ -10000,6 +10198,7 @@ edges | tainted-access-paths.js:30:23:30:30 | obj.sub4 | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:30:23:30:30 | obj.sub4 | This path depends on $@. | tainted-access-paths.js:6:24:6:30 | req.url | a user-provided value | | tainted-access-paths.js:31:23:31:30 | obj.sub4 | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:31:23:31:30 | obj.sub4 | This path depends on $@. | tainted-access-paths.js:6:24:6:30 | req.url | a user-provided value | | tainted-access-paths.js:40:23:40:26 | path | tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:40:23:40:26 | path | This path depends on $@. | tainted-access-paths.js:39:24:39:30 | req.url | a user-provided value | +| tainted-access-paths.js:49:10:49:13 | path | tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:49:10:49:13 | path | This path depends on $@. | tainted-access-paths.js:48:24:48:30 | req.url | a user-provided value | | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | This path depends on $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value | | tainted-require.js:12:29:12:47 | req.param("module") | tainted-require.js:12:29:12:47 | req.param("module") | tainted-require.js:12:29:12:47 | req.param("module") | This path depends on $@. | tainted-require.js:12:29:12:47 | req.param("module") | a user-provided value | | tainted-require.js:14:11:14:29 | req.param("module") | tainted-require.js:14:11:14:29 | req.param("module") | tainted-require.js:14:11:14:29 | req.param("module") | This path depends on $@. | tainted-require.js:14:11:14:29 | req.param("module") | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-access-paths.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-access-paths.js index e439628d065..465b5b70b69 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-access-paths.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-access-paths.js @@ -40,4 +40,11 @@ var server2 = http.createServer(function(req, res) { nodefs.readFileSync(path); // NOT OK }); -server2.listen(); \ No newline at end of file +server2.listen(); + +const chownr = require("chownr"); + +var server3 = http.createServer(function (req, res) { + let path = url.parse(req.url, true).query.path; + chownr(path, "someuid", "somegid", function (err) {}); // NOT OK +}); diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index e81dbd4d99a..3af55bfd598 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -1026,6 +1026,10 @@ nodes | tst.js:476:20:476:22 | url | | tst.js:486:22:486:24 | url | | tst.js:486:22:486:24 | url | +| tst.js:491:23:491:35 | location.hash | +| tst.js:491:23:491:35 | location.hash | +| tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:45 | locatio ... bstr(1) | | typeahead.js:20:13:20:45 | target | | typeahead.js:20:22:20:45 | documen ... .search | | typeahead.js:20:22:20:45 | documen ... .search | @@ -2081,6 +2085,10 @@ edges | tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:46 | documen ... bstr(1) | tst.js:471:7:471:46 | url | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | | typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | @@ -2354,6 +2362,7 @@ edges | tst.js:475:25:475:27 | url | tst.js:471:13:471:36 | documen ... .search | tst.js:475:25:475:27 | url | Cross-site scripting vulnerability due to $@. | tst.js:471:13:471:36 | documen ... .search | user-provided value | | tst.js:476:20:476:22 | url | tst.js:471:13:471:36 | documen ... .search | tst.js:476:20:476:22 | url | Cross-site scripting vulnerability due to $@. | tst.js:471:13:471:36 | documen ... .search | user-provided value | | tst.js:486:22:486:24 | url | tst.js:471:13:471:36 | documen ... .search | tst.js:486:22:486:24 | url | Cross-site scripting vulnerability due to $@. | tst.js:471:13:471:36 | documen ... .search | user-provided value | +| tst.js:491:23:491:45 | locatio ... bstr(1) | tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | Cross-site scripting vulnerability due to $@. | tst.js:491:23:491:35 | location.hash | user-provided value | | typeahead.js:25:18:25:20 | val | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:25:18:25:20 | val | Cross-site scripting vulnerability due to $@. | typeahead.js:20:22:20:45 | documen ... .search | user-provided value | | v-html.vue:2:8:2:23 | v-html=tainted | v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | Cross-site scripting vulnerability due to $@. | v-html.vue:6:42:6:58 | document.location | user-provided value | | various-concat-obfuscations.js:4:4:4:31 | "
    " ...
    " | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:4:4:4:31 | "
    " ...
    " | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index e72df859347..f8f72db0b4a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -1038,6 +1038,10 @@ nodes | tst.js:476:20:476:22 | url | | tst.js:486:22:486:24 | url | | tst.js:486:22:486:24 | url | +| tst.js:491:23:491:35 | location.hash | +| tst.js:491:23:491:35 | location.hash | +| tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:45 | locatio ... bstr(1) | | typeahead.js:9:28:9:30 | loc | | typeahead.js:9:28:9:30 | loc | | typeahead.js:9:28:9:30 | loc | @@ -2143,6 +2147,10 @@ edges | tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:46 | documen ... bstr(1) | tst.js:471:7:471:46 | url | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js index bc2b9a6a358..3c609ddcc92 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js @@ -487,4 +487,6 @@ function urlStuff() { } window.open(location.hash.substr(1)); // OK - any JavaScript is executed in another context -} \ No newline at end of file + + navigation.navigate(location.hash.substr(1)); // NOT OK +} diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected index 713db4aa08b..94f1fe314b0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected @@ -46,6 +46,16 @@ nodes | main.js:66:35:66:41 | attrVal | | main.js:67:63:67:69 | attrVal | | main.js:67:63:67:69 | attrVal | +| main.js:79:34:79:36 | val | +| main.js:79:34:79:36 | val | +| main.js:81:35:81:37 | val | +| main.js:81:35:81:37 | val | +| main.js:89:21:89:21 | x | +| main.js:90:23:90:23 | x | +| main.js:90:23:90:23 | x | +| main.js:93:43:93:43 | x | +| main.js:93:43:93:43 | x | +| main.js:94:31:94:31 | x | | typed.ts:1:39:1:39 | s | | typed.ts:1:39:1:39 | s | | typed.ts:2:29:2:29 | s | @@ -107,6 +117,15 @@ edges | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | +| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | +| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | +| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | +| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | +| main.js:89:21:89:21 | x | main.js:90:23:90:23 | x | +| main.js:89:21:89:21 | x | main.js:90:23:90:23 | x | +| main.js:93:43:93:43 | x | main.js:94:31:94:31 | x | +| main.js:93:43:93:43 | x | main.js:94:31:94:31 | x | +| main.js:94:31:94:31 | x | main.js:89:21:89:21 | x | | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | @@ -132,5 +151,7 @@ edges | main.js:47:65:47:73 | this.step | main.js:52:41:52:41 | s | main.js:47:65:47:73 | this.step | $@ based on $@ might later cause $@. | main.js:47:65:47:73 | this.step | HTML construction | main.js:52:41:52:41 | s | library input | main.js:47:54:47:85 | " ... /span>" | cross-site scripting | | main.js:62:19:62:31 | settings.name | main.js:56:28:56:34 | options | main.js:62:19:62:31 | settings.name | $@ based on $@ might later cause $@. | main.js:62:19:62:31 | settings.name | HTML construction | main.js:56:28:56:34 | options | library input | main.js:62:11:62:40 | "" + ... "" | cross-site scripting | | main.js:67:63:67:69 | attrVal | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | $@ based on $@ might later cause $@. | main.js:67:63:67:69 | attrVal | HTML construction | main.js:66:35:66:41 | attrVal | library input | main.js:67:47:67:78 | "" | cross-site scripting | +| main.js:81:35:81:37 | val | main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | $@ based on $@ might later cause $@. | main.js:81:35:81:37 | val | HTML construction | main.js:79:34:79:36 | val | library input | main.js:81:24:81:49 | " ... /span>" | cross-site scripting | +| main.js:90:23:90:23 | x | main.js:93:43:93:43 | x | main.js:90:23:90:23 | x | $@ based on $@ might later cause $@. | main.js:90:23:90:23 | x | HTML construction | main.js:93:43:93:43 | x | library input | main.js:94:20:94:32 | createHTML(x) | cross-site scripting | | typed.ts:2:29:2:29 | s | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | $@ based on $@ might later cause $@. | typed.ts:2:29:2:29 | s | HTML construction | typed.ts:1:39:1:39 | s | library input | typed.ts:3:31:3:34 | html | cross-site scripting | | typed.ts:8:40:8:40 | s | typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | $@ based on $@ might later cause $@. | typed.ts:8:40:8:40 | s | HTML construction | typed.ts:6:43:6:43 | s | library input | typed.ts:8:29:8:52 | " ... /span>" | cross-site scripting | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js index 1097e126feb..2e9d344b1f3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js @@ -75,3 +75,21 @@ module.exports.intentionalTemplate = function (obj) { const html = "" + obj.spanTemplate + ""; // OK document.querySelector("#template").innerHTML = html; } + +module.exports.types = function (val) { + if (typeof val === "string") { + $("#foo").html("" + val + ""); // NOT OK + } else if (typeof val === "number") { + $("#foo").html("" + val + ""); // OK + } else if (typeof val === "boolean") { + $("#foo").html("" + val + ""); // OK + } +} + +function createHTML(x) { + return "" + x + ""; // NOT OK +} + +module.exports.usesCreateHTML = function (x) { + $("#foo").html(createHTML(x)); +} \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected index dfc86af8cf1..49511750e6f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected @@ -11,6 +11,10 @@ nodes | lib/index.js:13:38:13:41 | data | | lib/index.js:14:21:14:24 | data | | lib/index.js:14:21:14:24 | data | +| lib/index.js:19:26:19:29 | data | +| lib/index.js:19:26:19:29 | data | +| lib/index.js:22:7:22:10 | data | +| lib/index.js:22:7:22:10 | data | edges | lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | | lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | @@ -24,7 +28,12 @@ edges | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | +| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | +| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | +| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | +| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | #select | lib/index.js:2:21:2:24 | data | lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | $@ flows to here and is later $@. | lib/index.js:1:35:1:38 | data | Library input | lib/index.js:2:15:2:30 | "(" + data + ")" | interpreted as code | | lib/index.js:6:26:6:29 | name | lib/index.js:5:35:5:38 | name | lib/index.js:6:26:6:29 | name | $@ flows to here and is later $@. | lib/index.js:5:35:5:38 | name | Library input | lib/index.js:6:17:6:29 | "obj." + name | interpreted as code | | lib/index.js:14:21:14:24 | data | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | $@ flows to here and is later $@. | lib/index.js:13:38:13:41 | data | Library input | lib/index.js:14:15:14:30 | "(" + data + ")" | interpreted as code | +| lib/index.js:22:7:22:10 | data | lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | $@ flows to here and is later $@. | lib/index.js:19:26:19:29 | data | Library input | lib/index.js:25:24:25:26 | str | interpreted as code | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js index b5df26c11d5..4289ebfc686 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js @@ -12,4 +12,24 @@ export function safeAssignment(obj, value) { global.unsafeDeserialize = function (data) { return eval("(" + data + ")"); // NOT OK -} \ No newline at end of file +} + +const matter = require("gray-matter"); + +export function greySink(data) { + const str = ` + ---js + ${data} + --- + ` + const res = matter(str); + console.log(res); + + matter(str, { // OK + engines: { + js: function (data) { + console.log("NOPE"); + } + } + }); +} diff --git a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected new file mode 100644 index 00000000000..a79b3100a80 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected @@ -0,0 +1,3 @@ +| tst.js:8:9:8:19 | /\\/foo\\/.*/ | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO/' will bypass the middleware. | tst.js:8:9:8:19 | /\\/foo\\/.*/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | +| tst.js:14:5:14:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO' will bypass the middleware. | tst.js:14:5:14:28 | new Reg ... (.*)?') | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | +| tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO/' will bypass the middleware. | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.qlref b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.qlref new file mode 100644 index 00000000000..75705303770 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.qlref @@ -0,0 +1 @@ +Security/CWE-178/CaseSensitiveMiddlewarePath.ql diff --git a/javascript/ql/test/query-tests/Security/CWE-178/charclass.js b/javascript/ql/test/query-tests/Security/CWE-178/charclass.js new file mode 100644 index 00000000000..f10e0a2d7ab --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-178/charclass.js @@ -0,0 +1,9 @@ +const express = require('express'); +const app = express(); + +app.get(/\/[a-zA-Z]+/, (req, res, next) => { // OK - regexp term is case insensitive + next(); +}); + +app.get('/foo', (req, res) => { +}); diff --git a/javascript/ql/test/query-tests/Security/CWE-178/tst.js b/javascript/ql/test/query-tests/Security/CWE-178/tst.js new file mode 100644 index 00000000000..1acb57b16ea --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-178/tst.js @@ -0,0 +1,61 @@ +const express = require('express'); +const app = express(); +const unknown = require('~something/blah'); + +app.all(/\/.*/, unknown()); // OK - does not contain letters +app.all(/\/.*/i, unknown()); // OK + +app.all(/\/foo\/.*/, unknown()); // NOT OK +app.all(/\/foo\/.*/i, unknown()); // OK - case insensitive + +app.use(/\/x\/#\d{6}/, express.static('images/')); // OK - not a middleware + +app.get( + new RegExp('^/foo(.*)?'), // NOT OK - case sensitive + unknown(), + function(req, res, next) { + if (req.params.blah) { + next(); + } + } +); + +app.get( + new RegExp('^/foo(.*)?', 'i'), // OK - case insensitive + unknown(), + function(req, res, next) { + if (req.params.blah) { + next(); + } + } +); + +app.get( + new RegExp('^/foo(.*)?'), // OK - not a middleware + unknown(), + function(req,res) { + res.send('Hello World!'); + } +); + +app.use(/\/foo\/([0-9]+)/, (req, res, next) => { // NOT OK - case sensitive + unknown(req); + next(); +}); + +app.use(/\/foo\/([0-9]+)/i, (req, res, next) => { // OK - case insensitive + unknown(req); + next(); +}); + + +app.use(/\/foo\/([0-9]+)/, (req, res) => { // OK - not middleware + unknown(req, res); +}); + +app.use(/\/foo\/([0-9]+)/i, (req, res) => { // OK - not middleware (also case insensitive) + unknown(req, res); +}); + +app.get('/foo/:param', (req, res) => { // OK - not a middleware +}); diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 01b052d3a72..83a09c70446 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,24 @@ +## 0.5.1 + +### Deprecated APIs + +- The documentation of API graphs (the `API` module) has been expanded, and some of the members predicates of `API::Node` + have been renamed as follows: + - `getAnImmediateUse` -> `asSource` + - `getARhs` -> `asSink` + - `getAUse` -> `getAValueReachableFromSource` + - `getAValueReachingRhs` -> `getAValueReachingSink` + +### Minor Analysis Improvements + +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). + +## 0.5.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + ## 0.4.1 ## 0.4.0 diff --git a/python/ql/src/analysis/DefinitionTracking.qll b/python/ql/lib/analysis/DefinitionTracking.qll similarity index 98% rename from python/ql/src/analysis/DefinitionTracking.qll rename to python/ql/lib/analysis/DefinitionTracking.qll index 90166b84991..dafbffad64e 100644 --- a/python/ql/src/analysis/DefinitionTracking.qll +++ b/python/ql/lib/analysis/DefinitionTracking.qll @@ -14,10 +14,13 @@ class Definition extends TLocalDefinition { /** Gets a textual representation of this element. */ string toString() { result = "Definition " + this.getAstNode().getLocation().toString() } + /** Gets the AST Node associated with this element */ AstNode getAstNode() { this = TLocalDefinition(result) } + /** Gets the Module associated with this element */ Module getModule() { result = this.getAstNode().getScope().getEnclosingModule() } + /** Gets the source location of the AST Node associated with this element */ Location getLocation() { result = this.getAstNode().getLocation() } } diff --git a/python/ql/src/analysis/IDEContextual.qll b/python/ql/lib/analysis/IDEContextual.qll similarity index 100% rename from python/ql/src/analysis/IDEContextual.qll rename to python/ql/lib/analysis/IDEContextual.qll diff --git a/python/ql/src/analysis/LocalDefinitions.ql b/python/ql/lib/analysis/LocalDefinitions.ql similarity index 94% rename from python/ql/src/analysis/LocalDefinitions.ql rename to python/ql/lib/analysis/LocalDefinitions.ql index fae19995f57..d86e3e9254b 100644 --- a/python/ql/src/analysis/LocalDefinitions.ql +++ b/python/ql/lib/analysis/LocalDefinitions.ql @@ -8,7 +8,7 @@ */ import python -import DefinitionTracking +import analysis.DefinitionTracking external string selectedSourceFile(); diff --git a/python/ql/src/analysis/LocalReferences.ql b/python/ql/lib/analysis/LocalReferences.ql similarity index 93% rename from python/ql/src/analysis/LocalReferences.ql rename to python/ql/lib/analysis/LocalReferences.ql index cf254e9fc3d..6eea0846e85 100644 --- a/python/ql/src/analysis/LocalReferences.ql +++ b/python/ql/lib/analysis/LocalReferences.ql @@ -8,7 +8,7 @@ */ import python -import DefinitionTracking +import analysis.DefinitionTracking external string selectedSourceFile(); diff --git a/python/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/python/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md deleted file mode 100644 index 2bd95798f89..00000000000 --- a/python/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -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/python/ql/lib/change-notes/2022-06-22-sensitive-common-words.md b/python/ql/lib/change-notes/2022-06-22-sensitive-common-words.md deleted file mode 100644 index 9102d58abdb..00000000000 --- a/python/ql/lib/change-notes/2022-06-22-sensitive-common-words.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). diff --git a/java/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/python/ql/lib/change-notes/released/0.5.0.md similarity index 83% rename from java/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md rename to python/ql/lib/change-notes/released/0.5.0.md index 2bd95798f89..db19d4ebfec 100644 --- a/java/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ b/python/ql/lib/change-notes/released/0.5.0.md @@ -1,4 +1,5 @@ ---- -category: deprecated ---- +## 0.5.0 + +### Deprecated APIs + * The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/python/ql/lib/change-notes/released/0.5.1.md b/python/ql/lib/change-notes/released/0.5.1.md new file mode 100644 index 00000000000..1b560c7a35a --- /dev/null +++ b/python/ql/lib/change-notes/released/0.5.1.md @@ -0,0 +1,14 @@ +## 0.5.1 + +### Deprecated APIs + +- The documentation of API graphs (the `API` module) has been expanded, and some of the members predicates of `API::Node` + have been renamed as follows: + - `getAnImmediateUse` -> `asSource` + - `getARhs` -> `asSink` + - `getAUse` -> `getAValueReachableFromSource` + - `getAValueReachingRhs` -> `getAValueReachingSink` + +### Minor Analysis Improvements + +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 89fa3a87180..0bf7024c337 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.1 +lastReleaseVersion: 0.5.1 diff --git a/python/ql/src/printAst.ql b/python/ql/lib/printAst.ql similarity index 100% rename from python/ql/src/printAst.ql rename to python/ql/lib/printAst.ql diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 10320703ecd..f1a7c716b1e 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.5.0-dev +version: 0.5.2-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index fcb89e5f866..cf4e4fb3cd5 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -12,76 +12,165 @@ import semmle.python.dataflow.new.DataFlow private import semmle.python.internal.CachedStages /** - * Provides classes and predicates for working with APIs used in a database. + * Provides classes and predicates for working with the API boundary between the current + * codebase and external libraries. + * + * See `API::Node` for more in-depth documentation. */ module API { /** - * An abstract representation of a definition or use of an API component such as a function - * exported by a Python package, or its result. + * A node in the API graph, representing a value that has crossed the boundary between this + * codebase and an external library (or in general, any external codebase). + * + * ### Basic usage + * + * API graphs are typically used to identify "API calls", that is, calls to an external function + * whose implementation is not necessarily part of the current codebase. + * + * The most basic use of API graphs is typically as follows: + * 1. Start with `API::moduleImport` for the relevant library. + * 2. Follow up with a chain of accessors such as `getMember` describing how to get to the relevant API function. + * 3. Map the resulting API graph nodes to data-flow nodes, using `asSource` or `asSink`. + * + * For example, a simplified way to get the first argument of a call to `json.dumps` would be + * ```ql + * API::moduleImport("json").getMember("dumps").getParameter(0).asSink() + * ``` + * + * The most commonly used accessors are `getMember`, `getParameter`, and `getReturn`. + * + * ### API graph nodes + * + * There are two kinds of nodes in the API graphs, distinguished by who is "holding" the value: + * - **Use-nodes** represent values held by the current codebase, which came from an external library. + * (The current codebase is "using" a value that came from the library). + * - **Def-nodes** represent values held by the external library, which came from this codebase. + * (The current codebase "defines" the value seen by the library). + * + * API graph nodes are associated with data-flow nodes in the current codebase. + * (API graphs are designed to work when external libraries are not part of the database, + * so we do not associate with concrete data-flow nodes from the external library). + * - **Use-nodes** are associated with data-flow nodes where a value enters the current codebase, + * such as the return value of a call to an external function. + * - **Def-nodes** are associated with data-flow nodes where a value leaves the current codebase, + * such as an argument passed in a call to an external function. + * + * + * ### Access paths and edge labels + * + * Nodes in the API graph are associated with a set of access paths, describing a series of operations + * that may be performed to obtain that value. + * + * For example, the access path `API::moduleImport("json").getMember("dumps")` represents the action of + * importing `json` and then accessing the member `dumps` on the resulting object. + * + * Each edge in the graph is labelled by such an "operation". For an edge `A->B`, the type of the `A` node + * determines who is performing the operation, and the type of the `B` node determines who ends up holding + * the result: + * - An edge starting from a use-node describes what the current codebase is doing to a value that + * came from a library. + * - An edge starting from a def-node describes what the external library might do to a value that + * came from the current codebase. + * - An edge ending in a use-node means the result ends up in the current codebase (at its associated data-flow node). + * - An edge ending in a def-node means the result ends up in external code (its associated data-flow node is + * the place where it was "last seen" in the current codebase before flowing out) + * + * Because the implementation of the external library is not visible, it is not known exactly what operations + * it will perform on values that flow there. Instead, the edges starting from a def-node are operations that would + * lead to an observable effect within the current codebase; without knowing for certain if the library will actually perform + * those operations. (When constructing these edges, we assume the library is somewhat well-behaved). + * + * For example, given this snippet: + * ```python + * import foo + * foo.bar(lambda x: doSomething(x)) + * ``` + * A callback is passed to the external function `foo.bar`. We can't know if `foo.bar` will actually invoke this callback. + * But _if_ the library should decide to invoke the callback, then a value will flow into the current codebase via the `x` parameter. + * For that reason, an edge is generated representing the argument-passing operation that might be performed by `foo.bar`. + * This edge is going from the def-node associated with the callback to the use-node associated with the parameter `x`. */ class Node extends Impl::TApiNode { /** - * Gets a data-flow node corresponding to a use of the API component represented by this node. + * Gets a data-flow node where this value may flow after entering the current codebase. * - * For example, `import re; re.escape` is a use of the `escape` function from the - * `re` module, and `import re; re.escape("hello")` is a use of the return of that function. - * - * This includes indirect uses found via data flow, meaning that in - * ```python - * def f(x): - * pass - * - * f(obj.foo) - * ``` - * both `obj.foo` and `x` are uses of the `foo` member from `obj`. + * This is similar to `asSource()` but additionally includes nodes that are transitively reachable by data flow. + * See `asSource()` for examples. */ - DataFlow::Node getAUse() { + DataFlow::Node getAValueReachableFromSource() { exists(DataFlow::LocalSourceNode src | Impl::use(this, src) | Impl::trackUseNode(src).flowsTo(result) ) } /** - * Gets a data-flow node corresponding to the right-hand side of a definition of the API - * component represented by this node. + * Gets a data-flow node where this value leaves the current codebase and flows into an + * external library (or in general, any external codebase). * - * For example, in the property write `foo.bar = x`, variable `x` is the the right-hand side - * of a write to the `bar` property of `foo`. + * Concretely, this is either an argument passed to a call to external code, + * or the right-hand side of an attribute write on an object flowing into such a call. * - * Note that for parameters, it is the arguments flowing into that parameter that count as - * right-hand sides of the definition, not the declaration of the parameter itself. - * Consequently, in : + * For example: * ```python - * from mypkg import foo; + * import foo + * + * # 'x' is matched by API::moduleImport("foo").getMember("bar").getParameter(0).asSink() * foo.bar(x) + * + * # 'x' is matched by API::moduleImport("foo").getMember("bar").getParameter(0).getMember("prop").asSink() + * obj.prop = x + * foo.bar(obj); * ``` - * `x` is the right-hand side of a definition of the first parameter of `bar` from the `mypkg.foo` module. + * + * This predicate does not include nodes transitively reaching the sink by data flow; + * use `getAValueReachingSink` for that. */ - DataFlow::Node getARhs() { Impl::rhs(this, result) } + DataFlow::Node asSink() { Impl::rhs(this, result) } /** - * Gets a data-flow node that may interprocedurally flow to the right-hand side of a definition - * of the API component represented by this node. + * Gets a data-flow node that transitively flows to an external library (or in general, any external codebase). + * + * This is similar to `asSink()` but additionally includes nodes that transitively reach a sink by data flow. + * See `asSink()` for examples. */ - DataFlow::Node getAValueReachingRhs() { result = Impl::trackDefNode(this.getARhs()) } + DataFlow::Node getAValueReachingSink() { result = Impl::trackDefNode(this.asSink()) } /** - * Gets an immediate use of the API component represented by this node. + * Gets a data-flow node where this value enters the current codebase. * - * For example, `import re; re.escape` is a an immediate use of the `escape` member - * from the `re` module. + * For example: + * ```python + * # API::moduleImport("re").asSource() + * import re * - * Unlike `getAUse()`, this predicate only gets the immediate references, not the indirect uses - * found via data flow. This means that in `x = re.escape` only `re.escape` is a reference - * to the `escape` member of `re`, neither `x` nor any node that `x` flows to is a reference to - * this API component. + * # API::moduleImport("re").getMember("escape").asSource() + * re.escape + * + * # API::moduleImport("re").getMember("escape").getReturn().asSource() + * re.escape() + * ``` + * + * This predicate does not include nodes transitively reachable by data flow; + * use `getAValueReachableFromSource` for that. */ - DataFlow::LocalSourceNode getAnImmediateUse() { Impl::use(this, result) } + DataFlow::LocalSourceNode asSource() { Impl::use(this, result) } + + /** DEPRECATED. This predicate has been renamed to `getAValueReachableFromSource()`. */ + deprecated DataFlow::Node getAUse() { result = this.getAValueReachableFromSource() } + + /** DEPRECATED. This predicate has been renamed to `asSource()`. */ + deprecated DataFlow::LocalSourceNode getAnImmediateUse() { result = this.asSource() } + + /** DEPRECATED. This predicate has been renamed to `asSink()`. */ + deprecated DataFlow::Node getARhs() { result = this.asSink() } + + /** DEPRECATED. This predicate has been renamed to `getAValueReachingSink()`. */ + deprecated DataFlow::Node getAValueReachingRhs() { result = this.getAValueReachingSink() } /** * Gets a call to the function represented by this API component. */ - CallNode getACall() { result = this.getReturn().getAnImmediateUse() } + CallNode getACall() { result = this.getReturn().asSource() } /** * Gets a node representing member `m` of this API component. @@ -306,7 +395,7 @@ module API { class CallNode extends DataFlow::CallCfgNode { API::Node callee; - CallNode() { this = callee.getReturn().getAnImmediateUse() } + CallNode() { this = callee.getReturn().asSource() } /** Gets the API node for the `i`th parameter of this invocation. */ pragma[nomagic] @@ -319,14 +408,14 @@ module API { * Gets an API node where a RHS of the node is the `i`th argument to this call. */ pragma[noinline] - private Node getAParameterCandidate(int i) { result.getARhs() = this.getArg(i) } + private Node getAParameterCandidate(int i) { result.asSink() = this.getArg(i) } /** Gets the API node for a parameter of this invocation. */ Node getAParameter() { result = this.getParameter(_) } /** Gets the object that this method-call is being called on, if this is a method-call */ Node getSelfParameter() { - result.getARhs() = this.(DataFlow::MethodCallNode).getObject() and + result.asSink() = this.(DataFlow::MethodCallNode).getObject() and result = callee.getSelfParameter() } @@ -346,13 +435,13 @@ module API { pragma[noinline] private Node getAKeywordParameterCandidate(string name) { - result.getARhs() = this.getArgByName(name) + result.asSink() = this.getArgByName(name) } /** Gets the API node for the return value of this call. */ Node getReturn() { result = callee.getReturn() and - result.getAnImmediateUse() = this + result.asSource() = this } /** diff --git a/python/ql/lib/semmle/python/RegexTreeView.qll b/python/ql/lib/semmle/python/RegexTreeView.qll index 8e2ae1e90f3..80a5e6a4be4 100644 --- a/python/ql/lib/semmle/python/RegexTreeView.qll +++ b/python/ql/lib/semmle/python/RegexTreeView.qll @@ -1000,11 +1000,22 @@ class RegExpBackRef extends RegExpTerm, TRegExpBackRef { /** Gets the capture group this back reference refers to. */ RegExpGroup getGroup() { - result.getLiteral() = this.getLiteral() and - ( - result.getNumber() = this.getNumber() or - result.getName() = this.getName() - ) + this.hasLiteralAndNumber(result.getLiteral(), result.getNumber()) or + this.hasLiteralAndName(result.getLiteral(), result.getName()) + } + + /** Join-order helper for `getGroup`. */ + pragma[nomagic] + private predicate hasLiteralAndNumber(RegExpLiteral literal, int number) { + literal = this.getLiteral() and + number = this.getNumber() + } + + /** Join-order helper for `getGroup`. */ + pragma[nomagic] + private predicate hasLiteralAndName(RegExpLiteral literal, string name) { + literal = this.getLiteral() and + name = this.getName() } override RegExpTerm getChild(int i) { none() } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 7b9e78d2c4b..a076f7a2e45 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index 7b9e78d2c4b..a076f7a2e45 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index 7b9e78d2c4b..a076f7a2e45 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index 7b9e78d2c4b..a076f7a2e45 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index 406f1fb6b12..8ab76dc56df 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -527,16 +527,55 @@ class StarPatternElementNode extends Node, TStarPatternElementNode { override Location getLocation() { result = consumer.getLocation() } } +/** + * Gets a node that controls whether other nodes are evaluated. + * + * In the base case, this is the last node of `conditionBlock`, and `flipped` is `false`. + * This definition accounts for (short circuting) `and`- and `or`-expressions, as the structure + * of basic blocks will reflect their semantics. + * + * However, in the program + * ```python + * if not is_safe(path): + * return + * ``` + * the last node in the `ConditionBlock` is `not is_safe(path)`. + * + * We would like to consider also `is_safe(path)` a guard node, albeit with `flipped` being `true`. + * Thus we recurse through `not`-expressions. + */ +ControlFlowNode guardNode(ConditionBlock conditionBlock, boolean flipped) { + // Base case: the last node truly does determine which successor is chosen + result = conditionBlock.getLastNode() and + flipped = false + or + // Recursive case: if a guard node is a `not`-expression, + // the operand is also a guard node, but with inverted polarity. + exists(UnaryExprNode notNode | + result = notNode.getOperand() and + notNode.getNode().getOp() instanceof Not + | + notNode = guardNode(conditionBlock, flipped.booleanNot()) + ) +} + /** * A node that controls whether other nodes are evaluated. + * + * The field `flipped` allows us to match `GuardNode`s underneath + * `not`-expressions and still choose the appropriate branch. */ class GuardNode extends ControlFlowNode { ConditionBlock conditionBlock; + boolean flipped; - GuardNode() { this = conditionBlock.getLastNode() } + GuardNode() { this = guardNode(conditionBlock, flipped) } /** Holds if this guard controls block `b` upon evaluating to `branch`. */ - predicate controlsBlock(BasicBlock b, boolean branch) { conditionBlock.controls(b, branch) } + predicate controlsBlock(BasicBlock b, boolean branch) { + branch in [true, false] and + conditionBlock.controls(b, branch.booleanXor(flipped)) + } } /** diff --git a/python/ql/lib/semmle/python/filters/Tests.qll b/python/ql/lib/semmle/python/filters/Tests.qll index 44ea2edebe4..20f6713a837 100644 --- a/python/ql/lib/semmle/python/filters/Tests.qll +++ b/python/ql/lib/semmle/python/filters/Tests.qll @@ -9,7 +9,7 @@ class UnitTestClass extends TestScope, Class { testCaseString.matches("%TestCase") and testCaseClass = any(API::Node mod).getMember(testCaseString) | - this.getParent() = testCaseClass.getASubclass*().getAnImmediateUse().asExpr() + this.getParent() = testCaseClass.getASubclass*().asSource().asExpr() ) } } diff --git a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll index 359c8c14159..5f687a01b49 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll @@ -243,9 +243,7 @@ module AiohttpWebModel { /** A class that has a super-type which is an aiohttp.web View class. */ class AiohttpViewClassFromSuperClass extends AiohttpViewClass { - AiohttpViewClassFromSuperClass() { - this.getParent() = View::subclassRef().getAnImmediateUse().asExpr() - } + AiohttpViewClassFromSuperClass() { this.getParent() = View::subclassRef().asSource().asExpr() } } /** A class that is used in a route-setup, therefore being considered an aiohttp.web View class. */ @@ -628,7 +626,8 @@ module AiohttpWebModel { // and just go with the LHS this.asCfgNode() = subscript | - subscript.getObject() = aiohttpResponseInstance().getMember("cookies").getAUse().asCfgNode() and + subscript.getObject() = + aiohttpResponseInstance().getMember("cookies").getAValueReachableFromSource().asCfgNode() and value.asCfgNode() = subscript.(DefinitionNode).getValue() and index.asCfgNode() = subscript.getIndex() ) @@ -686,8 +685,8 @@ private module AiohttpClientModel { DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { exists(API::Node param | param = this.getKeywordParameter(["ssl", "verify_ssl"]) | - disablingNode = param.getARhs() and - argumentOrigin = param.getAValueReachingRhs() and + disablingNode = param.asSink() and + argumentOrigin = param.getAValueReachingSink() and // aiohttp.client treats `None` as the default and all other "falsey" values as `False`. argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false and not argumentOrigin.asExpr() instanceof None diff --git a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll index fdcf21afc34..3d43c13b91a 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll @@ -53,7 +53,7 @@ private module Aiomysql { class CursorExecuteCall extends SqlConstruction::Range, API::CallNode { CursorExecuteCall() { this = cursor().getMember("execute").getACall() } - override DataFlow::Node getSql() { result = this.getParameter(0, "operation").getARhs() } + override DataFlow::Node getSql() { result = this.getParameter(0, "operation").asSink() } } /** @@ -63,7 +63,7 @@ private module Aiomysql { class AwaitedCursorExecuteCall extends SqlExecution::Range { CursorExecuteCall executeCall; - AwaitedCursorExecuteCall() { this = executeCall.getReturn().getAwaited().getAnImmediateUse() } + AwaitedCursorExecuteCall() { this = executeCall.getReturn().getAwaited().asSource() } override DataFlow::Node getSql() { result = executeCall.getSql() } } @@ -94,7 +94,7 @@ private module Aiomysql { class SAConnectionExecuteCall extends SqlConstruction::Range, API::CallNode { SAConnectionExecuteCall() { this = saConnection().getMember("execute").getACall() } - override DataFlow::Node getSql() { result = this.getParameter(0, "query").getARhs() } + override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() } } /** @@ -104,7 +104,7 @@ private module Aiomysql { class AwaitedSAConnectionExecuteCall extends SqlExecution::Range { SAConnectionExecuteCall execute; - AwaitedSAConnectionExecuteCall() { this = execute.getReturn().getAwaited().getAnImmediateUse() } + AwaitedSAConnectionExecuteCall() { this = execute.getReturn().getAwaited().asSource() } override DataFlow::Node getSql() { result = execute.getSql() } } diff --git a/python/ql/lib/semmle/python/frameworks/Aiopg.qll b/python/ql/lib/semmle/python/frameworks/Aiopg.qll index afc553fe04b..053d59df51a 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiopg.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiopg.qll @@ -53,7 +53,7 @@ private module Aiopg { class CursorExecuteCall extends SqlConstruction::Range, API::CallNode { CursorExecuteCall() { this = cursor().getMember("execute").getACall() } - override DataFlow::Node getSql() { result = this.getParameter(0, "operation").getARhs() } + override DataFlow::Node getSql() { result = this.getParameter(0, "operation").asSink() } } /** @@ -63,7 +63,7 @@ private module Aiopg { class AwaitedCursorExecuteCall extends SqlExecution::Range { CursorExecuteCall execute; - AwaitedCursorExecuteCall() { this = execute.getReturn().getAwaited().getAnImmediateUse() } + AwaitedCursorExecuteCall() { this = execute.getReturn().getAwaited().asSource() } override DataFlow::Node getSql() { result = execute.getSql() } } @@ -90,7 +90,7 @@ private module Aiopg { class SAConnectionExecuteCall extends SqlConstruction::Range, API::CallNode { SAConnectionExecuteCall() { this = saConnection().getMember("execute").getACall() } - override DataFlow::Node getSql() { result = this.getParameter(0, "query").getARhs() } + override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() } } /** @@ -100,7 +100,7 @@ private module Aiopg { class AwaitedSAConnectionExecuteCall extends SqlExecution::Range { SAConnectionExecuteCall excute; - AwaitedSAConnectionExecuteCall() { this = excute.getReturn().getAwaited().getAnImmediateUse() } + AwaitedSAConnectionExecuteCall() { this = excute.getReturn().getAwaited().asSource() } override DataFlow::Node getSql() { result = excute.getSql() } } diff --git a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll index 81da12a015c..ca28dca550f 100644 --- a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll +++ b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll @@ -61,7 +61,7 @@ private module Asyncpg { this = ModelOutput::getATypeNode("asyncpg", "Connection").getMember("cursor").getACall() } - override DataFlow::Node getSql() { result = this.getParameter(0, "query").getARhs() } + override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() } } /** The creation of a `Cursor` executes the associated query. */ @@ -71,14 +71,14 @@ private module Asyncpg { CursorCreation() { exists(CursorConstruction c | sql = c.getSql() and - this = c.getReturn().getAwaited().getAnImmediateUse() + this = c.getReturn().getAwaited().asSource() ) or exists(API::CallNode prepareCall | prepareCall = ModelOutput::getATypeNode("asyncpg", "Connection").getMember("prepare").getACall() | - sql = prepareCall.getParameter(0, "query").getARhs() and + sql = prepareCall.getParameter(0, "query").asSink() and this = prepareCall .getReturn() @@ -86,7 +86,7 @@ private module Asyncpg { .getMember("cursor") .getReturn() .getAwaited() - .getAnImmediateUse() + .asSource() ) } diff --git a/python/ql/lib/semmle/python/frameworks/Cryptodome.qll b/python/ql/lib/semmle/python/frameworks/Cryptodome.qll index 8d1e47d0ff3..0c3e8968c23 100644 --- a/python/ql/lib/semmle/python/frameworks/Cryptodome.qll +++ b/python/ql/lib/semmle/python/frameworks/Cryptodome.qll @@ -164,7 +164,7 @@ private module CryptodomeModel { .getMember("Cipher") .getMember(cipherName) .getMember(modeName) - .getAUse() + .getAValueReachableFromSource() | result = modeName.splitAt("_", 1) ) diff --git a/python/ql/lib/semmle/python/frameworks/Cryptography.qll b/python/ql/lib/semmle/python/frameworks/Cryptography.qll index 954def9e7da..021da3ef0a0 100644 --- a/python/ql/lib/semmle/python/frameworks/Cryptography.qll +++ b/python/ql/lib/semmle/python/frameworks/Cryptography.qll @@ -144,12 +144,10 @@ private module CryptographyModel { DataFlow::Node getCurveArg() { result in [this.getArg(0), this.getArgByName("curve")] } override int getKeySizeWithOrigin(DataFlow::Node origin) { - exists(API::Node n | - n = Ecc::predefinedCurveClass(result) and origin = n.getAnImmediateUse() - | - this.getCurveArg() = n.getAUse() + exists(API::Node n | n = Ecc::predefinedCurveClass(result) and origin = n.asSource() | + this.getCurveArg() = n.getAValueReachableFromSource() or - this.getCurveArg() = n.getReturn().getAUse() + this.getCurveArg() = n.getReturn().getAValueReachableFromSource() ) } @@ -191,12 +189,12 @@ private module CryptographyModel { .getMember("ciphers") .getMember("Cipher") .getACall() and - algorithmClassRef(algorithmName).getReturn().getAUse() in [ + algorithmClassRef(algorithmName).getReturn().getAValueReachableFromSource() in [ call.getArg(0), call.getArgByName("algorithm") ] and exists(DataFlow::Node modeArg | modeArg in [call.getArg(1), call.getArgByName("mode")] | - if modeArg = modeClassRef(_).getReturn().getAUse() - then modeArg = modeClassRef(modeName).getReturn().getAUse() + if modeArg = modeClassRef(_).getReturn().getAValueReachableFromSource() + then modeArg = modeClassRef(modeName).getReturn().getAValueReachableFromSource() else modeName = "" ) ) @@ -254,7 +252,7 @@ private module CryptographyModel { .getMember("hashes") .getMember("Hash") .getACall() and - algorithmClassRef(algorithmName).getReturn().getAUse() in [ + algorithmClassRef(algorithmName).getReturn().getAValueReachableFromSource() in [ call.getArg(0), call.getArgByName("algorithm") ] ) diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll index a22957d1fe0..a430513cb62 100644 --- a/python/ql/lib/semmle/python/frameworks/Django.qll +++ b/python/ql/lib/semmle/python/frameworks/Django.qll @@ -562,7 +562,7 @@ module PrivateDjango { /** A `django.db.connection` is a PEP249 compliant DB connection. */ class DjangoDbConnection extends PEP249::Connection::InstanceSource { - DjangoDbConnection() { this = connection().getAnImmediateUse() } + DjangoDbConnection() { this = connection().asSource() } } // ------------------------------------------------------------------------- @@ -869,7 +869,7 @@ module PrivateDjango { /** Gets the (AST) class of the Django model class `modelClass`. */ Class getModelClassClass(API::Node modelClass) { - result.getParent() = modelClass.getAnImmediateUse().asExpr() and + result.getParent() = modelClass.asSource().asExpr() and modelClass = Model::subclassRef() } @@ -2202,9 +2202,7 @@ module PrivateDjango { * thereby handling user input. */ class DjangoFormClass extends Class, SelfRefMixin { - DjangoFormClass() { - this.getParent() = Django::Forms::Form::subclassRef().getAnImmediateUse().asExpr() - } + DjangoFormClass() { this.getParent() = Django::Forms::Form::subclassRef().asSource().asExpr() } } /** @@ -2237,7 +2235,7 @@ module PrivateDjango { */ class DjangoFormFieldClass extends Class { DjangoFormFieldClass() { - this.getParent() = Django::Forms::Field::subclassRef().getAnImmediateUse().asExpr() + this.getParent() = Django::Forms::Field::subclassRef().asSource().asExpr() } } @@ -2340,7 +2338,7 @@ module PrivateDjango { */ class DjangoViewClassFromSuperClass extends DjangoViewClass { DjangoViewClassFromSuperClass() { - this.getParent() = Django::Views::View::subclassRef().getAnImmediateUse().asExpr() + this.getParent() = Django::Views::View::subclassRef().asSource().asExpr() } } @@ -2743,7 +2741,7 @@ module PrivateDjango { .getMember("utils") .getMember("log") .getMember("request_logger") - .getAnImmediateUse() + .asSource() } } @@ -2801,7 +2799,7 @@ module PrivateDjango { .getMember("decorators") .getMember("csrf") .getMember(decoratorName) - .getAUse() and + .getAValueReachableFromSource() and this.asExpr() = function.getADecorator() } diff --git a/python/ql/lib/semmle/python/frameworks/Fabric.qll b/python/ql/lib/semmle/python/frameworks/Fabric.qll index bb1500965f4..5fd9d2afe18 100644 --- a/python/ql/lib/semmle/python/frameworks/Fabric.qll +++ b/python/ql/lib/semmle/python/frameworks/Fabric.qll @@ -179,7 +179,7 @@ private module FabricV2 { DataFlow::ParameterNode { FabricTaskFirstParamConnectionInstance() { exists(Function func | - func.getADecorator() = Fabric::Tasks::task().getAUse().asExpr() and + func.getADecorator() = Fabric::Tasks::task().getAValueReachableFromSource().asExpr() and this.getParameter() = func.getArg(0) ) } diff --git a/python/ql/lib/semmle/python/frameworks/FastApi.qll b/python/ql/lib/semmle/python/frameworks/FastApi.qll index 1c48562eb70..f042dafea59 100644 --- a/python/ql/lib/semmle/python/frameworks/FastApi.qll +++ b/python/ql/lib/semmle/python/frameworks/FastApi.qll @@ -90,7 +90,8 @@ private module FastApi { private class PydanticModelRequestHandlerParam extends Pydantic::BaseModel::InstanceSource, DataFlow::ParameterNode { PydanticModelRequestHandlerParam() { - this.getParameter().getAnnotation() = Pydantic::BaseModel::subclassRef().getAUse().asExpr() and + this.getParameter().getAnnotation() = + Pydantic::BaseModel::subclassRef().getAValueReachableFromSource().asExpr() and any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter() } } @@ -104,7 +105,8 @@ private module FastApi { private class WebSocketRequestHandlerParam extends Starlette::WebSocket::InstanceSource, DataFlow::ParameterNode { WebSocketRequestHandlerParam() { - this.getParameter().getAnnotation() = Starlette::WebSocket::classRef().getAUse().asExpr() and + this.getParameter().getAnnotation() = + Starlette::WebSocket::classRef().getAValueReachableFromSource().asExpr() and any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter() } } @@ -165,8 +167,8 @@ private module FastApi { // user-defined subclasses exists(Class cls, API::Node base | base = getModeledResponseClass(_).getASubclass*() and - cls.getABase() = base.getAUse().asExpr() and - responseClass.getAnImmediateUse().asExpr() = cls.getParent() + cls.getABase() = base.getAValueReachableFromSource().asExpr() and + responseClass.asSource().asExpr() = cls.getParent() | exists(Assign assign | assign = cls.getAStmt() | assign.getATarget().(Name).getId() = "media_type" and @@ -257,7 +259,7 @@ private module FastApi { override string getMimetypeDefault() { exists(API::Node responseClass | - responseClass.getAUse() = routeSetup.getResponseClassArg() and + responseClass.getAValueReachableFromSource() = routeSetup.getResponseClassArg() and result = getDefaultMimeType(responseClass) ) or @@ -274,7 +276,7 @@ private module FastApi { FileSystemAccess::Range { FastApiRequestHandlerFileResponseReturn() { exists(API::Node responseClass | - responseClass.getAUse() = routeSetup.getResponseClassArg() and + responseClass.getAValueReachableFromSource() = routeSetup.getResponseClassArg() and responseClass = getModeledResponseClass("FileResponse").getASubclass*() ) } @@ -292,7 +294,7 @@ private module FastApi { HTTP::Server::HttpRedirectResponse::Range { FastApiRequestHandlerRedirectReturn() { exists(API::Node responseClass | - responseClass.getAUse() = routeSetup.getResponseClassArg() and + responseClass.getAValueReachableFromSource() = routeSetup.getResponseClassArg() and responseClass = getModeledResponseClass("RedirectResponse").getASubclass*() ) } @@ -311,7 +313,7 @@ private module FastApi { class RequestHandlerParam extends InstanceSource, DataFlow::ParameterNode { RequestHandlerParam() { this.getParameter().getAnnotation() = - getModeledResponseClass(_).getASubclass*().getAUse().asExpr() and + getModeledResponseClass(_).getASubclass*().getAValueReachableFromSource().asExpr() and any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter() } } diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll index 02331ed316e..8ee93fcec52 100644 --- a/python/ql/lib/semmle/python/frameworks/Flask.qll +++ b/python/ql/lib/semmle/python/frameworks/Flask.qll @@ -195,7 +195,7 @@ module Flask { FlaskViewClass() { api_node = Views::View::subclassRef() and - this.getParent() = api_node.getAnImmediateUse().asExpr() + this.getParent() = api_node.asSource().asExpr() } /** Gets a function that could handle incoming requests, if any. */ @@ -220,7 +220,7 @@ module Flask { class FlaskMethodViewClass extends FlaskViewClass { FlaskMethodViewClass() { api_node = Views::MethodView::subclassRef() and - this.getParent() = api_node.getAnImmediateUse().asExpr() + this.getParent() = api_node.asSource().asExpr() } override Function getARequestHandler() { @@ -305,7 +305,7 @@ module Flask { ) or exists(FlaskViewClass vc | - this.getViewArg() = vc.asViewResult().getAUse() and + this.getViewArg() = vc.asViewResult().getAValueReachableFromSource() and result = vc.getARequestHandler() ) } @@ -339,7 +339,7 @@ module Flask { */ private class FlaskRequestSource extends RemoteFlowSource::Range { FlaskRequestSource() { - this = request().getAUse() and + this = request().getAValueReachableFromSource() and not any(Import imp).contains(this.asExpr()) and not exists(ControlFlowNode def | this.asVar().getSourceVariable().hasDefiningNode(def) | any(Import imp).contains(def.getNode()) @@ -357,7 +357,7 @@ module Flask { private class InstanceTaintSteps extends InstanceTaintStepsHelper { InstanceTaintSteps() { this = "flask.Request" } - override DataFlow::Node getInstance() { result = request().getAUse() } + override DataFlow::Node getInstance() { result = request().getAValueReachableFromSource() } override string getAttributeName() { result in [ @@ -404,7 +404,7 @@ module Flask { private class RequestAttrMultiDict extends Werkzeug::MultiDict::InstanceSource { RequestAttrMultiDict() { - this = request().getMember(["args", "values", "form", "files"]).getAnImmediateUse() + this = request().getMember(["args", "values", "form", "files"]).asSource() } } @@ -415,26 +415,25 @@ module Flask { // be able to do something more structured for providing modeling of the members // of a container-object. exists(API::Node files | files = request().getMember("files") | - this.asCfgNode().(SubscriptNode).getObject() = files.getAUse().asCfgNode() + this.asCfgNode().(SubscriptNode).getObject() = + files.getAValueReachableFromSource().asCfgNode() or this = files.getMember("get").getACall() or this.asCfgNode().(SubscriptNode).getObject() = - files.getMember("getlist").getReturn().getAUse().asCfgNode() + files.getMember("getlist").getReturn().getAValueReachableFromSource().asCfgNode() ) } } /** An `Headers` instance that originates from a flask request. */ private class FlaskRequestHeadersInstances extends Werkzeug::Headers::InstanceSource { - FlaskRequestHeadersInstances() { this = request().getMember("headers").getAnImmediateUse() } + FlaskRequestHeadersInstances() { this = request().getMember("headers").asSource() } } /** An `Authorization` instance that originates from a flask request. */ private class FlaskRequestAuthorizationInstances extends Werkzeug::Authorization::InstanceSource { - FlaskRequestAuthorizationInstances() { - this = request().getMember("authorization").getAnImmediateUse() - } + FlaskRequestAuthorizationInstances() { this = request().getMember("authorization").asSource() } } // --------------------------------------------------------------------------- @@ -574,6 +573,6 @@ module Flask { * - https://flask.palletsprojects.com/en/2.0.x/logging/ */ private class FlaskLogger extends Stdlib::Logger::InstanceSource { - FlaskLogger() { this = FlaskApp::instance().getMember("logger").getAnImmediateUse() } + FlaskLogger() { this = FlaskApp::instance().getMember("logger").asSource() } } } diff --git a/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll b/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll index 6269baee9d5..535e32426b2 100644 --- a/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll +++ b/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll @@ -35,7 +35,7 @@ private module FlaskSqlAlchemy { /** Access on a DB resulting in an Engine */ private class DbEngine extends SqlAlchemy::Engine::InstanceSource { DbEngine() { - this = dbInstance().getMember("engine").getAnImmediateUse() + this = dbInstance().getMember("engine").asSource() or this = dbInstance().getMember("get_engine").getACall() } @@ -44,7 +44,7 @@ private module FlaskSqlAlchemy { /** Access on a DB resulting in a Session */ private class DbSession extends SqlAlchemy::Session::InstanceSource { DbSession() { - this = dbInstance().getMember("session").getAnImmediateUse() + this = dbInstance().getMember("session").asSource() or this = dbInstance().getMember("create_session").getReturn().getACall() or diff --git a/python/ql/lib/semmle/python/frameworks/Httpx.qll b/python/ql/lib/semmle/python/frameworks/Httpx.qll index 67dbbffbd9f..b746de6ee5e 100644 --- a/python/ql/lib/semmle/python/frameworks/Httpx.qll +++ b/python/ql/lib/semmle/python/frameworks/Httpx.qll @@ -44,8 +44,8 @@ private module HttpxModel { override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { - disablingNode = this.getKeywordParameter("verify").getARhs() and - argumentOrigin = this.getKeywordParameter("verify").getAValueReachingRhs() and + disablingNode = this.getKeywordParameter("verify").asSink() and + argumentOrigin = this.getKeywordParameter("verify").getAValueReachingSink() and // unlike `requests`, httpx treats `None` as turning off verify (and not as the default) argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false // TODO: Handling of insecure SSLContext passed to verify argument @@ -89,8 +89,8 @@ private module HttpxModel { constructor = classRef().getACall() and this = constructor.getReturn().getMember(methodName).getACall() | - disablingNode = constructor.getKeywordParameter("verify").getARhs() and - argumentOrigin = constructor.getKeywordParameter("verify").getAValueReachingRhs() and + disablingNode = constructor.getKeywordParameter("verify").asSink() and + argumentOrigin = constructor.getKeywordParameter("verify").getAValueReachingSink() and // unlike `requests`, httpx treats `None` as turning off verify (and not as the default) argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false // TODO: Handling of insecure SSLContext passed to verify argument diff --git a/python/ql/lib/semmle/python/frameworks/Invoke.qll b/python/ql/lib/semmle/python/frameworks/Invoke.qll index 435536dda9f..b1ceb078907 100644 --- a/python/ql/lib/semmle/python/frameworks/Invoke.qll +++ b/python/ql/lib/semmle/python/frameworks/Invoke.qll @@ -39,7 +39,8 @@ private module Invoke { result = InvokeModule::Context::ContextClass::classRef().getACall() or exists(Function func | - func.getADecorator() = invoke().getMember("task").getAUse().asExpr() and + func.getADecorator() = + invoke().getMember("task").getAValueReachableFromSource().asExpr() and result.(DataFlow::ParameterNode).getParameter() = func.getArg(0) ) ) diff --git a/python/ql/lib/semmle/python/frameworks/Lxml.qll b/python/ql/lib/semmle/python/frameworks/Lxml.qll index 70e46a6d3b0..63c71a67110 100644 --- a/python/ql/lib/semmle/python/frameworks/Lxml.qll +++ b/python/ql/lib/semmle/python/frameworks/Lxml.qll @@ -141,17 +141,18 @@ private module Lxml { // resolve_entities has default True not exists(this.getArgByName("resolve_entities")) or - this.getKeywordParameter("resolve_entities").getAValueReachingRhs().asExpr() = any(True t) + this.getKeywordParameter("resolve_entities").getAValueReachingSink().asExpr() = + any(True t) ) or kind.isXmlBomb() and - this.getKeywordParameter("huge_tree").getAValueReachingRhs().asExpr() = any(True t) and - not this.getKeywordParameter("resolve_entities").getAValueReachingRhs().asExpr() = + this.getKeywordParameter("huge_tree").getAValueReachingSink().asExpr() = any(True t) and + not this.getKeywordParameter("resolve_entities").getAValueReachingSink().asExpr() = any(False t) or kind.isDtdRetrieval() and - this.getKeywordParameter("load_dtd").getAValueReachingRhs().asExpr() = any(True t) and - this.getKeywordParameter("no_network").getAValueReachingRhs().asExpr() = any(False t) + this.getKeywordParameter("load_dtd").getAValueReachingSink().asExpr() = any(True t) and + this.getKeywordParameter("no_network").getAValueReachingSink().asExpr() = any(False t) } } @@ -318,11 +319,11 @@ private module Lxml { kind.isXxe() or kind.isXmlBomb() and - this.getKeywordParameter("huge_tree").getAValueReachingRhs().asExpr() = any(True t) + this.getKeywordParameter("huge_tree").getAValueReachingSink().asExpr() = any(True t) or kind.isDtdRetrieval() and - this.getKeywordParameter("load_dtd").getAValueReachingRhs().asExpr() = any(True t) and - this.getKeywordParameter("no_network").getAValueReachingRhs().asExpr() = any(False t) + this.getKeywordParameter("load_dtd").getAValueReachingSink().asExpr() = any(True t) and + this.getKeywordParameter("no_network").getAValueReachingSink().asExpr() = any(False t) } override predicate mayExecuteInput() { none() } diff --git a/python/ql/lib/semmle/python/frameworks/Requests.qll b/python/ql/lib/semmle/python/frameworks/Requests.qll index 6c9028d6135..0c944d889d2 100644 --- a/python/ql/lib/semmle/python/frameworks/Requests.qll +++ b/python/ql/lib/semmle/python/frameworks/Requests.qll @@ -61,8 +61,8 @@ private module Requests { override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { - disablingNode = this.getKeywordParameter("verify").getARhs() and - argumentOrigin = this.getKeywordParameter("verify").getAValueReachingRhs() and + disablingNode = this.getKeywordParameter("verify").asSink() and + argumentOrigin = this.getKeywordParameter("verify").getAValueReachingSink() and // requests treats `None` as the default and all other "falsey" values as `False`. argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false and not argumentOrigin.asExpr() instanceof None diff --git a/python/ql/lib/semmle/python/frameworks/RestFramework.qll b/python/ql/lib/semmle/python/frameworks/RestFramework.qll index 61f031576de..c8f73f909c2 100644 --- a/python/ql/lib/semmle/python/frameworks/RestFramework.qll +++ b/python/ql/lib/semmle/python/frameworks/RestFramework.qll @@ -115,7 +115,7 @@ private module RestFramework { */ class RestFrameworkApiViewClass extends PrivateDjango::DjangoViewClassFromSuperClass { RestFrameworkApiViewClass() { - this.getParent() = any(ModeledApiViewClasses c).getASubclass*().getAnImmediateUse().asExpr() + this.getParent() = any(ModeledApiViewClasses c).getASubclass*().asSource().asExpr() } override Function getARequestHandler() { diff --git a/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll b/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll index 2d553c409b0..d9ba39814eb 100644 --- a/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll +++ b/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll @@ -44,7 +44,7 @@ private module RuamelYaml { API::moduleImport("ruamel") .getMember("yaml") .getMember(["SafeLoader", "BaseLoader", "CSafeLoader", "CBaseLoader"]) - .getAUse() + .getAValueReachableFromSource() ) } diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index a273511979c..df9301a46c3 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -274,7 +274,7 @@ module Stdlib { ClassInstantiation() { this = subclassRef().getACall() or - this = API::moduleImport("logging").getMember("root").getAnImmediateUse() + this = API::moduleImport("logging").getMember("root").asSource() or this = API::moduleImport("logging").getMember("getLogger").getACall() } @@ -1727,15 +1727,16 @@ private module StdlibPrivate { private DataFlow::TypeTrackingNode fieldList(DataFlow::TypeTracker t) { t.start() and // TODO: Should have better handling of subscripting - result.asCfgNode().(SubscriptNode).getObject() = instance().getAUse().asCfgNode() + result.asCfgNode().(SubscriptNode).getObject() = + instance().getAValueReachableFromSource().asCfgNode() or exists(DataFlow::TypeTracker t2 | result = fieldList(t2).track(t2, t)) } /** Gets a reference to a list of fields. */ DataFlow::Node fieldList() { - result = getlistResult().getAUse() or - result = getvalueResult().getAUse() or + result = getlistResult().getAValueReachableFromSource() or + result = getvalueResult().getAValueReachableFromSource() or fieldList(DataFlow::TypeTracker::end()).flowsTo(result) } @@ -1744,16 +1745,16 @@ private module StdlibPrivate { t.start() and // TODO: Should have better handling of subscripting result.asCfgNode().(SubscriptNode).getObject() = - [instance().getAUse(), fieldList()].asCfgNode() + [instance().getAValueReachableFromSource(), fieldList()].asCfgNode() or exists(DataFlow::TypeTracker t2 | result = field(t2).track(t2, t)) } /** Gets a reference to a field. */ DataFlow::Node field() { - result = getfirstResult().getAUse() + result = getfirstResult().getAValueReachableFromSource() or - result = getvalueResult().getAUse() + result = getvalueResult().getAValueReachableFromSource() or field(DataFlow::TypeTracker::end()).flowsTo(result) } @@ -1762,20 +1763,23 @@ private module StdlibPrivate { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { // Methods nodeFrom = nodeTo.(DataFlow::AttrRead).getObject() and - nodeFrom = instance().getAUse() and - nodeTo = [getvalueRef(), getfirstRef(), getlistRef()].getAUse() + nodeFrom = instance().getAValueReachableFromSource() and + nodeTo = [getvalueRef(), getfirstRef(), getlistRef()].getAValueReachableFromSource() or nodeFrom.asCfgNode() = nodeTo.asCfgNode().(CallNode).getFunction() and ( - nodeFrom = getvalueRef().getAUse() and nodeTo = getvalueResult().getAnImmediateUse() + nodeFrom = getvalueRef().getAValueReachableFromSource() and + nodeTo = getvalueResult().asSource() or - nodeFrom = getfirstRef().getAUse() and nodeTo = getfirstResult().getAnImmediateUse() + nodeFrom = getfirstRef().getAValueReachableFromSource() and + nodeTo = getfirstResult().asSource() or - nodeFrom = getlistRef().getAUse() and nodeTo = getlistResult().getAnImmediateUse() + nodeFrom = getlistRef().getAValueReachableFromSource() and + nodeTo = getlistResult().asSource() ) or // Indexing - nodeFrom in [instance().getAUse(), fieldList()] and + nodeFrom in [instance().getAValueReachableFromSource(), fieldList()] and nodeTo.asCfgNode().(SubscriptNode).getObject() = nodeFrom.asCfgNode() or // Attributes on Field @@ -1939,7 +1943,7 @@ private module StdlibPrivate { /** A HttpRequestHandler class definition (most likely in project code). */ class HttpRequestHandlerClassDef extends Class { - HttpRequestHandlerClassDef() { this.getParent() = subclassRef().getAnImmediateUse().asExpr() } + HttpRequestHandlerClassDef() { this.getParent() = subclassRef().asSource().asExpr() } } /** DEPRECATED: Alias for HttpRequestHandlerClassDef */ @@ -2037,7 +2041,7 @@ private module StdlibPrivate { .getMember("simple_server") .getMember("WSGIServer") .getASubclass*() - .getAnImmediateUse() + .asSource() .asExpr() } } @@ -2553,7 +2557,7 @@ private module StdlibPrivate { override DataFlow::Node getAPathArgument() { result = super.getAPathArgument() or - result = this.getParameter(0, "target").getARhs() + result = this.getParameter(0, "target").asSink() } } @@ -2570,7 +2574,7 @@ private module StdlibPrivate { override DataFlow::Node getAPathArgument() { result = super.getAPathArgument() or - result = this.getParameter(0, "target").getARhs() + result = this.getParameter(0, "target").asSink() } } @@ -2585,7 +2589,7 @@ private module StdlibPrivate { override DataFlow::Node getAPathArgument() { result = super.getAPathArgument() or - result = this.getParameter(0, "other_path").getARhs() + result = this.getParameter(0, "other_path").asSink() } } @@ -2653,7 +2657,7 @@ private module StdlibPrivate { /** Gets a call to `hashlib.new` with `algorithmName` as the first argument. */ private API::CallNode hashlibNewCall(string algorithmName) { algorithmName = - result.getParameter(0, "name").getAValueReachingRhs().asExpr().(StrConst).getText() and + result.getParameter(0, "name").getAValueReachingSink().asExpr().(StrConst).getText() and result = API::moduleImport("hashlib").getMember("new").getACall() } @@ -2670,7 +2674,7 @@ private module StdlibPrivate { override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) } - override DataFlow::Node getAnInput() { result = this.getParameter(1, "data").getARhs() } + override DataFlow::Node getAnInput() { result = this.getParameter(1, "data").asSink() } override Cryptography::BlockMode getBlockMode() { none() } } @@ -3433,13 +3437,13 @@ private module StdlibPrivate { private DataFlow::Node saxParserWithFeatureExternalGesTurnedOn(DataFlow::TypeTracker t) { t.start() and exists(SaxParserSetFeatureCall call | - call.getFeatureArg().getARhs() = + call.getFeatureArg().asSink() = API::moduleImport("xml") .getMember("sax") .getMember("handler") .getMember("feature_external_ges") - .getAUse() and - call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = true and + .getAValueReachableFromSource() and + call.getStateArg().getAValueReachingSink().asExpr().(BooleanLiteral).booleanValue() = true and result = call.getObject() ) or @@ -3449,13 +3453,13 @@ private module StdlibPrivate { // take account of that we can set the feature to False, which makes the parser safe again not exists(SaxParserSetFeatureCall call | call.getObject() = result and - call.getFeatureArg().getARhs() = + call.getFeatureArg().asSink() = API::moduleImport("xml") .getMember("sax") .getMember("handler") .getMember("feature_external_ges") - .getAUse() and - call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = false + .getAValueReachableFromSource() and + call.getStateArg().getAValueReachingSink().asExpr().(BooleanLiteral).booleanValue() = false ) } diff --git a/python/ql/lib/semmle/python/frameworks/Tornado.qll b/python/ql/lib/semmle/python/frameworks/Tornado.qll index 9c604afc1ec..d66da17aa5d 100644 --- a/python/ql/lib/semmle/python/frameworks/Tornado.qll +++ b/python/ql/lib/semmle/python/frameworks/Tornado.qll @@ -92,7 +92,7 @@ private module Tornado { /** A RequestHandler class (most likely in project code). */ class RequestHandlerClass extends Class { - RequestHandlerClass() { this.getParent() = subclassRef().getAnImmediateUse().asExpr() } + RequestHandlerClass() { this.getParent() = subclassRef().asSource().asExpr() } /** Gets a function that could handle incoming requests, if any. */ Function getARequestHandler() { diff --git a/python/ql/lib/semmle/python/frameworks/Twisted.qll b/python/ql/lib/semmle/python/frameworks/Twisted.qll index 513f5c942d0..c316321555e 100644 --- a/python/ql/lib/semmle/python/frameworks/Twisted.qll +++ b/python/ql/lib/semmle/python/frameworks/Twisted.qll @@ -33,7 +33,7 @@ private module Twisted { .getMember("resource") .getMember("Resource") .getASubclass*() - .getAnImmediateUse() + .asSource() .asExpr() } diff --git a/python/ql/lib/semmle/python/frameworks/Urllib3.qll b/python/ql/lib/semmle/python/frameworks/Urllib3.qll index 568591d64f9..418a135fbfc 100644 --- a/python/ql/lib/semmle/python/frameworks/Urllib3.qll +++ b/python/ql/lib/semmle/python/frameworks/Urllib3.qll @@ -71,14 +71,15 @@ private module Urllib3 { | // cert_reqs // see https://urllib3.readthedocs.io/en/stable/user-guide.html?highlight=cert_reqs#certificate-verification - disablingNode = constructor.getKeywordParameter("cert_reqs").getARhs() and - argumentOrigin = constructor.getKeywordParameter("cert_reqs").getAValueReachingRhs() and + disablingNode = constructor.getKeywordParameter("cert_reqs").asSink() and + argumentOrigin = constructor.getKeywordParameter("cert_reqs").getAValueReachingSink() and argumentOrigin.asExpr().(StrConst).getText() = "CERT_NONE" or // assert_hostname // see https://urllib3.readthedocs.io/en/stable/reference/urllib3.connectionpool.html?highlight=assert_hostname#urllib3.HTTPSConnectionPool - disablingNode = constructor.getKeywordParameter("assert_hostname").getARhs() and - argumentOrigin = constructor.getKeywordParameter("assert_hostname").getAValueReachingRhs() and + disablingNode = constructor.getKeywordParameter("assert_hostname").asSink() and + argumentOrigin = + constructor.getKeywordParameter("assert_hostname").getAValueReachingSink() and argumentOrigin.asExpr().(BooleanLiteral).booleanValue() = false ) } diff --git a/python/ql/lib/semmle/python/frameworks/Werkzeug.qll b/python/ql/lib/semmle/python/frameworks/Werkzeug.qll index e9e3f257871..5e318f59e73 100644 --- a/python/ql/lib/semmle/python/frameworks/Werkzeug.qll +++ b/python/ql/lib/semmle/python/frameworks/Werkzeug.qll @@ -285,7 +285,7 @@ private module WerkzeugOld { * See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Headers.getlist */ deprecated DataFlow::Node getlist() { - result = any(InstanceSourceApiNode a).getMember("getlist").getAUse() + result = any(InstanceSourceApiNode a).getMember("getlist").getAValueReachableFromSource() } private class MultiDictAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { @@ -331,7 +331,9 @@ private module WerkzeugOld { abstract deprecated class InstanceSourceApiNode extends API::Node { } /** Gets a reference to an instance of `werkzeug.datastructures.FileStorage`. */ - deprecated DataFlow::Node instance() { result = any(InstanceSourceApiNode a).getAUse() } + deprecated DataFlow::Node instance() { + result = any(InstanceSourceApiNode a).getAValueReachableFromSource() + } private class FileStorageAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { diff --git a/python/ql/lib/semmle/python/frameworks/Xmltodict.qll b/python/ql/lib/semmle/python/frameworks/Xmltodict.qll index f63fec7afe4..495725e9a76 100644 --- a/python/ql/lib/semmle/python/frameworks/Xmltodict.qll +++ b/python/ql/lib/semmle/python/frameworks/Xmltodict.qll @@ -29,7 +29,7 @@ private module Xmltodict { override predicate vulnerableTo(XML::XmlParsingVulnerabilityKind kind) { kind.isXmlBomb() and - this.getKeywordParameter("disable_entities").getAValueReachingRhs().asExpr() = any(False f) + this.getKeywordParameter("disable_entities").getAValueReachingSink().asExpr() = any(False f) } override predicate mayExecuteInput() { none() } diff --git a/python/ql/lib/semmle/python/frameworks/Yaml.qll b/python/ql/lib/semmle/python/frameworks/Yaml.qll index 07a98ec2ba3..670fad75e6e 100644 --- a/python/ql/lib/semmle/python/frameworks/Yaml.qll +++ b/python/ql/lib/semmle/python/frameworks/Yaml.qll @@ -64,7 +64,7 @@ private module Yaml { loader_arg = API::moduleImport("yaml") .getMember(["SafeLoader", "BaseLoader", "CSafeLoader", "CBaseLoader"]) - .getAUse() + .getAValueReachableFromSource() ) } diff --git a/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll b/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll index 2af91a69432..f8d7ae75ad0 100644 --- a/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll +++ b/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll @@ -23,7 +23,7 @@ private import semmle.python.dataflow.new.TaintTracking * A remote flow source originating from a CSV source row. */ private class RemoteFlowSourceFromCsv extends RemoteFlowSource { - RemoteFlowSourceFromCsv() { this = ModelOutput::getASourceNode("remote").getAnImmediateUse() } + RemoteFlowSourceFromCsv() { this = ModelOutput::getASourceNode("remote").asSource() } override string getSourceType() { result = "Remote flow (from model)" } } @@ -34,8 +34,8 @@ private class RemoteFlowSourceFromCsv extends RemoteFlowSource { private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, string kind) { exists(API::Node predNode, API::Node succNode | Specific::summaryStep(predNode, succNode, kind) and - pred = predNode.getARhs() and - succ = succNode.getAnImmediateUse() + pred = predNode.asSink() and + succ = succNode.asSource() ) } diff --git a/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll b/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll index 57e7131c2b7..5feaa7f61da 100644 --- a/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll +++ b/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll @@ -33,7 +33,9 @@ module PEP249 { } /** Gets a reference to the `connect` function of a module that implements PEP 249. */ - DataFlow::Node connect() { result = any(PEP249ModuleApiNode a).getMember("connect").getAUse() } + DataFlow::Node connect() { + result = any(PEP249ModuleApiNode a).getMember("connect").getAValueReachableFromSource() + } /** * Provides models for database connections (following PEP 249). diff --git a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll index 8bef349f417..04b0a9e4afd 100644 --- a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll +++ b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll @@ -74,9 +74,7 @@ private module NotExposed { } /** DEPRECATED: Alias for fullyQualifiedToApiGraphPath */ - deprecated string fullyQualifiedToAPIGraphPath(string fullyQaulified) { - result = fullyQualifiedToApiGraphPath(fullyQaulified) - } + deprecated predicate fullyQualifiedToAPIGraphPath = fullyQualifiedToApiGraphPath/1; bindingset[this] abstract class FindSubclassesSpec extends string { @@ -152,7 +150,7 @@ private module NotExposed { FindSubclassesSpec spec, string newAliasFullyQualified, ImportMember importMember, Module mod, Location loc ) { - importMember = newOrExistingModeling(spec).getAUse().asExpr() and + importMember = newOrExistingModeling(spec).getAValueReachableFromSource().asExpr() and importMember.getScope() = mod and loc = importMember.getLocation() and ( @@ -182,7 +180,7 @@ private module NotExposed { // WHAT A HACK :D :D relevantClass.getPath() = relevantClass.getAPredecessor().getPath() + ".getMember(\"" + relevantName + "\")" and - relevantClass.getAPredecessor().getAUse().asExpr() = importStar.getModule() and + relevantClass.getAPredecessor().getAValueReachableFromSource().asExpr() = importStar.getModule() and ( mod.isPackageInit() and newAliasFullyQualified = mod.getPackageName() + "." + relevantName @@ -204,7 +202,7 @@ private module NotExposed { FindSubclassesSpec spec, string newSubclassQualified, ClassExpr classExpr, Module mod, Location loc ) { - classExpr = newOrExistingModeling(spec).getASubclass*().getAnImmediateUse().asExpr() and + classExpr = newOrExistingModeling(spec).getASubclass*().asSource().asExpr() and classExpr.getScope() = mod and newSubclassQualified = mod.getName() + "." + classExpr.getName() and loc = classExpr.getLocation() and diff --git a/python/ql/lib/semmle/python/internal/CachedStages.qll b/python/ql/lib/semmle/python/internal/CachedStages.qll index ad4fe98ccee..290a90f5a73 100644 --- a/python/ql/lib/semmle/python/internal/CachedStages.qll +++ b/python/ql/lib/semmle/python/internal/CachedStages.qll @@ -121,7 +121,7 @@ module Stages { or exists(any(NewDataFlow::TypeTracker t).append(_)) or - exists(any(API::Node n).getAMember().getAUse()) + exists(any(API::Node n).getAMember().getAValueReachableFromSource()) } } diff --git a/python/ql/lib/semmle/python/pointsto/MRO.qll b/python/ql/lib/semmle/python/pointsto/MRO.qll index b1ea92b8c24..bc8ff0b1889 100644 --- a/python/ql/lib/semmle/python/pointsto/MRO.qll +++ b/python/ql/lib/semmle/python/pointsto/MRO.qll @@ -344,12 +344,12 @@ private class ClassListList extends TClassListList { ) } - private predicate legalMergeCandidate(ClassObjectInternal cls, ClassListList remaining) { - cls = this.getAHead() and remaining = this + private predicate legalMergeCandidate(ClassObjectInternal cls, ClassListList remainingList) { + cls = this.getAHead() and remainingList = this or - this.legalMergeCandidate(cls, ConsList(Empty(), remaining)) + this.legalMergeCandidate(cls, ConsList(Empty(), remainingList)) or - this.legalMergeCandidateNonEmpty(cls, remaining, Empty()) + this.legalMergeCandidateNonEmpty(cls, remainingList, Empty()) } pragma[noinline] @@ -386,10 +386,10 @@ private class ClassListList extends TClassListList { private ClassList flatten_list(ClassListList list, int n) { need_flattening(list) and - exists(ClassList head, ClassListList tail | list = ConsList(head, tail) | + exists(ClassList head, ClassListList tail | pragma[only_bind_out](list) = ConsList(head, tail) | n = head.length() and result = tail.flatten() or - result = Cons(head.getItem(n), flatten_list(list, n + 1)) + result = Cons(head.getItem(n), flatten_list(pragma[only_bind_out](list), n + 1)) ) } @@ -419,7 +419,9 @@ private ClassListList list_of_linearization_of_bases_plus_bases(ClassObjectInter result = ConsList(bases(cls), EmptyList()) and n = Types::base_count(cls) and n > 1 or exists(ClassListList partial | - partial = list_of_linearization_of_bases_plus_bases(cls, n + 1) and + partial = + list_of_linearization_of_bases_plus_bases(pragma[only_bind_into](cls), + pragma[only_bind_into](n + 1)) and result = ConsList(Mro::newStyleMro(Types::getBase(cls, n)), partial) ) } diff --git a/python/ql/lib/semmle/python/regex.qll b/python/ql/lib/semmle/python/regex.qll index b72adba1716..5431d5df320 100644 --- a/python/ql/lib/semmle/python/regex.qll +++ b/python/ql/lib/semmle/python/regex.qll @@ -75,7 +75,7 @@ private string canonical_name(API::Node flag) { */ private DataFlow::TypeTrackingNode re_flag_tracker(string flag_name, DataFlow::TypeTracker t) { t.start() and - exists(API::Node flag | flag_name = canonical_name(flag) and result = flag.getAnImmediateUse()) + exists(API::Node flag | flag_name = canonical_name(flag) and result = flag.asSource()) or exists(BinaryExprNode binop, DataFlow::Node operand | operand.getALocalSource() = re_flag_tracker(flag_name, t.continue()) and diff --git a/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll index 83ef25e2d78..a96bbb996bc 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll @@ -64,7 +64,7 @@ module PathInjection { private import semmle.python.frameworks.data.ModelsAsData private class DataAsFileSink extends Sink { - DataAsFileSink() { this = ModelOutput::getASinkNode("path-injection").getARhs() } + DataAsFileSink() { this = ModelOutput::getASinkNode("path-injection").asSink() } } /** diff --git a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll index 7e307c0e57c..61172dc192a 100644 --- a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll @@ -67,6 +67,6 @@ module SqlInjection { /** A sink for sql-injection from model data. */ private class DataAsSqlSink extends Sink { - DataAsSqlSink() { this = ModelOutput::getASinkNode("sql-injection").getARhs() } + DataAsSqlSink() { this = ModelOutput::getASinkNode("sql-injection").asSink() } } } diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll new file mode 100644 index 00000000000..1a3df320358 --- /dev/null +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll @@ -0,0 +1,142 @@ +/** + * Provides default sources, sinks and sanitizers for detecting + * "tar slip" + * vulnerabilities, as well as extension points for adding your own. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.Concepts +private import semmle.python.dataflow.new.BarrierGuards +private import semmle.python.ApiGraphs + +/** + * Provides default sources, sinks and sanitizers for detecting + * "tar slip" + * vulnerabilities, as well as extension points for adding your own. + */ +module TarSlip { + /** + * A data flow source for "tar slip" vulnerabilities. + */ + abstract class Source extends DataFlow::Node { } + + /** + * A data flow sink for "tar slip" vulnerabilities. + */ + abstract class Sink extends DataFlow::Node { } + + /** + * A sanitizer for "tar slip" vulnerabilities. + */ + abstract class Sanitizer extends DataFlow::Node { } + + /** + * A call to `tarfile.open`, considered as a flow source. + */ + class TarfileOpen extends Source { + TarfileOpen() { + this = API::moduleImport("tarfile").getMember("open").getACall() and + // If argument refers to a string object, then it's a hardcoded path and + // this tarfile is safe. + not this.(DataFlow::CallCfgNode).getArg(0).getALocalSource().asExpr() instanceof StrConst and + // Ignore opens within the tarfile module itself + not this.getLocation().getFile().getBaseName() = "tarfile.py" + } + } + + /** + * A sanitizer based on file name. This because we extract the standard library. + * + * For efficiency we don't want to track the flow of taint + * around the tarfile module. + */ + class ExcludeTarFilePy extends Sanitizer { + ExcludeTarFilePy() { this.getLocation().getFile().getBaseName() = "tarfile.py" } + } + + /** + * A sink capturing method calls to `extractall`. + * + * For a call to `file.extractall` without arguments, `file` is considered a sink. + */ + class ExtractAllSink extends Sink { + ExtractAllSink() { + exists(DataFlow::CallCfgNode call | + call = + API::moduleImport("tarfile") + .getMember("open") + .getReturn() + .getMember("extractall") + .getACall() and + not exists(call.getArg(_)) and + not exists(call.getArgByName(_)) and + this = call.(DataFlow::MethodCallNode).getObject() + ) + } + } + + /** + * An argument to `extract` is considered a sink. + */ + class ExtractSink extends Sink { + ExtractSink() { + exists(DataFlow::CallCfgNode call | + call = + API::moduleImport("tarfile").getMember("open").getReturn().getMember("extract").getACall() and + this = call.getArg(0) + ) + } + } + + /** The `members` argument `extractall` is considered a sink. */ + class ExtractMembersSink extends Sink { + ExtractMembersSink() { + exists(DataFlow::CallCfgNode call | + call = + API::moduleImport("tarfile") + .getMember("open") + .getReturn() + .getMember("extractall") + .getACall() and + this in [call.getArg(0), call.getArgByName("members")] + ) + } + } + + /** + * Holds if `g` clears taint for `tarInfo`. + * + * The test `if (info.name)` should clear taint for `info`, + * where `` is any function matching `"%path"`. + * `info` is assumed to be a `TarInfo` instance. + */ + predicate tarFileInfoSanitizer(DataFlow::GuardNode g, ControlFlowNode tarInfo, boolean branch) { + exists(CallNode call, AttrNode attr | + g = call and + // We must test the name of the tar info object. + attr = call.getAnArg() and + attr.getName() = "name" and + attr.getObject() = tarInfo + | + // The assumption that any test that matches %path is a sanitizer might be too broad. + call.getAChild*().(AttrNode).getName().matches("%path") + or + call.getAChild*().(NameNode).getId().matches("%path") + ) and + branch = false + } + + /** + * A sanitizer guard heuristic. + * + * The test `if (info.name)` should clear taint for `info`, + * where `` is any function matching `"%path"`. + * `info` is assumed to be a `TarInfo` instance. + */ + class TarFileInfoSanitizer extends Sanitizer { + TarFileInfoSanitizer() { + this = DataFlow::BarrierGuard::getABarrierNode() + } + } +} diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll new file mode 100644 index 00000000000..6cf41742a66 --- /dev/null +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll @@ -0,0 +1,25 @@ +/** + * Provides a taint-tracking configuration for detecting "command injection" vulnerabilities. + * + * Note, for performance reasons: only import this file if + * `TarSlip::Configuration` is needed, otherwise + * `TarSlipCustomizations` should be imported instead. + */ + +private import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import TarSlipCustomizations::TarSlip + +/** + * A taint-tracking configuration for detecting "command injection" vulnerabilities. + */ +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "TarSlip" } + + override predicate isSource(DataFlow::Node source) { source instanceof Source } + + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } +} diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 80db3bd9944..fae4ab0dc9a 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,19 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/python-all` package. + +## 0.2.0 + +### Major Analysis Improvements + +* Improved library modeling for the query "Request without certificate validation" (`py/request-without-cert-validation`), so it now also covers `httpx`, `aiohttp.client`, and `urllib3`. + +### Minor Analysis Improvements + +* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now reports if a cryptographic operation is potentially insecure due to use of a weak block mode. + ## 0.1.4 ## 0.1.3 diff --git a/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll b/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll index 2192951f76d..5e9bc406512 100644 --- a/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll +++ b/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll @@ -53,7 +53,7 @@ predicate matchesBeginningOfString(RegExpTerm term) { } /** - * Holds if the given sequence contains top-level domain preceded by a dot, such as `.com`, + * Holds if the given sequence `seq` contains top-level domain preceded by a dot, such as `.com`, * excluding cases where this is at the very beginning of the regexp. * * `i` is bound to the index of the last child in the top-level domain part. diff --git a/python/ql/src/Security/CWE-022/TarSlip.ql b/python/ql/src/Security/CWE-022/TarSlip.ql index 76d799a0aca..b2ad6cb3372 100644 --- a/python/ql/src/Security/CWE-022/TarSlip.ql +++ b/python/ql/src/Security/CWE-022/TarSlip.ql @@ -13,170 +13,10 @@ */ import python -import semmle.python.security.Paths -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic +import semmle.python.security.dataflow.TarSlipQuery +import DataFlow::PathGraph -/** A TaintKind to represent open tarfile objects. That is, the result of calling `tarfile.open(...)` */ -class OpenTarFile extends TaintKind { - OpenTarFile() { this = "tarfile.open" } - - override TaintKind getTaintOfMethodResult(string name) { - name = "getmember" and result instanceof TarFileInfo - or - name = "getmembers" and result.(SequenceKind).getItem() instanceof TarFileInfo - } - - override ClassValue getType() { result = Value::named("tarfile.TarFile") } - - override TaintKind getTaintForIteration() { result instanceof TarFileInfo } -} - -/** The source of open tarfile objects. That is, any call to `tarfile.open(...)` */ -class TarfileOpen extends TaintSource { - TarfileOpen() { - Value::named("tarfile.open").getACall() = this and - /* - * If argument refers to a string object, then it's a hardcoded path and - * this tarfile is safe. - */ - - not this.(CallNode).getAnArg().pointsTo(any(StringValue str)) and - /* Ignore opens within the tarfile module itself */ - not this.(ControlFlowNode).getLocation().getFile().getBaseName() = "tarfile.py" - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof OpenTarFile } -} - -class TarFileInfo extends TaintKind { - TarFileInfo() { this = "tarfile.entry" } - - override TaintKind getTaintOfMethodResult(string name) { name = "next" and result = this } - - override TaintKind getTaintOfAttribute(string name) { - name = "name" and result instanceof TarFileInfo - } -} - -/* - * For efficiency we don't want to track the flow of taint - * around the tarfile module. - */ - -class ExcludeTarFilePy extends Sanitizer { - ExcludeTarFilePy() { this = "Tar sanitizer" } - - override predicate sanitizingNode(TaintKind taint, ControlFlowNode node) { - node.getLocation().getFile().getBaseName() = "tarfile.py" and - ( - taint instanceof OpenTarFile - or - taint instanceof TarFileInfo - or - taint.(SequenceKind).getItem() instanceof TarFileInfo - ) - } -} - -/* Any call to an extractall method */ -class ExtractAllSink extends TaintSink { - ExtractAllSink() { - exists(CallNode call | - this = call.getFunction().(AttrNode).getObject("extractall") and - not exists(call.getAnArg()) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof OpenTarFile } -} - -/* Argument to extract method */ -class ExtractSink extends TaintSink { - CallNode call; - - ExtractSink() { - call.getFunction().(AttrNode).getName() = "extract" and - this = call.getArg(0) - } - - override predicate sinks(TaintKind kind) { kind instanceof TarFileInfo } -} - -/* Members argument to extract method */ -class ExtractMembersSink extends TaintSink { - CallNode call; - - ExtractMembersSink() { - call.getFunction().(AttrNode).getName() = "extractall" and - (this = call.getArg(0) or this = call.getArgByName("members")) - } - - override predicate sinks(TaintKind kind) { - kind.(SequenceKind).getItem() instanceof TarFileInfo - or - kind instanceof OpenTarFile - } -} - -class TarFileInfoSanitizer extends Sanitizer { - TarFileInfoSanitizer() { this = "TarInfo sanitizer" } - - /* The test `if :` clears taint on its `false` edge. */ - override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) { - taint instanceof TarFileInfo and - clears_taint_on_false_edge(test.getTest(), test.getSense()) - } - - private predicate clears_taint_on_false_edge(ControlFlowNode test, boolean sense) { - path_sanitizing_test(test) and - sense = false - or - // handle `not` (also nested) - test.(UnaryExprNode).getNode().getOp() instanceof Not and - clears_taint_on_false_edge(test.(UnaryExprNode).getOperand(), sense.booleanNot()) - } -} - -private predicate path_sanitizing_test(ControlFlowNode test) { - /* Assume that any test with "path" in it is a sanitizer */ - test.getAChild+().(AttrNode).getName().matches("%path") - or - test.getAChild+().(NameNode).getId().matches("%path") -} - -class TarSlipConfiguration extends TaintTracking::Configuration { - TarSlipConfiguration() { this = "TarSlip configuration" } - - override predicate isSource(TaintTracking::Source source) { source instanceof TarfileOpen } - - override predicate isSink(TaintTracking::Sink sink) { - sink instanceof ExtractSink or - sink instanceof ExtractAllSink or - sink instanceof ExtractMembersSink - } - - override predicate isSanitizer(Sanitizer sanitizer) { - sanitizer instanceof TarFileInfoSanitizer - or - sanitizer instanceof ExcludeTarFilePy - } - - override predicate isBarrier(DataFlow::Node node) { - // Avoid flow into the tarfile module - exists(ParameterDefinition def | - node.asVariable().getDefinition() = def - or - node.asCfgNode() = def.getDefiningNode() - | - def.getScope() = Value::named("tarfile.open").(CallableValue).getScope() - or - def.isSelf() and def.getScope().getEnclosingModule().getName() = "tarfile" - ) - } -} - -from TarSlipConfiguration config, TaintedPathSource src, TaintedPathSink sink -where config.hasFlowPath(src, sink) -select sink.getSink(), src, sink, "Extraction of tarfile from $@", src.getSource(), +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Extraction of tarfile from $@", source.getNode(), "a potentially untrusted source" diff --git a/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql b/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql index 820937f8649..97bbb72edec 100644 --- a/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql +++ b/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql @@ -42,7 +42,7 @@ where not exists(call.getArgByName("autoescape")) or call.getKeywordParameter("autoescape") - .getAValueReachingRhs() + .getAValueReachingSink() .asExpr() .(ImmutableLiteral) .booleanValue() = false diff --git a/python/ql/src/Security/CWE-285/PamAuthorization.ql b/python/ql/src/Security/CWE-285/PamAuthorization.ql index 233e42e6239..affb59ff7db 100644 --- a/python/ql/src/Security/CWE-285/PamAuthorization.ql +++ b/python/ql/src/Security/CWE-285/PamAuthorization.ql @@ -18,9 +18,9 @@ import semmle.python.dataflow.new.TaintTracking API::Node libPam() { exists(API::CallNode findLibCall, API::CallNode cdllCall | findLibCall = API::moduleImport("ctypes").getMember("util").getMember("find_library").getACall() and - findLibCall.getParameter(0).getAValueReachingRhs().asExpr().(StrConst).getText() = "pam" and + findLibCall.getParameter(0).getAValueReachingSink().asExpr().(StrConst).getText() = "pam" and cdllCall = API::moduleImport("ctypes").getMember("CDLL").getACall() and - cdllCall.getParameter(0).getAValueReachingRhs() = findLibCall + cdllCall.getParameter(0).getAValueReachingSink() = findLibCall | result = cdllCall.getReturn() ) diff --git a/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql b/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql index 89548d714ce..713354c84a0 100644 --- a/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql +++ b/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql @@ -29,7 +29,7 @@ where call = paramikoSSHClientInstance().getMember("set_missing_host_key_policy").getACall() and arg in [call.getArg(0), call.getArgByName("policy")] and ( - arg = unsafe_paramiko_policy(name).getAUse() or - arg = unsafe_paramiko_policy(name).getReturn().getAUse() + arg = unsafe_paramiko_policy(name).getAValueReachableFromSource() or + arg = unsafe_paramiko_policy(name).getReturn().getAValueReachableFromSource() ) select call, "Setting missing host key policy to " + name + " may be unsafe." diff --git a/python/ql/src/Security/CWE-327/PyOpenSSL.qll b/python/ql/src/Security/CWE-327/PyOpenSSL.qll index a0008cdc7c1..7f7b9184570 100644 --- a/python/ql/src/Security/CWE-327/PyOpenSSL.qll +++ b/python/ql/src/Security/CWE-327/PyOpenSSL.qll @@ -17,7 +17,8 @@ class PyOpenSSLContextCreation extends ContextCreation, DataFlow::CallCfgNode { protocolArg in [this.getArg(0), this.getArgByName("method")] | protocolArg in [ - pyo.specific_version(result).getAUse(), pyo.unspecific_version(result).getAUse() + pyo.specific_version(result).getAValueReachableFromSource(), + pyo.unspecific_version(result).getAValueReachableFromSource() ] ) } @@ -43,9 +44,10 @@ class SetOptionsCall extends ProtocolRestriction, DataFlow::CallCfgNode { } override ProtocolVersion getRestriction() { - API::moduleImport("OpenSSL").getMember("SSL").getMember("OP_NO_" + result).getAUse() in [ - this.getArg(0), this.getArgByName("options") - ] + API::moduleImport("OpenSSL") + .getMember("SSL") + .getMember("OP_NO_" + result) + .getAValueReachableFromSource() in [this.getArg(0), this.getArgByName("options")] } } diff --git a/python/ql/src/Security/CWE-327/Ssl.qll b/python/ql/src/Security/CWE-327/Ssl.qll index 80ef32c8de6..d1122f82ed9 100644 --- a/python/ql/src/Security/CWE-327/Ssl.qll +++ b/python/ql/src/Security/CWE-327/Ssl.qll @@ -15,7 +15,10 @@ class SSLContextCreation extends ContextCreation, DataFlow::CallCfgNode { protocolArg in [this.getArg(0), this.getArgByName("protocol")] | protocolArg = - [ssl.specific_version(result).getAUse(), ssl.unspecific_version(result).getAUse()] + [ + ssl.specific_version(result).getAValueReachableFromSource(), + ssl.unspecific_version(result).getAValueReachableFromSource() + ] ) or not exists(this.getArg(_)) and @@ -54,7 +57,11 @@ class OptionsAugOr extends ProtocolRestriction, DataFlow::CfgNode { aa.getTarget() = attr.getNode() and attr.getName() = "options" and attr.getObject() = node and - flag = API::moduleImport("ssl").getMember("OP_NO_" + restriction).getAUse().asExpr() and + flag = + API::moduleImport("ssl") + .getMember("OP_NO_" + restriction) + .getAValueReachableFromSource() + .asExpr() and ( aa.getValue() = flag or @@ -79,7 +86,11 @@ class OptionsAugAndNot extends ProtocolUnrestriction, DataFlow::CfgNode { attr.getObject() = node and notFlag.getOp() instanceof Invert and notFlag.getOperand() = flag and - flag = API::moduleImport("ssl").getMember("OP_NO_" + restriction).getAUse().asExpr() and + flag = + API::moduleImport("ssl") + .getMember("OP_NO_" + restriction) + .getAValueReachableFromSource() + .asExpr() and ( aa.getValue() = notFlag or @@ -134,7 +145,10 @@ class ContextSetVersion extends ProtocolRestriction, ProtocolUnrestriction, Data this = aw.getObject() and aw.getAttributeName() = "minimum_version" and aw.getValue() = - API::moduleImport("ssl").getMember("TLSVersion").getMember(restriction).getAUse() + API::moduleImport("ssl") + .getMember("TLSVersion") + .getMember(restriction) + .getAValueReachableFromSource() ) } @@ -188,7 +202,8 @@ class Ssl extends TlsLibrary { override DataFlow::CallCfgNode insecure_connection_creation(ProtocolVersion version) { result = API::moduleImport("ssl").getMember("wrap_socket").getACall() and - this.specific_version(version).getAUse() = result.getArgByName("ssl_version") and + this.specific_version(version).getAValueReachableFromSource() = + result.getArgByName("ssl_version") and version.isInsecure() } diff --git a/python/ql/src/Security/CWE-732/WeakFilePermissions.ql b/python/ql/src/Security/CWE-732/WeakFilePermissions.ql index 393198cf72e..90921b99fb9 100644 --- a/python/ql/src/Security/CWE-732/WeakFilePermissions.ql +++ b/python/ql/src/Security/CWE-732/WeakFilePermissions.ql @@ -36,13 +36,13 @@ string permissive_permission(int p) { predicate chmod_call(API::CallNode call, string name, int mode) { call = API::moduleImport("os").getMember("chmod").getACall() and - mode = call.getParameter(1, "mode").getAValueReachingRhs().asExpr().(IntegerLiteral).getValue() and + mode = call.getParameter(1, "mode").getAValueReachingSink().asExpr().(IntegerLiteral).getValue() and name = "chmod" } predicate open_call(API::CallNode call, string name, int mode) { call = API::moduleImport("os").getMember("open").getACall() and - mode = call.getParameter(2, "mode").getAValueReachingRhs().asExpr().(IntegerLiteral).getValue() and + mode = call.getParameter(2, "mode").getAValueReachingSink().asExpr().(IntegerLiteral).getValue() and name = "open" } diff --git a/python/ql/src/analysis/Consistency.ql b/python/ql/src/analysis/Consistency.ql index d6f1bbc32c5..9f739d18415 100644 --- a/python/ql/src/analysis/Consistency.ql +++ b/python/ql/src/analysis/Consistency.ql @@ -5,7 +5,7 @@ */ import python -import DefinitionTracking +import analysis.DefinitionTracking predicate uniqueness_error(int number, string what, string problem) { what in [ diff --git a/python/ql/src/analysis/Definitions.ql b/python/ql/src/analysis/Definitions.ql index a2ed4f36bf6..bf2458dd8ab 100644 --- a/python/ql/src/analysis/Definitions.ql +++ b/python/ql/src/analysis/Definitions.ql @@ -6,7 +6,7 @@ */ import python -import DefinitionTracking +import analysis.DefinitionTracking from NiceLocationExpr use, Definition defn, string kind where defn = definitionOf(use, kind) diff --git a/python/ql/src/analysis/RatioOfDefinitions.ql b/python/ql/src/analysis/RatioOfDefinitions.ql index f7ef4741ee6..562deb75005 100644 --- a/python/ql/src/analysis/RatioOfDefinitions.ql +++ b/python/ql/src/analysis/RatioOfDefinitions.ql @@ -3,7 +3,7 @@ */ import python -import DefinitionTracking +import analysis.DefinitionTracking predicate want_to_have_definition(Expr e) { /* not builtin object like len, tuple, etc. */ diff --git a/python/ql/src/change-notes/2022-05-16-broken-crypto-block-mode.md b/python/ql/src/change-notes/2022-05-16-broken-crypto-block-mode.md deleted file mode 100644 index 3ddf8c2c884..00000000000 --- a/python/ql/src/change-notes/2022-05-16-broken-crypto-block-mode.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. diff --git a/python/ql/src/change-notes/2022-06-08-request-without-certificate-validation-modeling.md b/python/ql/src/change-notes/2022-06-08-request-without-certificate-validation-modeling.md deleted file mode 100644 index f21f7cb93ba..00000000000 --- a/python/ql/src/change-notes/2022-06-08-request-without-certificate-validation-modeling.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Improved library modeling for the query "Request without certificate validation" (`py/request-without-cert-validation`), so it now also covers `httpx`, `aiohttp.client`, and `urllib3`. diff --git a/python/ql/src/change-notes/2022-07-15-move-contextual-queries.md b/python/ql/src/change-notes/2022-07-15-move-contextual-queries.md new file mode 100644 index 00000000000..25ae1b57b99 --- /dev/null +++ b/python/ql/src/change-notes/2022-07-15-move-contextual-queries.md @@ -0,0 +1,5 @@ +--- +category: breaking +--- +* Contextual queries and the query libraries they depend on have been moved to the `codeql/python-all` package. + diff --git a/python/ql/src/change-notes/released/0.2.0.md b/python/ql/src/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..d9816a102f4 --- /dev/null +++ b/python/ql/src/change-notes/released/0.2.0.md @@ -0,0 +1,9 @@ +## 0.2.0 + +### Major Analysis Improvements + +* Improved library modeling for the query "Request without certificate validation" (`py/request-without-cert-validation`), so it now also covers `httpx`, `aiohttp.client`, and `urllib3`. + +### Minor Analysis Improvements + +* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now reports if a cryptographic operation is potentially insecure due to use of a weak block mode. diff --git a/python/ql/src/change-notes/released/0.3.0.md b/python/ql/src/change-notes/released/0.3.0.md new file mode 100644 index 00000000000..7b54313449c --- /dev/null +++ b/python/ql/src/change-notes/released/0.3.0.md @@ -0,0 +1,5 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/python-all` package. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index e8ee3af8ef9..95f6e3a0ba6 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.3.0 diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py new file mode 100644 index 00000000000..96aeb436a9b --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py @@ -0,0 +1,7 @@ +blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name) +blob_client.require_encryption = True +blob_client.key_encryption_key = kek +# GOOD: Must use `encryption_version` set to `2.0` +blob_client.encryption_version = '2.0' # Use Version 2.0! +with open("decryptedcontentfile.txt", "rb") as stream: + blob_client.upload_blob(stream, overwrite=OVERWRITE_EXISTING) \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp new file mode 100644 index 00000000000..a2f9a2213c3 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -0,0 +1,29 @@ + + + + + +

    Azure Storage .NET, Java, and Python SDKs support encryption on the client with a customer-managed key that is maintained in Azure Key Vault or another key store.

    +

    Current release versions of the Azure Storage SDKs use cipher block chaining (CBC mode) for client-side encryption (referred to as v1).

    + +
    + + +

    Consider switching to v2 client-side encryption.

    + +
    + + + + + + +
  • + Azure Storage Client Encryption Blog. +
  • +
  • + CVE-2022-30187 +
  • + +
    +
    diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql new file mode 100644 index 00000000000..c9687b17821 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -0,0 +1,90 @@ +/** + * @name Unsafe usage of v1 version of Azure Storage client-side encryption. + * @description Using version v1 of Azure Storage client-side encryption is insecure, and may enable an attacker to decrypt encrypted data + * @kind problem + * @tags security + * cryptography + * external/cwe/cwe-327 + * @id py/azure-storage/unsafe-client-side-encryption-in-use + * @problem.severity error + * @precision medium + */ + +import python +import semmle.python.ApiGraphs + +predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrNode node) { + exists( + API::Node n, API::Node n2, Attribute a, AssignStmt astmt, API::Node uploadBlob, + ControlFlowNode ctrlFlowNode, string s + | + s in ["key_encryption_key", "key_resolver_function"] and + n = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobClient") + .getReturn() + .getMember(s) and + n2 = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobClient") + .getReturn() + .getMember("upload_blob") and + n.getAValueReachableFromSource().asExpr() = a and + astmt.getATarget() = a and + a.getAFlowNode() = node and + uploadBlob = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobClient") + .getReturn() + .getMember("upload_blob") and + uploadBlob.getACall().asExpr() = call and + ctrlFlowNode = call.getAFlowNode() and + node.strictlyReaches(ctrlFlowNode) and + node != ctrlFlowNode and + not exists( + AssignStmt astmt2, Attribute a2, AttrNode encryptionVersionSet, StrConst uc, + API::Node encryptionVersion + | + uc = astmt2.getValue() and + uc.getText() in ["'2.0'", "2.0"] and + encryptionVersion = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobClient") + .getReturn() + .getMember("encryption_version") and + encryptionVersion.getAValueReachableFromSource().asExpr() = a2 and + astmt2.getATarget() = a2 and + a2.getAFlowNode() = encryptionVersionSet and + encryptionVersionSet.strictlyReaches(ctrlFlowNode) + ) + ) +} + +predicate isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(Call call, ControlFlowNode node) { + exists(API::Node c, string s, Keyword k | k.getAFlowNode() = node | + c.getACall().asExpr() = call and + c = API::moduleImport("azure").getMember("storage").getMember("blob").getMember(s) and + s in ["ContainerClient", "BlobClient", "BlobServiceClient"] and + k.getArg() = "key_encryption_key" and + k = call.getANamedArg() and + not k.getValue() instanceof None and + not exists(Keyword k2 | k2 = call.getANamedArg() | + k2.getArg() = "encryption_version" and + k2.getValue().(StrConst).getText() in ["'2.0'", "2.0"] + ) + ) +} + +from Call call, ControlFlowNode node +where + isUnsafeClientSideAzureStorageEncryptionViaAttributes(call, node) or + isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(call, node) +select node, "Unsafe usage of v1 version of Azure Storage client-side encryption." diff --git a/python/ql/src/experimental/semmle/python/frameworks/Django.qll b/python/ql/src/experimental/semmle/python/frameworks/Django.qll index 6853f9c3f6a..f1895af0ea9 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/Django.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/Django.qll @@ -86,11 +86,13 @@ private module ExperimentalPrivateDjango { t.start() and ( exists(SubscriptNode subscript | - subscript.getObject() = baseClassRef().getReturn().getAUse().asCfgNode() and + subscript.getObject() = + baseClassRef().getReturn().getAValueReachableFromSource().asCfgNode() and result.asCfgNode() = subscript ) or - result.(DataFlow::AttrRead).getObject() = baseClassRef().getReturn().getAUse() + result.(DataFlow::AttrRead).getObject() = + baseClassRef().getReturn().getAValueReachableFromSource() ) or exists(DataFlow::TypeTracker t2 | result = headerInstance(t2).track(t2, t)) diff --git a/python/ql/src/experimental/semmle/python/frameworks/Flask.qll b/python/ql/src/experimental/semmle/python/frameworks/Flask.qll index 5444a692b26..3252acf24fd 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/Flask.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/Flask.qll @@ -29,7 +29,11 @@ module ExperimentalFlask { /** Gets a reference to a header instance. */ private DataFlow::LocalSourceNode headerInstance() { - result = [Flask::Response::classRef(), flaskMakeResponse()].getReturn().getAMember().getAUse() + result = + [Flask::Response::classRef(), flaskMakeResponse()] + .getReturn() + .getAMember() + .getAValueReachableFromSource() } /** Gets a reference to a header instance call/subscript */ diff --git a/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll b/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll index 6085dddf5f8..871b47b48c9 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll @@ -90,7 +90,9 @@ private module LDAP { /**List of SSL-demanding options */ private class LDAPSSLOptions extends DataFlow::Node { - LDAPSSLOptions() { this = ldap().getMember("OPT_X_TLS_" + ["DEMAND", "HARD"]).getAUse() } + LDAPSSLOptions() { + this = ldap().getMember("OPT_X_TLS_" + ["DEMAND", "HARD"]).getAValueReachableFromSource() + } } /** diff --git a/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll b/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll index c5efb3dd833..2d7c93c3029 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll @@ -50,11 +50,11 @@ private module NoSql { t.start() and ( exists(SubscriptNode subscript | - subscript.getObject() = mongoClientInstance().getAUse().asCfgNode() and + subscript.getObject() = mongoClientInstance().getAValueReachableFromSource().asCfgNode() and result.asCfgNode() = subscript ) or - result.(DataFlow::AttrRead).getObject() = mongoClientInstance().getAUse() + result.(DataFlow::AttrRead).getObject() = mongoClientInstance().getAValueReachableFromSource() or result = mongoEngine().getMember(["get_db", "connect"]).getACall() or diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 85db089100e..155e57024e8 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.2.0-dev +version: 0.3.1-dev groups: - python - queries diff --git a/python/ql/test/TestUtilities/VerifyApiGraphs.qll b/python/ql/test/TestUtilities/VerifyApiGraphs.qll index 22d7ae365d4..f2d43a08867 100644 --- a/python/ql/test/TestUtilities/VerifyApiGraphs.qll +++ b/python/ql/test/TestUtilities/VerifyApiGraphs.qll @@ -21,10 +21,10 @@ import semmle.python.ApiGraphs private DataFlow::Node getNode(API::Node nd, string kind) { kind = "def" and - result = nd.getARhs() + result = nd.asSink() or kind = "use" and - result = nd.getAUse() + result = nd.getAValueReachableFromSource() } private string getLocStr(Location loc) { diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py b/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py index 2fc809cf18f..f1b01f4f84a 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py +++ b/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py @@ -50,7 +50,7 @@ def test_non_eq2(): if not ts == "safe": ensure_tainted(ts) # $ tainted else: - ensure_not_tainted(ts) # $ SPURIOUS: tainted + ensure_not_tainted(ts) def test_in_list(): @@ -157,7 +157,7 @@ def test_not_in2(): if not ts in ["safe", "also_safe"]: ensure_tainted(ts) # $ tainted else: - ensure_not_tainted(ts) # $ SPURIOUS: tainted + ensure_not_tainted(ts) def is_safe(x): diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected index c8c41375538..fdad063534b 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected @@ -6,12 +6,20 @@ isSanitizer | TestTaintTrackingConfiguration | test.py:34:39:34:39 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test.py:52:28:52:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test.py:66:10:66:29 | ControlFlowNode for emulated_escaping() | -| TestTaintTrackingConfiguration | test_logical.py:30:28:30:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:45:28:45:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:50:28:50:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:89:28:89:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:100:28:100:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:145:28:145:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:33:28:33:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:40:28:40:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:48:28:48:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:53:28:53:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:92:28:92:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:103:28:103:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:111:28:111:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:130:28:130:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:137:28:137:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:148:28:148:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:155:28:155:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:151:28:151:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:158:28:158:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:167:24:167:24 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:176:24:176:24 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:185:24:185:24 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:193:24:193:24 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_reference.py:31:28:31:28 | ControlFlowNode for s | diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql index c68bd2d274d..984cf74d036 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql @@ -6,6 +6,12 @@ predicate isSafeCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean branc branch = true } +predicate isUnsafeCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean branch) { + g.(CallNode).getNode().getFunc().(Name).getId() in ["is_unsafe", "emulated_is_unsafe"] and + node = g.(CallNode).getAnArg() and + branch = false +} + class CustomSanitizerOverrides extends TestTaintTrackingConfiguration { override predicate isSanitizer(DataFlow::Node node) { exists(Call call | @@ -16,6 +22,8 @@ class CustomSanitizerOverrides extends TestTaintTrackingConfiguration { node.asExpr().(Call).getFunc().(Name).getId() = "emulated_escaping" or node = DataFlow::BarrierGuard::getABarrierNode() + or + node = DataFlow::BarrierGuard::getABarrierNode() } } diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py index a879c3c332c..26e69b8fc05 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py @@ -22,6 +22,9 @@ def random_choice(): def is_safe(arg): return arg == "safe" +def is_unsafe(arg): + return arg == TAINTED_STRING + def test_basic(): s = TAINTED_STRING @@ -34,7 +37,7 @@ def test_basic(): if not is_safe(s): ensure_tainted(s) # $ tainted else: - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) def test_if_in_depth(): @@ -105,7 +108,7 @@ def test_and(): ensure_tainted(s) # $ tainted else: # cannot be tainted - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) def test_tricky(): @@ -124,14 +127,14 @@ def test_nesting_not(): s = TAINTED_STRING if not(not(is_safe(s))): - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) else: ensure_tainted(s) # $ tainted if not(not(not(is_safe(s)))): ensure_tainted(s) # $ tainted else: - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) # Adding `and True` makes the sanitizer trigger when it would otherwise not. See output in @@ -161,7 +164,16 @@ def test_with_return(): if not is_safe(s): return - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) + + +def test_with_return_neg(): + s = TAINTED_STRING + + if is_unsafe(s): + return + + ensure_not_tainted(s) def test_with_exception(): @@ -170,7 +182,15 @@ def test_with_exception(): if not is_safe(s): raise Exception("unsafe") - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) + +def test_with_exception_neg(): + s = TAINTED_STRING + + if is_unsafe(s): + raise Exception("unsafe") + + ensure_not_tainted(s) # Make tests runable @@ -182,7 +202,12 @@ test_tricky() test_nesting_not() test_nesting_not_with_and_true() test_with_return() +test_with_return_neg() try: test_with_exception() except: pass +try: + test_with_exception_neg() +except: + pass diff --git a/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql b/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql index 91375904043..74f5f259319 100644 --- a/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql +++ b/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql @@ -5,7 +5,7 @@ import semmle.python.ApiGraphs private DataFlow::TypeTrackingNode module_tracker(TypeTracker t) { t.start() and - result = API::moduleImport("module").getAnImmediateUse() + result = API::moduleImport("module").asSource() or exists(TypeTracker t2 | result = module_tracker(t2).track(t2, t)) } diff --git a/python/ql/test/experimental/dataflow/typetracking/tracked.ql b/python/ql/test/experimental/dataflow/typetracking/tracked.ql index 142e5b11639..c35775d0046 100644 --- a/python/ql/test/experimental/dataflow/typetracking/tracked.ql +++ b/python/ql/test/experimental/dataflow/typetracking/tracked.ql @@ -120,7 +120,7 @@ class TrackedSelfTest extends InlineExpectationsTest { /** Gets a reference to `foo` (fictive module). */ private DataFlow::TypeTrackingNode foo(DataFlow::TypeTracker t) { t.start() and - result = API::moduleImport("foo").getAnImmediateUse() + result = API::moduleImport("foo").asSource() or exists(DataFlow::TypeTracker t2 | result = foo(t2).track(t2, t)) } @@ -131,7 +131,7 @@ DataFlow::Node foo() { foo(DataFlow::TypeTracker::end()).flowsTo(result) } /** Gets a reference to `foo.bar` (fictive module). */ private DataFlow::TypeTrackingNode foo_bar(DataFlow::TypeTracker t) { t.start() and - result = API::moduleImport("foo").getMember("bar").getAnImmediateUse() + result = API::moduleImport("foo").getMember("bar").asSource() or t.startInAttr("bar") and result = foo() @@ -145,7 +145,7 @@ DataFlow::Node foo_bar() { foo_bar(DataFlow::TypeTracker::end()).flowsTo(result) /** Gets a reference to `foo.bar.baz` (fictive attribute on `foo.bar` module). */ private DataFlow::TypeTrackingNode foo_bar_baz(DataFlow::TypeTracker t) { t.start() and - result = API::moduleImport("foo").getMember("bar").getMember("baz").getAnImmediateUse() + result = API::moduleImport("foo").getMember("bar").getMember("baz").asSource() or t.startInAttr("baz") and result = foo_bar() diff --git a/python/ql/test/experimental/meta/MaDTest.qll b/python/ql/test/experimental/meta/MaDTest.qll index 3d75ba0d2e7..a4b5877f5ea 100644 --- a/python/ql/test/experimental/meta/MaDTest.qll +++ b/python/ql/test/experimental/meta/MaDTest.qll @@ -19,7 +19,7 @@ class MadSinkTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(DataFlow::Node sink, string kind | - sink = ModelOutput::getASinkNode(kind).getARhs() and + sink = ModelOutput::getASinkNode(kind).asSink() and location = sink.getLocation() and element = sink.toString() and value = prettyNodeForInlineTest(sink) and @@ -38,7 +38,7 @@ class MadSourceTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(DataFlow::Node source, string kind | - source = ModelOutput::getASourceNode(kind).getAnImmediateUse() and + source = ModelOutput::getASourceNode(kind).asSource() and location = source.getLocation() and element = source.toString() and value = prettyNodeForInlineTest(source) and diff --git a/python/ql/test/library-tests/ApiGraphs/py2/use.ql b/python/ql/test/library-tests/ApiGraphs/py2/use.ql index f02bb048c58..6b18b2c1dd7 100644 --- a/python/ql/test/library-tests/ApiGraphs/py2/use.ql +++ b/python/ql/test/library-tests/ApiGraphs/py2/use.ql @@ -9,7 +9,7 @@ class ApiUseTest extends InlineExpectationsTest { override string getARelevantTag() { result = "use" } private predicate relevant_node(API::Node a, DataFlow::Node n, Location l) { - n = a.getAUse() and l = n.getLocation() + n = a.getAValueReachableFromSource() and l = n.getLocation() } override predicate hasActualResult(Location location, string element, string tag, string value) { diff --git a/python/ql/test/library-tests/frameworks/data/test.ql b/python/ql/test/library-tests/frameworks/data/test.ql index 86f960b1adf..cdd1782052a 100644 --- a/python/ql/test/library-tests/frameworks/data/test.ql +++ b/python/ql/test/library-tests/frameworks/data/test.ql @@ -87,11 +87,11 @@ class BasicTaintTracking extends TaintTracking::Configuration { BasicTaintTracking() { this = "BasicTaintTracking" } override predicate isSource(DataFlow::Node source) { - source = ModelOutput::getASourceNode("test-source").getAnImmediateUse() + source = ModelOutput::getASourceNode("test-source").asSource() } override predicate isSink(DataFlow::Node sink) { - sink = ModelOutput::getASinkNode("test-sink").getARhs() + sink = ModelOutput::getASinkNode("test-sink").asSink() } } @@ -100,11 +100,11 @@ query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) { } query predicate isSink(DataFlow::Node node, string kind) { - node = ModelOutput::getASinkNode(kind).getARhs() + node = ModelOutput::getASinkNode(kind).asSink() } query predicate isSource(DataFlow::Node node, string kind) { - node = ModelOutput::getASourceNode(kind).getAnImmediateUse() + node = ModelOutput::getASourceNode(kind).asSource() } class SyntaxErrorTest extends ModelInput::SinkModelCsv { diff --git a/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected b/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected index edcdaf88e48..2ddfe7143d0 100644 --- a/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected +++ b/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected @@ -1,29 +1,36 @@ edges -| tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open | -| tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open | -| tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:17:14:17:16 | tarfile.open | -| tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:17:14:17:16 | tarfile.open | -| tarslip.py:17:1:17:17 | tarfile.entry | tarslip.py:18:17:18:21 | tarfile.entry | -| tarslip.py:17:1:17:17 | tarfile.entry | tarslip.py:18:17:18:21 | tarfile.entry | -| tarslip.py:17:14:17:16 | tarfile.open | tarslip.py:17:1:17:17 | tarfile.entry | -| tarslip.py:17:14:17:16 | tarfile.open | tarslip.py:17:1:17:17 | tarfile.entry | -| tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:34:14:34:16 | tarfile.open | -| tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:34:14:34:16 | tarfile.open | -| tarslip.py:34:1:34:17 | tarfile.entry | tarslip.py:37:17:37:21 | tarfile.entry | -| tarslip.py:34:1:34:17 | tarfile.entry | tarslip.py:37:17:37:21 | tarfile.entry | -| tarslip.py:34:14:34:16 | tarfile.open | tarslip.py:34:1:34:17 | tarfile.entry | -| tarslip.py:34:14:34:16 | tarfile.open | tarslip.py:34:1:34:17 | tarfile.entry | -| tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open | -| tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open | -| tarslip.py:56:7:56:39 | tarfile.open | tarslip.py:57:14:57:16 | tarfile.open | -| tarslip.py:56:7:56:39 | tarfile.open | tarslip.py:57:14:57:16 | tarfile.open | -| tarslip.py:57:1:57:17 | tarfile.entry | tarslip.py:59:21:59:25 | tarfile.entry | -| tarslip.py:57:1:57:17 | tarfile.entry | tarslip.py:59:21:59:25 | tarfile.entry | -| tarslip.py:57:14:57:16 | tarfile.open | tarslip.py:57:1:57:17 | tarfile.entry | -| tarslip.py:57:14:57:16 | tarfile.open | tarslip.py:57:1:57:17 | tarfile.entry | +| tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | tarslip.py:13:1:13:3 | ControlFlowNode for tar | +| tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | tarslip.py:17:5:17:9 | GSSA Variable entry | +| tarslip.py:17:5:17:9 | GSSA Variable entry | tarslip.py:18:17:18:21 | ControlFlowNode for entry | +| tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | tarslip.py:34:5:34:9 | GSSA Variable entry | +| tarslip.py:34:5:34:9 | GSSA Variable entry | tarslip.py:37:17:37:21 | ControlFlowNode for entry | +| tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | tarslip.py:41:24:41:26 | ControlFlowNode for tar | +| tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | tarslip.py:57:5:57:9 | GSSA Variable entry | +| tarslip.py:57:5:57:9 | GSSA Variable entry | tarslip.py:59:21:59:25 | ControlFlowNode for entry | +| tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | tarslip.py:80:5:80:9 | GSSA Variable entry | +| tarslip.py:80:5:80:9 | GSSA Variable entry | tarslip.py:82:21:82:25 | ControlFlowNode for entry | +nodes +| tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:13:1:13:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:17:5:17:9 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| tarslip.py:18:17:18:21 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:34:5:34:9 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| tarslip.py:37:17:37:21 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:41:24:41:26 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:57:5:57:9 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| tarslip.py:59:21:59:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:80:5:80:9 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| tarslip.py:82:21:82:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +subpaths #select -| tarslip.py:13:1:13:3 | tar | tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open | Extraction of tarfile from $@ | tarslip.py:12:7:12:39 | Attribute() | a potentially untrusted source | -| tarslip.py:18:17:18:21 | entry | tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:18:17:18:21 | tarfile.entry | Extraction of tarfile from $@ | tarslip.py:16:7:16:39 | Attribute() | a potentially untrusted source | -| tarslip.py:37:17:37:21 | entry | tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:37:17:37:21 | tarfile.entry | Extraction of tarfile from $@ | tarslip.py:33:7:33:39 | Attribute() | a potentially untrusted source | -| tarslip.py:41:24:41:26 | tar | tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open | Extraction of tarfile from $@ | tarslip.py:40:7:40:39 | Attribute() | a potentially untrusted source | -| tarslip.py:59:21:59:25 | entry | tarslip.py:56:7:56:39 | tarfile.open | tarslip.py:59:21:59:25 | tarfile.entry | Extraction of tarfile from $@ | tarslip.py:56:7:56:39 | Attribute() | a potentially untrusted source | +| tarslip.py:13:1:13:3 | ControlFlowNode for tar | tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | tarslip.py:13:1:13:3 | ControlFlowNode for tar | Extraction of tarfile from $@ | tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | a potentially untrusted source | +| tarslip.py:18:17:18:21 | ControlFlowNode for entry | tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | tarslip.py:18:17:18:21 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | a potentially untrusted source | +| tarslip.py:37:17:37:21 | ControlFlowNode for entry | tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | tarslip.py:37:17:37:21 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | a potentially untrusted source | +| tarslip.py:41:24:41:26 | ControlFlowNode for tar | tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | tarslip.py:41:24:41:26 | ControlFlowNode for tar | Extraction of tarfile from $@ | tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | a potentially untrusted source | +| tarslip.py:59:21:59:25 | ControlFlowNode for entry | tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | tarslip.py:59:21:59:25 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | a potentially untrusted source | +| tarslip.py:82:21:82:25 | ControlFlowNode for entry | tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | tarslip.py:82:21:82:25 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | a potentially untrusted source | diff --git a/python/ql/test/query-tests/Security/CWE-022-TarSlip/options b/python/ql/test/query-tests/Security/CWE-022-TarSlip/options deleted file mode 100644 index 492768b3481..00000000000 --- a/python/ql/test/query-tests/Security/CWE-022-TarSlip/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: -p ../lib/ --max-import-depth=3 diff --git a/ql/README.md b/ql/README.md index 4bb5e30ba84..29b5aaef63c 100644 --- a/ql/README.md +++ b/ql/README.md @@ -21,14 +21,14 @@ cargo build --release The generated `ql/src/ql.dbscheme` and `ql/src/codeql_ql/ast/internal/TreeSitter.qll` files are included in the repository, but they can be re-generated as follows: ```bash -./create-extractor-pack.sh +./scripts/create-extractor-pack.sh ``` ## Building a CodeQL database for a QL program First, get an extractor pack: -Run `./create-extractor-pack.sh` (Linux/Mac) or `.\create-extractor-pack.ps1` (Windows PowerShell) and the pack will be created in the `extractor-pack` directory. +Run `./scripts/create-extractor-pack.sh` (Linux/Mac) or `.\scripts\create-extractor-pack.ps1` (Windows PowerShell) and the pack will be created in the `extractor-pack` directory. Then run diff --git a/ql/autobuilder/src/main.rs b/ql/autobuilder/src/main.rs index 45977b3792d..df47cc33184 100644 --- a/ql/autobuilder/src/main.rs +++ b/ql/autobuilder/src/main.rs @@ -15,29 +15,25 @@ fn main() -> std::io::Result<()> { let mut cmd = Command::new(codeql); cmd.arg("database") .arg("index-files") + .arg("--include-extension=.ql") + .arg("--include-extension=.qll") + .arg("--include-extension=.dbscheme") + .arg("--include=**/qlpack.yml") .arg("--size-limit=5m") .arg("--language=ql") .arg("--working-dir=.") .arg(db); - let mut has_include_dir = false; // TODO: This is a horrible hack, wait for the post-merge discussion in https://github.com/github/codeql/pull/7444 to be resolved for line in env::var("LGTM_INDEX_FILTERS") .unwrap_or_default() .split('\n') { if let Some(stripped) = line.strip_prefix("include:") { - cmd.arg("--include").arg(stripped); - has_include_dir = true; + cmd.arg("--also-match=".to_owned() + stripped); } else if let Some(stripped) = line.strip_prefix("exclude:") { - cmd.arg("--exclude").arg(stripped); + cmd.arg("--exclude=".to_owned() + stripped); } } - if !has_include_dir { - cmd.arg("--include-extension=.ql") - .arg("--include-extension=.qll") - .arg("--include-extension=.dbscheme") - .arg("--include=**/qlpack.yml"); - } let exit = &cmd.spawn()?.wait()?; std::process::exit(exit.code().unwrap_or(1)) } diff --git a/ql/extractor/src/extractor.rs b/ql/extractor/src/extractor.rs index 8cdaff1b738..db280634ae5 100644 --- a/ql/extractor/src/extractor.rs +++ b/ql/extractor/src/extractor.rs @@ -1,161 +1,112 @@ +use crate::trap; use node_types::{EntryKind, Field, NodeTypeMap, Storage, TypeName}; -use std::borrow::Cow; use std::collections::BTreeMap as Map; use std::collections::BTreeSet as Set; use std::fmt; -use std::io::Write; use std::path::Path; use tracing::{error, info, span, Level}; use tree_sitter::{Language, Node, Parser, Range, Tree}; -pub struct TrapWriter { - /// The accumulated trap entries - trap_output: Vec, - /// A counter for generating fresh labels - counter: u32, - /// cache of global keys - global_keys: std::collections::HashMap, +pub fn populate_file(writer: &mut trap::Writer, absolute_path: &Path) -> trap::Label { + let (file_label, fresh) = + writer.global_id(&trap::full_id_for_file(&normalize_path(absolute_path))); + if fresh { + writer.add_tuple( + "files", + vec![ + trap::Arg::Label(file_label), + trap::Arg::String(normalize_path(absolute_path)), + ], + ); + populate_parent_folders(writer, file_label, absolute_path.parent()); + } + file_label } -pub fn new_trap_writer() -> TrapWriter { - TrapWriter { - counter: 0, - trap_output: Vec::new(), - global_keys: std::collections::HashMap::new(), +fn populate_empty_file(writer: &mut trap::Writer) -> trap::Label { + let (file_label, fresh) = writer.global_id("empty;sourcefile"); + if fresh { + writer.add_tuple( + "files", + vec![ + trap::Arg::Label(file_label), + trap::Arg::String("".to_string()), + ], + ); } + file_label } -impl TrapWriter { - /// Gets a label that will hold the unique ID of the passed string at import time. - /// This can be used for incrementally importable TRAP files -- use globally unique - /// strings to compute a unique ID for table tuples. - /// - /// Note: You probably want to make sure that the key strings that you use are disjoint - /// for disjoint column types; the standard way of doing this is to prefix (or append) - /// the column type name to the ID. Thus, you might identify methods in Java by the - /// full ID "methods_com.method.package.DeclaringClass.method(argumentList)". +pub fn populate_empty_location(writer: &mut trap::Writer) { + let file_label = populate_empty_file(writer); + location(writer, file_label, 0, 0, 0, 0); +} - fn fresh_id(&mut self) -> Label { - let label = Label(self.counter); - self.counter += 1; - self.trap_output.push(TrapEntry::FreshId(label)); - label - } - - fn global_id(&mut self, key: &str) -> (Label, bool) { - if let Some(label) = self.global_keys.get(key) { - return (*label, false); - } - let label = Label(self.counter); - self.counter += 1; - self.global_keys.insert(key.to_owned(), label); - self.trap_output - .push(TrapEntry::MapLabelToKey(label, key.to_owned())); - (label, true) - } - - fn add_tuple(&mut self, table_name: &str, args: Vec) { - self.trap_output - .push(TrapEntry::GenericTuple(table_name.to_owned(), args)) - } - - fn populate_file(&mut self, absolute_path: &Path) -> Label { - let (file_label, fresh) = self.global_id(&full_id_for_file(absolute_path)); - if fresh { - self.add_tuple( - "files", - vec![ - Arg::Label(file_label), - Arg::String(normalize_path(absolute_path)), - ], - ); - self.populate_parent_folders(file_label, absolute_path.parent()); - } - file_label - } - - fn populate_empty_file(&mut self) -> Label { - let (file_label, fresh) = self.global_id("empty;sourcefile"); - if fresh { - self.add_tuple( - "files", - vec![Arg::Label(file_label), Arg::String("".to_string())], - ); - } - file_label - } - - pub fn populate_empty_location(&mut self) { - let file_label = self.populate_empty_file(); - self.location(file_label, 0, 0, 0, 0); - } - - fn populate_parent_folders(&mut self, child_label: Label, path: Option<&Path>) { - let mut path = path; - let mut child_label = child_label; - loop { - match path { - None => break, - Some(folder) => { - let (folder_label, fresh) = self.global_id(&full_id_for_folder(folder)); - self.add_tuple( - "containerparent", - vec![Arg::Label(folder_label), Arg::Label(child_label)], +pub fn populate_parent_folders( + writer: &mut trap::Writer, + child_label: trap::Label, + path: Option<&Path>, +) { + let mut path = path; + let mut child_label = child_label; + loop { + match path { + None => break, + Some(folder) => { + let (folder_label, fresh) = + writer.global_id(&trap::full_id_for_folder(&normalize_path(folder))); + writer.add_tuple( + "containerparent", + vec![ + trap::Arg::Label(folder_label), + trap::Arg::Label(child_label), + ], + ); + if fresh { + writer.add_tuple( + "folders", + vec![ + trap::Arg::Label(folder_label), + trap::Arg::String(normalize_path(folder)), + ], ); - if fresh { - self.add_tuple( - "folders", - vec![ - Arg::Label(folder_label), - Arg::String(normalize_path(folder)), - ], - ); - path = folder.parent(); - child_label = folder_label; - } else { - break; - } + path = folder.parent(); + child_label = folder_label; + } else { + break; } } } } +} - fn location( - &mut self, - file_label: Label, - start_line: usize, - start_column: usize, - end_line: usize, - end_column: usize, - ) -> Label { - let (loc_label, fresh) = self.global_id(&format!( - "loc,{{{}}},{},{},{},{}", - file_label, start_line, start_column, end_line, end_column - )); - if fresh { - self.add_tuple( - "locations_default", - vec![ - Arg::Label(loc_label), - Arg::Label(file_label), - Arg::Int(start_line), - Arg::Int(start_column), - Arg::Int(end_line), - Arg::Int(end_column), - ], - ); - } - loc_label - } - - fn comment(&mut self, text: String) { - self.trap_output.push(TrapEntry::Comment(text)); - } - - pub fn output(self, writer: &mut dyn Write) -> std::io::Result<()> { - write!(writer, "{}", Program(self.trap_output)) +fn location( + writer: &mut trap::Writer, + file_label: trap::Label, + start_line: usize, + start_column: usize, + end_line: usize, + end_column: usize, +) -> trap::Label { + let (loc_label, fresh) = writer.global_id(&format!( + "loc,{{{}}},{},{},{},{}", + file_label, start_line, start_column, end_line, end_column + )); + if fresh { + writer.add_tuple( + "locations_default", + vec![ + trap::Arg::Label(loc_label), + trap::Arg::Label(file_label), + trap::Arg::Int(start_line), + trap::Arg::Int(start_column), + trap::Arg::Int(end_line), + trap::Arg::Int(end_column), + ], + ); } + loc_label } /// Extracts the source file at `path`, which is assumed to be canonicalized. @@ -163,71 +114,43 @@ pub fn extract( language: Language, language_prefix: &str, schema: &NodeTypeMap, - trap_writer: &mut TrapWriter, + trap_writer: &mut trap::Writer, path: &Path, source: &[u8], ranges: &[Range], ) -> std::io::Result<()> { + let path_str = format!("{}", path.display()); let span = span!( Level::TRACE, "extract", - file = %path.display() + file = %path_str ); let _enter = span.enter(); - info!("extracting: {}", path.display()); + info!("extracting: {}", path_str); let mut parser = Parser::new(); parser.set_language(language).unwrap(); parser.set_included_ranges(ranges).unwrap(); let tree = parser.parse(&source, None).expect("Failed to parse file"); - trap_writer.comment(format!("Auto-generated TRAP file for {}", path.display())); - let file_label = &trap_writer.populate_file(path); - let mut visitor = Visitor { + trap_writer.comment(format!("Auto-generated TRAP file for {}", path_str)); + let file_label = populate_file(trap_writer, path); + let mut visitor = Visitor::new( source, trap_writer, // TODO: should we handle path strings that are not valid UTF8 better? - path: format!("{}", path.display()), - file_label: *file_label, - toplevel_child_counter: 0, - stack: Vec::new(), + &path_str, + file_label, language_prefix, schema, - }; + ); traverse(&tree, &mut visitor); parser.reset(); Ok(()) } -/// Escapes a string for use in a TRAP key, by replacing special characters with -/// HTML entities. -fn escape_key<'a, S: Into>>(key: S) -> Cow<'a, str> { - fn needs_escaping(c: char) -> bool { - matches!(c, '&' | '{' | '}' | '"' | '@' | '#') - } - - let key = key.into(); - if key.contains(needs_escaping) { - let mut escaped = String::with_capacity(2 * key.len()); - for c in key.chars() { - match c { - '&' => escaped.push_str("&"), - '{' => escaped.push_str("{"), - '}' => escaped.push_str("}"), - '"' => escaped.push_str("""), - '@' => escaped.push_str("@"), - '#' => escaped.push_str("#"), - _ => escaped.push(c), - } - } - Cow::Owned(escaped) - } else { - key - } -} - /// Normalizes the path according the common CodeQL specification. Assumes that /// `path` has already been canonicalized using `std::fs::canonicalize`. fn normalize_path(path: &Path) -> String { @@ -267,34 +190,28 @@ fn normalize_path(path: &Path) -> String { } } -fn full_id_for_file(path: &Path) -> String { - format!("{};sourcefile", escape_key(&normalize_path(path))) -} - -fn full_id_for_folder(path: &Path) -> String { - format!("{};folder", escape_key(&normalize_path(path))) -} - struct ChildNode { field_name: Option<&'static str>, - label: Label, + label: trap::Label, type_name: TypeName, } struct Visitor<'a> { /// The file path of the source code (as string) - path: String, + path: &'a str, /// The label to use whenever we need to refer to the `@file` entity of this /// source file. - file_label: Label, + file_label: trap::Label, /// The source code as a UTF-8 byte array source: &'a [u8], - /// A TrapWriter to accumulate trap entries - trap_writer: &'a mut TrapWriter, + /// A trap::Writer to accumulate trap entries + trap_writer: &'a mut trap::Writer, /// A counter for top-level child nodes toplevel_child_counter: usize, - /// Language prefix - language_prefix: &'a str, + /// Language-specific name of the AST info table + ast_node_info_table_name: String, + /// Language-specific name of the tokeninfo table + tokeninfo_table_name: String, /// A lookup table from type name to node types schema: &'a NodeTypeMap, /// A stack for gathering information from child nodes. Whenever a node is @@ -303,27 +220,48 @@ struct Visitor<'a> { /// node the list containing the child data is popped from the stack and /// matched against the dbscheme for the node. If the expectations are met /// the corresponding row definitions are added to the trap_output. - stack: Vec<(Label, usize, Vec)>, + stack: Vec<(trap::Label, usize, Vec)>, } -impl Visitor<'_> { +impl<'a> Visitor<'a> { + fn new( + source: &'a [u8], + trap_writer: &'a mut trap::Writer, + path: &'a str, + file_label: trap::Label, + language_prefix: &str, + schema: &'a NodeTypeMap, + ) -> Visitor<'a> { + Visitor { + path, + file_label, + source, + trap_writer, + toplevel_child_counter: 0, + ast_node_info_table_name: format!("{}_ast_node_info", language_prefix), + tokeninfo_table_name: format!("{}_tokeninfo", language_prefix), + schema, + stack: Vec::new(), + } + } + fn record_parse_error( &mut self, error_message: String, full_error_message: String, - loc: Label, + loc: trap::Label, ) { error!("{}", full_error_message); let id = self.trap_writer.fresh_id(); self.trap_writer.add_tuple( "diagnostics", vec![ - Arg::Label(id), - Arg::Int(40), // severity 40 = error - Arg::String("parse_error".to_string()), - Arg::String(error_message), - Arg::String(full_error_message), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Int(40), // severity 40 = error + trap::Arg::String("parse_error".to_string()), + trap::Arg::String(error_message), + trap::Arg::String(full_error_message), + trap::Arg::Label(loc), ], ); } @@ -335,7 +273,8 @@ impl Visitor<'_> { node: Node, ) { let (start_line, start_column, end_line, end_column) = location_for(self.source, node); - let loc = self.trap_writer.location( + let loc = location( + self.trap_writer, self.file_label, start_line, start_column, @@ -374,7 +313,8 @@ impl Visitor<'_> { } let (id, _, child_nodes) = self.stack.pop().expect("Vistor: empty stack"); let (start_line, start_column, end_line, end_column) = location_for(self.source, node); - let loc = self.trap_writer.location( + let loc = location( + self.trap_writer, self.file_label, start_line, start_column, @@ -402,19 +342,19 @@ impl Visitor<'_> { match &table.kind { EntryKind::Token { kind_id, .. } => { self.trap_writer.add_tuple( - &format!("{}_ast_node_info", self.language_prefix), + &self.ast_node_info_table_name, vec![ - Arg::Label(id), - Arg::Label(parent_id), - Arg::Int(parent_index), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Label(parent_id), + trap::Arg::Int(parent_index), + trap::Arg::Label(loc), ], ); self.trap_writer.add_tuple( - &format!("{}_tokeninfo", self.language_prefix), + &self.tokeninfo_table_name, vec![ - Arg::Label(id), - Arg::Int(*kind_id), + trap::Arg::Label(id), + trap::Arg::Int(*kind_id), sliced_source_arg(self.source, node), ], ); @@ -425,15 +365,15 @@ impl Visitor<'_> { } => { if let Some(args) = self.complex_node(&node, fields, &child_nodes, id) { self.trap_writer.add_tuple( - &format!("{}_ast_node_info", self.language_prefix), + &self.ast_node_info_table_name, vec![ - Arg::Label(id), - Arg::Label(parent_id), - Arg::Int(parent_index), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Label(parent_id), + trap::Arg::Int(parent_index), + trap::Arg::Label(loc), ], ); - let mut all_args = vec![Arg::Label(id)]; + let mut all_args = vec![trap::Arg::Label(id)]; all_args.extend(args); self.trap_writer.add_tuple(table_name, all_args); } @@ -472,9 +412,9 @@ impl Visitor<'_> { node: &Node, fields: &[Field], child_nodes: &[ChildNode], - parent_id: Label, - ) -> Option> { - let mut map: Map<&Option, (&Field, Vec)> = Map::new(); + parent_id: trap::Label, + ) -> Option> { + let mut map: Map<&Option, (&Field, Vec)> = Map::new(); for field in fields { map.insert(&field.name, (field, Vec::new())); } @@ -488,9 +428,9 @@ impl Visitor<'_> { { // We can safely unwrap because type_matches checks the key is in the map. let (int_value, _) = int_mapping.get(&child_node.type_name.kind).unwrap(); - values.push(Arg::Int(*int_value)); + values.push(trap::Arg::Int(*int_value)); } else { - values.push(Arg::Label(child_node.label)); + values.push(trap::Arg::Label(child_node.label)); } } else if field.name.is_some() { let error_message = format!( @@ -569,9 +509,9 @@ impl Visitor<'_> { ); break; } - let mut args = vec![Arg::Label(parent_id)]; + let mut args = vec![trap::Arg::Label(parent_id)]; if *has_index { - args.push(Arg::Int(index)) + args.push(trap::Arg::Int(index)) } args.push(child_value.clone()); self.trap_writer.add_tuple(table_name, args); @@ -625,9 +565,9 @@ impl Visitor<'_> { } // Emit a slice of a source file as an Arg. -fn sliced_source_arg(source: &[u8], n: Node) -> Arg { +fn sliced_source_arg(source: &[u8], n: Node) -> trap::Arg { let range = n.byte_range(); - Arg::String(String::from_utf8_lossy(&source[range.start..range.end]).into_owned()) + trap::Arg::String(String::from_utf8_lossy(&source[range.start..range.end]).into_owned()) } // Emit a pair of `TrapEntry`s for the provided node, appropriately calibrated. @@ -699,59 +639,6 @@ fn traverse(tree: &Tree, visitor: &mut Visitor) { } } -pub struct Program(Vec); - -impl fmt::Display for Program { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut text = String::new(); - for trap_entry in &self.0 { - text.push_str(&format!("{}\n", trap_entry)); - } - write!(f, "{}", text) - } -} - -enum TrapEntry { - /// Maps the label to a fresh id, e.g. `#123=*`. - FreshId(Label), - /// Maps the label to a key, e.g. `#7=@"foo"`. - MapLabelToKey(Label, String), - /// foo_bar(arg*) - GenericTuple(String, Vec), - Comment(String), -} -impl fmt::Display for TrapEntry { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - TrapEntry::FreshId(label) => write!(f, "{}=*", label), - TrapEntry::MapLabelToKey(label, key) => { - write!(f, "{}=@\"{}\"", label, key.replace("\"", "\"\"")) - } - TrapEntry::GenericTuple(name, args) => { - write!(f, "{}(", name)?; - for (index, arg) in args.iter().enumerate() { - if index > 0 { - write!(f, ",")?; - } - write!(f, "{}", arg)?; - } - write!(f, ")") - } - TrapEntry::Comment(line) => write!(f, "// {}", line), - } - } -} - -#[derive(Debug, Copy, Clone)] -// Identifiers of the form #0, #1... -struct Label(u32); - -impl fmt::Display for Label { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "#{:x}", self.0) - } -} - // Numeric indices. #[derive(Debug, Copy, Clone)] struct Index(usize); @@ -761,69 +648,3 @@ impl fmt::Display for Index { write!(f, "{}", self.0) } } - -// Some untyped argument to a TrapEntry. -#[derive(Debug, Clone)] -enum Arg { - Label(Label), - Int(usize), - String(String), -} - -const MAX_STRLEN: usize = 1048576; - -impl fmt::Display for Arg { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Arg::Label(x) => write!(f, "{}", x), - Arg::Int(x) => write!(f, "{}", x), - Arg::String(x) => write!( - f, - "\"{}\"", - limit_string(x, MAX_STRLEN).replace("\"", "\"\"") - ), - } - } -} - -/// Limit the length (in bytes) of a string. If the string's length in bytes is -/// less than or equal to the limit then the entire string is returned. Otherwise -/// the string is sliced at the provided limit. If there is a multi-byte character -/// at the limit then the returned slice will be slightly shorter than the limit to -/// avoid splitting that multi-byte character. -fn limit_string(string: &str, max_size: usize) -> &str { - if string.len() <= max_size { - return string; - } - let p = string.as_bytes(); - let mut index = max_size; - // We want to clip the string at [max_size]; however, the character at that position - // may span several bytes. We need to find the first byte of the character. In UTF-8 - // encoded data any byte that matches the bit pattern 10XXXXXX is not a start byte. - // Therefore we decrement the index as long as there are bytes matching this pattern. - // This ensures we cut the string at the border between one character and another. - while index > 0 && (p[index] & 0b11000000) == 0b10000000 { - index -= 1; - } - &string[0..index] -} - -#[test] -fn limit_string_test() { - assert_eq!("hello", limit_string(&"hello world".to_owned(), 5)); - assert_eq!("hi ☹", limit_string(&"hi ☹☹".to_owned(), 6)); - assert_eq!("hi ", limit_string(&"hi ☹☹".to_owned(), 5)); -} - -#[test] -fn escape_key_test() { - assert_eq!("foo!", escape_key("foo!")); - assert_eq!("foo{}", escape_key("foo{}")); - assert_eq!("{}", escape_key("{}")); - assert_eq!("", escape_key("")); - assert_eq!("/path/to/foo.rb", escape_key("/path/to/foo.rb")); - assert_eq!( - "/path/to/foo&{}"@#.rb", - escape_key("/path/to/foo&{}\"@#.rb") - ); -} diff --git a/ql/extractor/src/main.rs b/ql/extractor/src/main.rs index 7f8ab87a7ca..9584304c430 100644 --- a/ql/extractor/src/main.rs +++ b/ql/extractor/src/main.rs @@ -1,49 +1,13 @@ mod extractor; +mod trap; extern crate num_cpus; -use flate2::write::GzEncoder; use rayon::prelude::*; use std::fs; -use std::io::{BufRead, BufWriter}; +use std::io::BufRead; use std::path::{Path, PathBuf}; -enum TrapCompression { - None, - Gzip, -} - -impl TrapCompression { - fn from_env() -> TrapCompression { - match std::env::var("CODEQL_QL_TRAP_COMPRESSION") { - Ok(method) => match TrapCompression::from_string(&method) { - Some(c) => c, - None => { - tracing::error!("Unknown compression method '{}'; using gzip.", &method); - TrapCompression::Gzip - } - }, - // Default compression method if the env var isn't set: - Err(_) => TrapCompression::Gzip, - } - } - - fn from_string(s: &str) -> Option { - match s.to_lowercase().as_ref() { - "none" => Some(TrapCompression::None), - "gzip" => Some(TrapCompression::Gzip), - _ => None, - } - } - - fn extension(&self) -> &str { - match self { - TrapCompression::None => "trap", - TrapCompression::Gzip => "trap.gz", - } - } -} - /** * Gets the number of threads the extractor should use, by reading the * CODEQL_THREADS environment variable and using it as described in the @@ -115,7 +79,7 @@ fn main() -> std::io::Result<()> { .value_of("output-dir") .expect("missing --output-dir"); let trap_dir = PathBuf::from(trap_dir); - let trap_compression = TrapCompression::from_env(); + let trap_compression = trap::Compression::from_env("CODEQL_QL_TRAP_COMPRESSION"); let file_list = matches.value_of("file-list").expect("missing --file-list"); let file_list = fs::File::open(file_list)?; @@ -140,7 +104,7 @@ fn main() -> std::io::Result<()> { let src_archive_file = path_for(&src_archive_dir, &path, ""); let source = std::fs::read(&path)?; let code_ranges = vec![]; - let mut trap_writer = extractor::new_trap_writer(); + let mut trap_writer = trap::Writer::new(); extractor::extract( language, "ql", @@ -152,33 +116,25 @@ fn main() -> std::io::Result<()> { )?; std::fs::create_dir_all(&src_archive_file.parent().unwrap())?; std::fs::copy(&path, &src_archive_file)?; - write_trap(&trap_dir, path, trap_writer, &trap_compression) + write_trap(&trap_dir, path, &trap_writer, trap_compression) }) .expect("failed to extract files"); let path = PathBuf::from("extras"); - let mut trap_writer = extractor::new_trap_writer(); - trap_writer.populate_empty_location(); - write_trap(&trap_dir, path, trap_writer, &trap_compression) + let mut trap_writer = trap::Writer::new(); + extractor::populate_empty_location(&mut trap_writer); + write_trap(&trap_dir, path, &trap_writer, trap_compression) } fn write_trap( trap_dir: &Path, path: PathBuf, - trap_writer: extractor::TrapWriter, - trap_compression: &TrapCompression, + trap_writer: &trap::Writer, + trap_compression: trap::Compression, ) -> std::io::Result<()> { let trap_file = path_for(trap_dir, &path, trap_compression.extension()); std::fs::create_dir_all(&trap_file.parent().unwrap())?; - let trap_file = std::fs::File::create(&trap_file)?; - let mut trap_file = BufWriter::new(trap_file); - match trap_compression { - TrapCompression::None => trap_writer.output(&mut trap_file), - TrapCompression::Gzip => { - let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast()); - trap_writer.output(&mut compressed_writer) - } - } + trap_writer.write_to_file(&trap_file, trap_compression) } fn path_for(dir: &Path, path: &Path, ext: &str) -> PathBuf { diff --git a/ql/extractor/src/trap.rs b/ql/extractor/src/trap.rs new file mode 100644 index 00000000000..35a9b69f255 --- /dev/null +++ b/ql/extractor/src/trap.rs @@ -0,0 +1,275 @@ +use std::borrow::Cow; +use std::fmt; +use std::io::{BufWriter, Write}; +use std::path::Path; + +use flate2::write::GzEncoder; + +pub struct Writer { + /// The accumulated trap entries + trap_output: Vec, + /// A counter for generating fresh labels + counter: u32, + /// cache of global keys + global_keys: std::collections::HashMap, +} + +impl Writer { + pub fn new() -> Writer { + Writer { + counter: 0, + trap_output: Vec::new(), + global_keys: std::collections::HashMap::new(), + } + } + + pub fn fresh_id(&mut self) -> Label { + let label = Label(self.counter); + self.counter += 1; + self.trap_output.push(Entry::FreshId(label)); + label + } + + /// Gets a label that will hold the unique ID of the passed string at import time. + /// This can be used for incrementally importable TRAP files -- use globally unique + /// strings to compute a unique ID for table tuples. + /// + /// Note: You probably want to make sure that the key strings that you use are disjoint + /// for disjoint column types; the standard way of doing this is to prefix (or append) + /// the column type name to the ID. Thus, you might identify methods in Java by the + /// full ID "methods_com.method.package.DeclaringClass.method(argumentList)". + pub fn global_id(&mut self, key: &str) -> (Label, bool) { + if let Some(label) = self.global_keys.get(key) { + return (*label, false); + } + let label = Label(self.counter); + self.counter += 1; + self.global_keys.insert(key.to_owned(), label); + self.trap_output + .push(Entry::MapLabelToKey(label, key.to_owned())); + (label, true) + } + + pub fn add_tuple(&mut self, table_name: &str, args: Vec) { + self.trap_output + .push(Entry::GenericTuple(table_name.to_owned(), args)) + } + + pub fn comment(&mut self, text: String) { + self.trap_output.push(Entry::Comment(text)); + } + + pub fn write_to_file(&self, path: &Path, compression: Compression) -> std::io::Result<()> { + let trap_file = std::fs::File::create(path)?; + match compression { + Compression::None => { + let mut trap_file = BufWriter::new(trap_file); + self.write_trap_entries(&mut trap_file) + } + Compression::Gzip => { + let trap_file = GzEncoder::new(trap_file, flate2::Compression::fast()); + let mut trap_file = BufWriter::new(trap_file); + self.write_trap_entries(&mut trap_file) + } + } + } + + fn write_trap_entries(&self, file: &mut W) -> std::io::Result<()> { + for trap_entry in &self.trap_output { + writeln!(file, "{}", trap_entry)?; + } + std::io::Result::Ok(()) + } +} + +pub enum Entry { + /// Maps the label to a fresh id, e.g. `#123=*`. + FreshId(Label), + /// Maps the label to a key, e.g. `#7=@"foo"`. + MapLabelToKey(Label, String), + /// foo_bar(arg*) + GenericTuple(String, Vec), + Comment(String), +} + +impl fmt::Display for Entry { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Entry::FreshId(label) => write!(f, "{}=*", label), + Entry::MapLabelToKey(label, key) => { + write!(f, "{}=@\"{}\"", label, key.replace("\"", "\"\"")) + } + Entry::GenericTuple(name, args) => { + write!(f, "{}(", name)?; + for (index, arg) in args.iter().enumerate() { + if index > 0 { + write!(f, ",")?; + } + write!(f, "{}", arg)?; + } + write!(f, ")") + } + Entry::Comment(line) => write!(f, "// {}", line), + } + } +} + +#[derive(Debug, Copy, Clone)] +// Identifiers of the form #0, #1... +pub struct Label(u32); + +impl fmt::Display for Label { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "#{:x}", self.0) + } +} + +// Some untyped argument to a TrapEntry. +#[derive(Debug, Clone)] +pub enum Arg { + Label(Label), + Int(usize), + String(String), +} + +const MAX_STRLEN: usize = 1048576; + +impl fmt::Display for Arg { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Arg::Label(x) => write!(f, "{}", x), + Arg::Int(x) => write!(f, "{}", x), + Arg::String(x) => write!( + f, + "\"{}\"", + limit_string(x, MAX_STRLEN).replace("\"", "\"\"") + ), + } + } +} + +pub struct Program(Vec); + +impl fmt::Display for Program { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut text = String::new(); + for trap_entry in &self.0 { + text.push_str(&format!("{}\n", trap_entry)); + } + write!(f, "{}", text) + } +} + +pub fn full_id_for_file(normalized_path: &str) -> String { + format!("{};sourcefile", escape_key(normalized_path)) +} + +pub fn full_id_for_folder(normalized_path: &str) -> String { + format!("{};folder", escape_key(normalized_path)) +} + +/// Escapes a string for use in a TRAP key, by replacing special characters with +/// HTML entities. +fn escape_key<'a, S: Into>>(key: S) -> Cow<'a, str> { + fn needs_escaping(c: char) -> bool { + matches!(c, '&' | '{' | '}' | '"' | '@' | '#') + } + + let key = key.into(); + if key.contains(needs_escaping) { + let mut escaped = String::with_capacity(2 * key.len()); + for c in key.chars() { + match c { + '&' => escaped.push_str("&"), + '{' => escaped.push_str("{"), + '}' => escaped.push_str("}"), + '"' => escaped.push_str("""), + '@' => escaped.push_str("@"), + '#' => escaped.push_str("#"), + _ => escaped.push(c), + } + } + Cow::Owned(escaped) + } else { + key + } +} + +/// Limit the length (in bytes) of a string. If the string's length in bytes is +/// less than or equal to the limit then the entire string is returned. Otherwise +/// the string is sliced at the provided limit. If there is a multi-byte character +/// at the limit then the returned slice will be slightly shorter than the limit to +/// avoid splitting that multi-byte character. +fn limit_string(string: &str, max_size: usize) -> &str { + if string.len() <= max_size { + return string; + } + let p = string.as_bytes(); + let mut index = max_size; + // We want to clip the string at [max_size]; however, the character at that position + // may span several bytes. We need to find the first byte of the character. In UTF-8 + // encoded data any byte that matches the bit pattern 10XXXXXX is not a start byte. + // Therefore we decrement the index as long as there are bytes matching this pattern. + // This ensures we cut the string at the border between one character and another. + while index > 0 && (p[index] & 0b11000000) == 0b10000000 { + index -= 1; + } + &string[0..index] +} + +#[derive(Clone, Copy)] +pub enum Compression { + None, + Gzip, +} + +impl Compression { + pub fn from_env(var_name: &str) -> Compression { + match std::env::var(var_name) { + Ok(method) => match Compression::from_string(&method) { + Some(c) => c, + None => { + tracing::error!("Unknown compression method '{}'; using gzip.", &method); + Compression::Gzip + } + }, + // Default compression method if the env var isn't set: + Err(_) => Compression::Gzip, + } + } + + pub fn from_string(s: &str) -> Option { + match s.to_lowercase().as_ref() { + "none" => Some(Compression::None), + "gzip" => Some(Compression::Gzip), + _ => None, + } + } + + pub fn extension(&self) -> &str { + match self { + Compression::None => "trap", + Compression::Gzip => "trap.gz", + } + } +} + +#[test] +fn limit_string_test() { + assert_eq!("hello", limit_string(&"hello world".to_owned(), 5)); + assert_eq!("hi ☹", limit_string(&"hi ☹☹".to_owned(), 6)); + assert_eq!("hi ", limit_string(&"hi ☹☹".to_owned(), 5)); +} + +#[test] +fn escape_key_test() { + assert_eq!("foo!", escape_key("foo!")); + assert_eq!("foo{}", escape_key("foo{}")); + assert_eq!("{}", escape_key("{}")); + assert_eq!("", escape_key("")); + assert_eq!("/path/to/foo.rb", escape_key("/path/to/foo.rb")); + assert_eq!( + "/path/to/foo&{}"@#.rb", + escape_key("/path/to/foo&{}\"@#.rb") + ); +} diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index fa551b0de83..e399128c09a 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -21,11 +21,13 @@ private string stringIndexedMember(string name, string index) { class AstNode extends TAstNode { string toString() { result = this.getAPrimaryQlClass() } - /** - * Gets the location of the AST node. - */ + /** Gets the location of the AST node. */ cached - Location getLocation() { + Location getLocation() { result = this.getFullLocation() } // overriden in some subclasses + + /** Gets the location that spans the entire AST node. */ + cached + final Location getFullLocation() { exists(QL::AstNode node | not node instanceof QL::ParExpr | node = toQL(this) and result = node.getLocation() @@ -434,6 +436,8 @@ class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclarati ClasslessPredicate() { this = TClasslessPredicate(pred) } + override Location getLocation() { result = pred.getName().getLocation() } + /** * Gets the aliased value if this predicate is an alias * E.g. for `predicate foo = Module::bar/2;` gets `Module::bar/2`. @@ -484,6 +488,8 @@ class ClassPredicate extends TClassPredicate, Predicate { ClassPredicate() { this = TClassPredicate(pred) } + override Location getLocation() { result = pred.getName().getLocation() } + override string getName() { result = pred.getName().getValue() } override Formula getBody() { toQL(result) = pred.getChild(_).(QL::Body).getChild() } @@ -682,7 +688,7 @@ class TypeExpr extends TType, TypeRef { // resolve type resolveTypeExpr(this, result) or - // if it resolves to a module + // if it resolves to a module, exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType()) } @@ -701,6 +707,8 @@ class Module extends TModule, ModuleDeclaration { Module() { this = TModule(mod) } + override Location getLocation() { result = mod.getName().getLocation() } + override string getAPrimaryQlClass() { result = "Module" } override string getName() { result = mod.getName().getChild().getValue() } @@ -784,6 +792,8 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration { Class() { this = TClass(cls) } + override Location getLocation() { result = cls.getName().getLocation() } + override string getAPrimaryQlClass() { result = "Class" } override string getName() { result = cls.getName().getValue() } @@ -871,6 +881,8 @@ class NewType extends TNewType, TypeDeclaration, ModuleDeclaration { NewType() { this = TNewType(type) } + override Location getLocation() { result = type.getName().getLocation() } + override string getName() { result = type.getName().getValue() } override string getAPrimaryQlClass() { result = "NewType" } @@ -896,6 +908,8 @@ class NewTypeBranch extends TNewTypeBranch, Predicate, TypeDeclaration { NewTypeBranch() { this = TNewTypeBranch(branch) } + override Location getLocation() { result = branch.getName().getLocation() } + override string getAPrimaryQlClass() { result = "NewTypeBranch" } override string getName() { result = branch.getName().getValue() } @@ -1167,7 +1181,7 @@ class Import extends TImport, ModuleMember, TypeRef { */ string getImportString() { exists(string selec | - not exists(getSelectionName(_)) and selec = "" + not exists(this.getSelectionName(_)) and selec = "" or selec = "::" + strictconcat(int i, string q | q = this.getSelectionName(i) | q, "::" order by i) @@ -2217,9 +2231,7 @@ class ModuleExpr extends TModuleExpr, TypeRef { or not exists(me.getName()) and result = me.getChild().(QL::SimpleId).getValue() or - exists(QL::ModuleInstantiation instantiation | instantiation.getParent() = me | - result = instantiation.getName().getChild().getValue() - ) + result = me.getAFieldOrChild().(QL::ModuleInstantiation).getName().getChild().getValue() } /** @@ -2254,9 +2266,7 @@ class ModuleExpr extends TModuleExpr, TypeRef { * The result is either a `PredicateExpr` or a `TypeExpr`. */ SignatureExpr getArgument(int i) { - exists(QL::ModuleInstantiation instantiation | instantiation.getParent() = me | - result.toQL() = instantiation.getChild(i) - ) + result.toQL() = me.getAFieldOrChild().(QL::ModuleInstantiation).getChild(i) } } diff --git a/ql/ql/src/codeql_ql/ast/internal/Module.qll b/ql/ql/src/codeql_ql/ast/internal/Module.qll index b487c98cc7e..91a5888ac12 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Module.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Module.qll @@ -218,6 +218,20 @@ private module Cached { not exists(me.(ModuleExpr).getQualifier()) and exists(ContainerOrModule enclosing, string name | resolveModuleRefHelper(me, enclosing, name) | definesModule(enclosing, name, m, _) + ) and + ( + not me instanceof TypeExpr + or + // remove some spurious results that can happen with `TypeExpr` + me instanceof TypeExpr and + m instanceof Module_ and // TypeExpr can only resolve to a Module, and only in some scenarios + ( + // only possible if this is inside a moduleInstantiation. + me = any(ModuleExpr mod).getArgument(_).asType() + or + // or if it's a parameter to a parameterized module + me = any(SignatureExpr sig, Module mod | mod.hasParameter(_, _, sig) | sig).asType() + ) ) or exists(FileOrModule mid | @@ -229,7 +243,8 @@ private module Cached { pragma[noinline] private predicate resolveModuleRefHelper(TypeRef me, ContainerOrModule enclosing, string name) { enclosing = getEnclosingModule(me).getEnclosing*() and - name = [me.(ModuleExpr).getName(), me.(TypeExpr).getClassName()] + name = [me.(ModuleExpr).getName(), me.(TypeExpr).getClassName()] and + (not me instanceof ModuleExpr or not enclosing instanceof Folder_) // module expressions are not imports, so they can't resolve to a file (which is contained in a folder). } } @@ -248,7 +263,7 @@ boolean getPublicBool(AstNode n) { /** * Holds if `container` defines module `m` with name `name`. * - * `m` may be defined either directly or through `import`s. + * `m` may be defined either directly or through imports. */ private predicate definesModule( ContainerOrModule container, string name, ContainerOrModule m, boolean public @@ -332,7 +347,19 @@ module ModConsistency { * } */ - query predicate noName(Module mod) { not exists(mod.getName()) } + query predicate noName(AstNode mod) { + mod instanceof Module and + not exists(mod.(Module).getName()) + or + mod instanceof ModuleExpr and + not exists(mod.(ModuleExpr).getName()) + } - query predicate nonUniqueName(Module mod) { count(mod.getName()) >= 2 } + query predicate nonUniqueName(AstNode mod) { + mod instanceof Module and + count(mod.(Module).getName()) >= 2 + or + mod instanceof ModuleExpr and + count(mod.(ModuleExpr).getName()) >= 2 + } } diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll index eb7e298b7cd..d419534788b 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -31,7 +31,8 @@ private predicate definesPredicate( name = alias.getName() and resolvePredicateExpr(alias.getAlias(), p) and public = getPublicBool(alias) and - arity = alias.getArity() + arity = alias.getArity() and + arity = p.getArity() ) ) } @@ -48,15 +49,18 @@ private module Cached { m = pe.getQualifier().getResolvedModule() and public = true | - definesPredicate(m, pe.getName(), p.getArity(), p, public) + definesPredicate(m, pe.getName(), p.getArity(), p, public) and + p.getArity() = pe.getArity() ) } private predicate resolvePredicateCall(PredicateCall pc, PredicateOrBuiltin p) { + // calls to class methods exists(Class c, ClassType t | c = pc.getParent*() and t = c.getType() and - p = t.getClassPredicate(pc.getPredicateName(), pc.getNumberOfArguments()) + p = t.getClassPredicate(pc.getPredicateName(), pc.getNumberOfArguments()) and + not exists(pc.getQualifier()) // no module qualifier, because then it's not a call to a class method. ) or exists(FileOrModule m, boolean public | @@ -85,22 +89,47 @@ private module Cached { ) } + /** + * Holds if `mc` is a `this.method()` call to a predicate defined in the same class. + * helps avoid spuriously resolving to predicates in super-classes. + */ + private predicate resolveSelfClassCalls(MemberCall mc, PredicateOrBuiltin p) { + exists(Class c | + mc.getBase() instanceof ThisAccess and + c = mc.getEnclosingPredicate().getParent() and + p = c.getClassPredicate(mc.getMemberName()) and + p.getArity() = mc.getNumberOfArguments() + ) + } + private predicate resolveMemberCall(MemberCall mc, PredicateOrBuiltin p) { + resolveSelfClassCalls(mc, p) + or + not resolveSelfClassCalls(mc, _) and exists(Type t | t = mc.getBase().getType() and p = t.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments()) ) or // super calls - and `this.method()` calls in charpreds. (Basically: in charpreds there is no difference between super and this.) - exists(AstNode sup, ClassType type, Type supertype | + exists(AstNode sup, Type supertype | sup instanceof Super or sup.(ThisAccess).getEnclosingPredicate() instanceof CharPred | mc.getBase() = sup and - sup.getEnclosingPredicate().getParent().(Class).getType() = type and - supertype in [type.getASuperType(), type.getAnInstanceofType()] and - p = supertype.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments()) + p = supertype.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments()) and + ( + // super.method() + not exists(mc.getSuperType()) and + exists(ClassType type | + sup.getEnclosingPredicate().getParent().(Class).getType() = type and + supertype in [type.getASuperType(), type.getAnInstanceofType()] + ) + or + // Class.super.method() + supertype = mc.getSuperType().getResolvedType() + ) ) } @@ -172,24 +201,29 @@ module PredConsistency { } query predicate multipleResolvePredicateExpr(PredicateExpr pe, int c, ClasslessPredicate p) { - c = strictcount(ClasslessPredicate p0 | resolvePredicateExpr(pe, p0)) and + c = + strictcount(ClasslessPredicate p0 | + resolvePredicateExpr(pe, p0) and + // aliases are expected to resolve to multiple. + not exists(p0.getAlias()) + ) and c > 1 and resolvePredicateExpr(pe, p) } - // This can happen with parametarized modules - /* - * query predicate multipleResolveCall(Call call, int c, PredicateOrBuiltin p) { - * c = - * strictcount(PredicateOrBuiltin p0 | - * resolveCall(call, p0) and - * // aliases are expected to resolve to multiple. - * not exists(p0.(ClasslessPredicate).getAlias()) and - * // overridden predicates may have multiple targets - * not p0.(ClassPredicate).isOverride() - * ) and - * c > 1 and - * resolveCall(call, p) - * } - */ + query predicate multipleResolveCall(Call call, int c, PredicateOrBuiltin p) { + c = + strictcount(PredicateOrBuiltin p0 | + resolveCall(call, p0) and + // aliases are expected to resolve to multiple. + not exists(p0.(ClasslessPredicate).getAlias()) and + // overridden predicates may have multiple targets + not p0.(ClassPredicate).isOverride() and + not p0 instanceof Relation // <- DB relations resolve to both a relation and a predicate. + ) and + c > 1 and + resolveCall(call, p) and + // parameterized modules are expected to resolve to multiple. + not exists(Predicate sig | not exists(sig.getBody()) and resolveCall(call, sig)) } +} diff --git a/ql/ql/src/codeql_ql/dataflow/DataFlow.qll b/ql/ql/src/codeql_ql/dataflow/DataFlow.qll index da8bc1da837..c9043416bae 100644 --- a/ql/ql/src/codeql_ql/dataflow/DataFlow.qll +++ b/ql/ql/src/codeql_ql/dataflow/DataFlow.qll @@ -204,7 +204,7 @@ class SuperNode extends LocalFlow::TSuperNode { Node getANode() { LocalFlow::getRepr(result) = repr } /** Gets an AST node from any of the nodes in this super node. */ - AstNode asAstNode() { result = getANode().asAstNode() } + AstNode asAstNode() { result = this.getANode().asAstNode() } /** * Gets a single node from this super node. @@ -214,23 +214,25 @@ class SuperNode extends LocalFlow::TSuperNode { * - An `AstNodeNode` is preferred over other nodes. * - A node occurring earlier is preferred over one occurring later. */ - Node getArbitraryRepr() { result = min(Node n | n = getANode() | n order by getInternalId(n)) } + Node getArbitraryRepr() { + result = min(Node n | n = this.getANode() | n order by getInternalId(n)) + } /** * Gets the predicate containing all nodes that are part of this super node. */ - Predicate getEnclosingPredicate() { result = getANode().getEnclosingPredicate() } + Predicate getEnclosingPredicate() { result = this.getANode().getEnclosingPredicate() } /** Gets a string representation of this super node. */ string toString() { exists(int c | - c = strictcount(getANode()) and - result = "Super node of " + c + " nodes in " + getEnclosingPredicate().getName() + c = strictcount(this.getANode()) and + result = "Super node of " + c + " nodes in " + this.getEnclosingPredicate().getName() ) } /** Gets the location of an arbitrary node in this super node. */ - Location getLocation() { result = getArbitraryRepr().getLocation() } + Location getLocation() { result = this.getArbitraryRepr().getLocation() } /** Gets any member call whose receiver is in the same super node. */ MemberCall getALocalMemberCall() { superNode(result.getBase()) = this } @@ -287,7 +289,7 @@ class SuperNode extends LocalFlow::TSuperNode { cached private string getAStringValue(Tracker t) { t.start() and - result = asAstNode().(String).getValue() + result = this.asAstNode().(String).getValue() or exists(SuperNode pred, Tracker t2 | this = pred.track(t2, t) and diff --git a/ql/ql/src/codeql_ql/style/TypoDatabase.qll b/ql/ql/src/codeql_ql/style/TypoDatabase.qll index aad43d9d0cc..fadc1b8af75 100644 --- a/ql/ql/src/codeql_ql/style/TypoDatabase.qll +++ b/ql/ql/src/codeql_ql/style/TypoDatabase.qll @@ -5793,6 +5793,8 @@ predicate typos(string wrong, string right) { or wrong = "paramters" and right = "parameters" or + wrong = "parametarized" and right = "parameterized" + or wrong = "paranthesis" and right = "parenthesis" or wrong = "paraphenalia" and right = "paraphernalia" diff --git a/ql/ql/src/queries/bugs/InconsistentDeprecation.ql b/ql/ql/src/queries/bugs/InconsistentDeprecation.ql new file mode 100644 index 00000000000..366d2daa4f5 --- /dev/null +++ b/ql/ql/src/queries/bugs/InconsistentDeprecation.ql @@ -0,0 +1,24 @@ +/** + * @name Inconsistent deprecation + * @description A deprecated predicate that overrides a non-deprecated predicate is an indication that the super-predicate should be deprecated. + * @kind problem + * @problem.severity warning + * @id ql/inconsistent-deprecation + * @tags correctness + * maintanability + * @precision very-high + */ + +import ql + +predicate overrides(ClassPredicate sub, ClassPredicate sup, string description, string overrides) { + sub.overrides(sup) and description = "predicate" and overrides = "predicate" +} + +from AstNode sub, AstNode sup, string description, string overrides +where + overrides(sub, sup, description, overrides) and + sub.hasAnnotation("deprecated") and + not sup.hasAnnotation("deprecated") +select sub, "This deprecated " + description + " overrides $@. Consider deprecating both.", sup, + "a non-deprecated " + overrides diff --git a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql index 7f95fec935e..8691aa2168c 100644 --- a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql +++ b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql @@ -22,6 +22,11 @@ where or PredConsistency::noResolvePredicateExpr(node) and msg = "PredConsistency::noResolvePredicateExpr" or + PredConsistency::multipleResolveCall(node, _, _) and msg = "PredConsistency::multipleResolveCall" + or + PredConsistency::multipleResolvePredicateExpr(node, _, _) and + msg = "PredConsistency::multipleResolvePredicateExpr" + or TypeConsistency::exprNoType(node) and msg = "TypeConsistency::exprNoType" or TypeConsistency::varDefNoType(node) and msg = "TypeConsistency::varDefNoType" diff --git a/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql b/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql index 2317cdc80c4..c26b47554fe 100644 --- a/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql +++ b/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql @@ -119,12 +119,14 @@ class EffectiveDisjunction extends AstNode { * Holds if `disj` only uses `var` in one of its branches. */ pragma[noinline] -predicate onlyUseInOneBranch(EffectiveDisjunction disj, VarDef var) { +predicate onlyUseInOneBranch(EffectiveDisjunction disj, VarDef var, AstNode notBoundIn) { alwaysBindsVar(var, disj.getLeft()) and - not alwaysBindsVar(var, disj.getRight()) + not alwaysBindsVar(var, disj.getRight()) and + notBoundIn = disj.getRight() or not alwaysBindsVar(var, disj.getLeft()) and - alwaysBindsVar(var, disj.getRight()) + alwaysBindsVar(var, disj.getRight()) and + notBoundIn = disj.getLeft() } /** @@ -170,7 +172,7 @@ class EffectiveConjunction extends AstNode { predicate varIsAlwaysBound(VarDef var, AstNode node) { // base case alwaysBindsVar(var, node) and - onlyUseInOneBranch(_, var) // <- manual magic + onlyUseInOneBranch(_, var, _) // <- manual magic or // recursive cases exists(AstNode parent | node.getParent() = parent | varIsAlwaysBound(var, parent)) @@ -194,8 +196,8 @@ predicate varIsAlwaysBound(VarDef var, AstNode node) { * Holds if `disj` only uses `var` in one of its branches. * And we should report it as being a bad thing. */ -predicate badDisjunction(EffectiveDisjunction disj, VarDef var) { - onlyUseInOneBranch(disj, var) and +predicate badDisjunction(EffectiveDisjunction disj, VarDef var, AstNode notBoundIn) { + onlyUseInOneBranch(disj, var, notBoundIn) and // it's fine if it's always bound further up not varIsAlwaysBound(var, disj) and // none() on one side makes everything fine. (this happens, it's a type-system hack) @@ -213,9 +215,9 @@ predicate badDisjunction(EffectiveDisjunction disj, VarDef var) { not isTinyAssignment(disj.getAnOperand()) } -from EffectiveDisjunction disj, VarDef var, string type +from EffectiveDisjunction disj, VarDef var, AstNode notBoundIn, string type where - badDisjunction(disj, var) and - not badDisjunction(disj.getParent(), var) and // avoid duplicate reporting of the same error + badDisjunction(disj, var, notBoundIn) and + not badDisjunction(disj.getParent(), var, _) and // avoid duplicate reporting of the same error if var.getParent() instanceof FieldDecl then type = "field" else type = "variable" select disj, "The $@ is only used in one side of disjunct.", var, type + " " + var.getName() diff --git a/ql/ql/src/queries/reports/FrameworkCoverage.ql b/ql/ql/src/queries/reports/FrameworkCoverage.ql index 7f5eb7f5310..f394a5a0091 100644 --- a/ql/ql/src/queries/reports/FrameworkCoverage.ql +++ b/ql/ql/src/queries/reports/FrameworkCoverage.ql @@ -18,11 +18,13 @@ class PackageImportCall extends PredicateCall { PackageImportCall() { this.getQualifier().getName() = ["API", "DataFlow"] and this.getPredicateName() = ["moduleImport", "moduleMember"] and - not isExcludedFile(getLocation().getFile()) + not isExcludedFile(this.getLocation().getFile()) } /** Gets the name of a package referenced by this call */ - string getAPackageName() { result = DataFlow::superNode(getArgument(0)).getAStringValueNoCall() } + string getAPackageName() { + result = DataFlow::superNode(this.getArgument(0)).getAStringValueNoCall() + } } /** Gets a reference to `package` or any transitive member thereof. */ diff --git a/ql/ql/src/queries/style/LibraryAnnotation.ql b/ql/ql/src/queries/style/LibraryAnnotation.ql index cf4a4bc8232..99b80f97fb9 100644 --- a/ql/ql/src/queries/style/LibraryAnnotation.ql +++ b/ql/ql/src/queries/style/LibraryAnnotation.ql @@ -10,6 +10,9 @@ import ql -from AstNode n -where n.hasAnnotation("library") and not n.hasAnnotation("deprecated") +from AstNode n, Annotation library +where + library = n.getAnAnnotation() and + library.getName() = "library" and + not n.hasAnnotation("deprecated") select n, "Don't use the library annotation." diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql new file mode 100644 index 00000000000..c2b1e80fe53 --- /dev/null +++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql @@ -0,0 +1,94 @@ +/** + * @name Missing QLDoc for parameter + * @description It is suspicious when a predicate has a parameter that is + * unmentioned in the qldoc, and the qldoc contains a + * code-fragment mentioning a non-parameter. + * @kind problem + * @problem.severity warning + * @precision high + * @id ql/missing-parameter-qldoc + * @tags maintainability + */ + +import ql + +/** + * Gets a fragment enclosed in backticks (`) from a QLDoc of the predicate `p`. + * Skips code-blocks that are triple-quoted. + */ +private string getACodeFragment(Predicate p) { + result = p.getQLDoc().getContents().regexpFind("`([^`]*)`(?!`)", _, _) +} + +/** Gets a parameter name from `p`. */ +private string getAParameterName(Predicate p) { result = p.getParameter(_).getName() } + +/** + * Gets the name of a parameter of `p` that is mentioned in any way in the QLDoc of `p`. + * Also includes names that are mentioned in non-code fragments. + */ +private string getADocumentedParameter(Predicate p) { + result = p.getQLDoc().getContents().regexpFind("\\b\\w[\\w_]*\\b", _, _) and + result.toLowerCase() = getAParameterName(p).toLowerCase() +} + +/** + * Get something that looks like a parameter name from the QLDoc, + * but which is not a parameter of `p`. + */ +private string getAMentionedNonParameter(Predicate p) { + exists(string fragment | fragment = getACodeFragment(p) | + result = fragment.substring(1, fragment.length() - 1) + ) and + result.regexpMatch("^[a-z]\\w+$") and + not result.toLowerCase() = getAParameterName(p).toLowerCase() and + // keywords + not result = + [ + "true", "false", "NaN", "this", "forall", "exists", "null", "break", "return", "not", "if", + "then", "else", "import" + ] and + not result = any(Aggregate a).getKind() and // min, max, sum, count, etc. + not result = getMentionedThings(p.getLocation().getFile()) and + not result = any(Annotation a).getName() and // private, final, etc. + not result = any(Annotation a).getArgs(_).getValue() and // noinline, etc. + // variables inside the predicate are also fine + not result = any(VarDecl var | var.getEnclosingPredicate() = p).getName() +} + +/** Gets the names of all predicates and string constants that are mentioned in `file`. */ +pragma[noinline] +private string getMentionedThings(File file) { + // predicates get mentioned all the time, it's fine. + result = any(Predicate pred | pred.getLocation().getFile() = file).getName() or + result = any(Call c | c.getLocation().getFile() = file).getTarget().getName() or + result = any(String s | s.getLocation().getFile() = file).getValue() +} + +/** Gets a parameter name from `p` that is not mentioned in the qldoc. */ +private string getAnUndocumentedParameter(Predicate p) { + result = getAParameterName(p) and + not result.toLowerCase() = getADocumentedParameter(p).toLowerCase() and + not result = ["config", "conf", "cfg", "t", "t2"] and // DataFlow configurations / type-trackers are often undocumented, and that's fine. + not ( + // "the given" often refers to the first parameter. + p.getQLDoc().getContents().regexpMatch("(?s).*\\bthe given\\b.*") and + result = p.getParameter(0).getName() + ) +} + +/** Gets the one string containing the undocumented parameters from `p` */ +private string getUndocumentedParameters(Predicate p) { + result = strictconcat(string param | param = getAnUndocumentedParameter(p) | param, ", or ") +} + +/** Gets the parameter-like names mentioned in the QLDoc of `p` that are not parameters. */ +private string getMentionedNonParameters(Predicate p) { + result = strictconcat(string param | param = getAMentionedNonParameter(p) | param, ", and ") +} + +from Predicate p +where not p.getLocation().getFile().getBaseName() in ["Aliases.qll", "TreeSitter.qll"] // these are OK +select p, + "The QLDoc has no documentation for " + getUndocumentedParameters(p) + ", but the QLDoc mentions " + + getMentionedNonParameters(p) diff --git a/ql/ql/src/queries/style/UseInstanceofExtension.ql b/ql/ql/src/queries/style/UseInstanceofExtension.ql index 2e7b8e3de80..da27e5cbb47 100644 --- a/ql/ql/src/queries/style/UseInstanceofExtension.ql +++ b/ql/ql/src/queries/style/UseInstanceofExtension.ql @@ -18,4 +18,4 @@ where usesFieldBasedInstanceof(c, any(TypeExpr te | te.getResolvedType() = type), _, _) ) and message = "consider defining $@ as non-extending subtype of $@" -select c, message, c, c.getName(), type, type.getName() +select c, message, c, c.getName(), type.getDeclaration(), type.getName() diff --git a/ql/ql/test/callgraph/MultiResolve.qll b/ql/ql/test/callgraph/MultiResolve.qll new file mode 100644 index 00000000000..dce88d01689 --- /dev/null +++ b/ql/ql/test/callgraph/MultiResolve.qll @@ -0,0 +1,58 @@ +predicate foo(int a, int b) { + a = 2 and + b = 2 +} + +predicate foo(int a, int b, int c) { + a = 2 and + b = 2 and + c = 2 +} + +predicate myFoo = foo/2; + +predicate test(int i) { myFoo(i, i) } // <- should only resolve to the `foo` with 2 arguments (and the `myFoo` alias). + +module MyMod { + predicate bar() { any() } + + class Bar extends int { + Bar() { this = 42 } + + predicate bar() { + MyMod::bar() // <- should resolve to the module's predicate. + } + } +} + +class Super1 extends int { + Super1() { this = 42 } + + predicate foo() { any() } +} + +class Super2 extends int { + Super2() { this = 42 } + + predicate foo() { none() } +} + +class Sub extends Super1, Super2 { + override predicate foo() { Super1.super.foo() } // <- should resolve to Super1::foo() +} + +module Foo { + predicate foo() { any() } +} + +predicate test() { + Foo::foo() // <- should resolve to `foo` from the module above, and not from the `Foo.qll` file. +} + +class Sub2 extends Super1, Super2 { + override predicate foo() { Super2.super.foo() } // <- should resolve to Super2::foo() + + predicate test() { + this.foo() // <- should resolve to only the above `foo` predicate, but currently it resolves to that, and all the overrides [INCONSISTENCY] + } +} diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected index 97c84034602..7b86b05953b 100644 --- a/ql/ql/test/callgraph/callgraph.expected +++ b/ql/ql/test/callgraph/callgraph.expected @@ -1,47 +1,53 @@ getTarget -| Bar.qll:5:38:5:47 | PredicateCall | Bar.qll:8:3:8:31 | ClasslessPredicate snapshot | -| Bar.qll:24:12:24:32 | MemberCall | Bar.qll:19:3:19:47 | ClassPredicate getParameter | -| Bar.qll:26:12:26:31 | MemberCall | Bar.qll:19:3:19:47 | ClassPredicate getParameter | -| Bar.qll:30:12:30:32 | MemberCall | Bar.qll:19:3:19:47 | ClassPredicate getParameter | -| Baz.qll:8:18:8:44 | MemberCall | Baz.qll:4:3:4:37 | ClassPredicate getImportedPath | -| Foo.qll:5:26:5:30 | PredicateCall | Foo.qll:3:1:3:26 | ClasslessPredicate foo | -| Foo.qll:10:21:10:25 | PredicateCall | Foo.qll:8:3:8:28 | ClassPredicate bar | -| Foo.qll:14:30:14:40 | MemberCall | Foo.qll:10:3:10:27 | ClassPredicate baz | -| Foo.qll:17:27:17:42 | MemberCall | Foo.qll:8:3:8:28 | ClassPredicate bar | -| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:20:3:20:54 | ClasslessPredicate myThing2 | -| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:26:3:26:32 | ClasslessPredicate alias2 | -| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:22:3:22:32 | ClasslessPredicate myThing0 | -| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:24:3:24:32 | ClasslessPredicate alias0 | +| Bar.qll:5:38:5:47 | PredicateCall | Bar.qll:8:7:8:14 | ClasslessPredicate snapshot | +| Bar.qll:24:12:24:32 | MemberCall | Bar.qll:19:7:19:18 | ClassPredicate getParameter | +| Bar.qll:26:12:26:31 | MemberCall | Bar.qll:19:7:19:18 | ClassPredicate getParameter | +| Bar.qll:30:12:30:32 | MemberCall | Bar.qll:19:7:19:18 | ClassPredicate getParameter | +| Baz.qll:8:18:8:44 | MemberCall | Baz.qll:4:10:4:24 | ClassPredicate getImportedPath | +| Foo.qll:5:26:5:30 | PredicateCall | Foo.qll:3:11:3:13 | ClasslessPredicate foo | +| Foo.qll:10:21:10:25 | PredicateCall | Foo.qll:8:13:8:15 | ClassPredicate bar | +| Foo.qll:14:30:14:40 | MemberCall | Foo.qll:10:13:10:15 | ClassPredicate baz | +| Foo.qll:17:27:17:42 | MemberCall | Foo.qll:8:13:8:15 | ClassPredicate bar | +| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:20:13:20:20 | ClasslessPredicate myThing2 | +| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:26:13:26:18 | ClasslessPredicate alias2 | +| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:22:13:22:20 | ClasslessPredicate myThing0 | +| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:24:13:24:18 | ClasslessPredicate alias0 | | Foo.qll:36:36:36:65 | MemberCall | file://:0:0:0:0 | replaceAll | | Foo.qll:38:39:38:67 | MemberCall | file://:0:0:0:0 | regexpCapture | -| Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | -| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | -| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:12:14:43 | ClassPredicate bar | -| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | -| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:22:12:22:44 | ClassPredicate bar | -| Overrides.qll:28:3:28:9 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | -| Overrides.qll:29:3:29:10 | MemberCall | Overrides.qll:8:3:8:41 | ClassPredicate baz | -| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:2:13:2:36 | ClasslessPredicate fooSig | -| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:8:3:8:35 | ClasslessPredicate myFoo | -| ParamModules.qll:10:26:10:49 | PredicateCall | ParamModules.qll:5:5:5:43 | ClasslessPredicate bar | -| ParamModules.qll:26:27:26:53 | PredicateCall | ParamModules.qll:17:5:17:42 | ClasslessPredicate getAnEven | -| ParamModules.qll:26:27:26:61 | MemberCall | ParamModules.qll:23:5:23:39 | ClassPredicate myFoo | -| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:33:5:33:17 | ClasslessPredicate getThing | -| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:51:5:51:26 | ClasslessPredicate getThing | -| ParamModules.qll:59:30:59:45 | PredicateCall | ParamModules.qll:37:5:37:49 | ClasslessPredicate getThing | -| ParamModules.qll:59:30:59:53 | MemberCall | ParamModules.qll:46:7:46:41 | ClassPredicate myFoo | -| ParamModules.qll:61:39:61:47 | MemberCall | ParamModules.qll:46:7:46:41 | ClassPredicate myFoo | -| packs/other/OtherThing.qll:5:3:5:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:1:1:30 | ClasslessPredicate foo | -| packs/other/OtherThing.qll:6:3:6:8 | PredicateCall | packs/src/SrcThing.qll:8:1:8:30 | ClasslessPredicate bar | -| packs/src/SrcThing.qll:4:3:4:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:1:1:30 | ClasslessPredicate foo | -| packs/src/SrcThing.qll:5:3:5:8 | PredicateCall | packs/src/SrcThing.qll:8:1:8:30 | ClasslessPredicate bar | +| MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:1:11:1:13 | ClasslessPredicate foo | +| MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:12:11:12:15 | ClasslessPredicate myFoo | +| MultiResolve.qll:23:7:23:18 | PredicateCall | MultiResolve.qll:17:13:17:15 | ClasslessPredicate bar | +| MultiResolve.qll:41:30:41:47 | MemberCall | MultiResolve.qll:31:13:31:15 | ClassPredicate foo | +| MultiResolve.qll:49:3:49:12 | PredicateCall | MultiResolve.qll:45:13:45:15 | ClasslessPredicate foo | +| MultiResolve.qll:53:30:53:47 | MemberCall | MultiResolve.qll:37:13:37:15 | ClassPredicate foo | +| MultiResolve.qll:56:5:56:14 | MemberCall | MultiResolve.qll:53:22:53:24 | ClassPredicate foo | +| Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:7:6:9 | ClassPredicate bar | +| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:16:14:18 | ClassPredicate bar | +| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:22:16:22:18 | ClassPredicate bar | +| Overrides.qll:28:3:28:9 | MemberCall | Overrides.qll:6:7:6:9 | ClassPredicate bar | +| Overrides.qll:29:3:29:10 | MemberCall | Overrides.qll:8:13:8:15 | ClassPredicate baz | +| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:2:23:2:28 | ClasslessPredicate fooSig | +| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:8:13:8:17 | ClasslessPredicate myFoo | +| ParamModules.qll:10:26:10:49 | PredicateCall | ParamModules.qll:5:15:5:17 | ClasslessPredicate bar | +| ParamModules.qll:26:27:26:53 | PredicateCall | ParamModules.qll:17:13:17:21 | ClasslessPredicate getAnEven | +| ParamModules.qll:26:27:26:61 | MemberCall | ParamModules.qll:23:12:23:16 | ClassPredicate myFoo | +| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:33:7:33:14 | ClasslessPredicate getThing | +| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:51:7:51:14 | ClasslessPredicate getThing | +| ParamModules.qll:59:30:59:45 | PredicateCall | ParamModules.qll:37:7:37:14 | ClasslessPredicate getThing | +| ParamModules.qll:59:30:59:53 | MemberCall | ParamModules.qll:46:14:46:18 | ClassPredicate myFoo | +| ParamModules.qll:61:39:61:47 | MemberCall | ParamModules.qll:46:14:46:18 | ClassPredicate myFoo | +| packs/other/OtherThing.qll:5:3:5:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:11:1:13 | ClasslessPredicate foo | +| packs/other/OtherThing.qll:6:3:6:8 | PredicateCall | packs/src/SrcThing.qll:8:11:8:13 | ClasslessPredicate bar | +| packs/src/SrcThing.qll:4:3:4:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:11:1:13 | ClasslessPredicate foo | +| packs/src/SrcThing.qll:5:3:5:8 | PredicateCall | packs/src/SrcThing.qll:8:11:8:13 | ClasslessPredicate bar | dependsOn | packs/other/qlpack.yml:1:1:1:4 | ql-other-pack-thing | packs/src/qlpack.yml:1:1:1:4 | ql-testing-src-pack | | packs/src/qlpack.yml:1:1:1:4 | ql-testing-src-pack | packs/lib/qlpack.yml:1:1:1:4 | ql-testing-lib-pack | exprPredicate -| Foo.qll:24:22:24:31 | predicate | Foo.qll:22:3:22:32 | ClasslessPredicate myThing0 | -| Foo.qll:26:22:26:31 | predicate | Foo.qll:20:3:20:54 | ClasslessPredicate myThing2 | -| Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:27 | NewTypeBranch MkRoot | -| Foo.qll:47:65:47:70 | predicate | Foo.qll:44:9:44:56 | ClasslessPredicate edge | -| ParamModules.qll:4:18:4:25 | predicate | ParamModules.qll:2:13:2:36 | ClasslessPredicate fooSig | -| ParamModules.qll:10:34:10:40 | predicate | ParamModules.qll:8:3:8:35 | ClasslessPredicate myFoo | +| Foo.qll:24:22:24:31 | predicate | Foo.qll:22:13:22:20 | ClasslessPredicate myThing0 | +| Foo.qll:26:22:26:31 | predicate | Foo.qll:20:13:20:20 | ClasslessPredicate myThing2 | +| Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:25 | NewTypeBranch MkRoot | +| Foo.qll:47:65:47:70 | predicate | Foo.qll:44:19:44:22 | ClasslessPredicate edge | +| MultiResolve.qll:12:19:12:23 | predicate | MultiResolve.qll:1:11:1:13 | ClasslessPredicate foo | +| ParamModules.qll:4:18:4:25 | predicate | ParamModules.qll:2:23:2:28 | ClasslessPredicate fooSig | +| ParamModules.qll:10:34:10:40 | predicate | ParamModules.qll:8:13:8:17 | ClasslessPredicate myFoo | diff --git a/ql/ql/test/printAst/printAst.expected b/ql/ql/test/printAst/printAst.expected index 603608355d7..daa299215d3 100644 --- a/ql/ql/test/printAst/printAst.expected +++ b/ql/ql/test/printAst/printAst.expected @@ -3,8 +3,8 @@ nodes | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | | Foo.qll:1:1:27:2 | TopLevel | semmle.label | [TopLevel] TopLevel | | Foo.qll:1:1:27:2 | TopLevel | semmle.order | 1 | -| Foo.qll:3:1:7:1 | Class Foo | semmle.label | [Class] Class Foo | -| Foo.qll:3:1:7:1 | Class Foo | semmle.order | 3 | +| Foo.qll:3:7:3:9 | Class Foo | semmle.label | [Class] Class Foo | +| Foo.qll:3:7:3:9 | Class Foo | semmle.order | 3 | | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 | | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | [CharPred] CharPred Foo | @@ -17,8 +17,8 @@ nodes | Foo.qll:4:15:4:15 | Integer | semmle.order | 8 | | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 | -| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.label | [ClassPredicate] ClassPredicate toString | -| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 9 | +| Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.label | [ClassPredicate] ClassPredicate toString | +| Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.order | 10 | | Foo.qll:6:23:6:28 | result | semmle.label | [ResultAccess] result | | Foo.qll:6:23:6:28 | result | semmle.order | 11 | | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | @@ -27,8 +27,8 @@ nodes | Foo.qll:6:32:6:36 | String | semmle.order | 13 | | Foo.qll:9:1:9:5 | annotation | semmle.label | [Annotation] annotation | | Foo.qll:9:1:9:5 | annotation | semmle.order | 14 | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.label | [ClasslessPredicate] ClasslessPredicate foo | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 15 | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.label | [ClasslessPredicate] ClasslessPredicate foo | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.order | 15 | | Foo.qll:9:21:9:23 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 16 | | Foo.qll:9:21:9:25 | f | semmle.label | [VarDecl] f | @@ -59,8 +59,8 @@ nodes | Foo.qll:10:69:10:73 | inner | semmle.order | 29 | | Foo.qll:10:69:10:84 | MemberCall | semmle.label | [MemberCall] MemberCall | | Foo.qll:10:69:10:84 | MemberCall | semmle.order | 29 | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.label | [ClasslessPredicate] ClasslessPredicate calls | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.order | 31 | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.label | [ClasslessPredicate] ClasslessPredicate calls | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.order | 31 | | Foo.qll:13:17:13:19 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 32 | | Foo.qll:13:17:13:21 | f | semmle.label | [VarDecl] f | @@ -239,38 +239,38 @@ nodes edges | Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAnImport() | | Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:1:7:1 | Class Foo | semmle.label | getAClass() | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:1:7:1 | Class Foo | semmle.order | 3 | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.label | getAPredicate() | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 15 | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.label | getAPredicate() | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.order | 31 | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | getCharPred() | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.order | 5 | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.label | getClassPredicate(_) | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 9 | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.label | getAClass() | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.order | 3 | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.label | getAPredicate() | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.order | 15 | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.label | getAPredicate() | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.order | 31 | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | getCharPred() | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.order | 5 | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.label | getClassPredicate(_) | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.order | 10 | | Foo.qll:4:3:4:17 | CharPred Foo | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.label | getBody() | | Foo.qll:4:3:4:17 | CharPred Foo | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.order | 6 | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:11:4:11 | Integer | semmle.label | getLeftOperand() | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:11:4:11 | Integer | semmle.order | 6 | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.label | getRightOperand() | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.order | 8 | -| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | getReturnTypeExpr() | -| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 | -| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | getBody() | -| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 11 | +| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | getReturnTypeExpr() | +| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 | +| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | getBody() | +| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 11 | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.label | getLeftOperand() | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.order | 11 | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.label | getRightOperand() | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.order | 13 | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.label | getAnAnnotation() | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.order | 14 | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.label | getParameter(_) | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.order | 16 | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | getBody() | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 18 | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.label | getAnAnnotation() | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.order | 14 | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.label | getParameter(_) | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.order | 16 | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | getBody() | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 18 | | Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.label | getTypeExpr() | | Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 16 | | Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:3:10:3 | f | semmle.label | getLeftOperand() | @@ -297,10 +297,10 @@ edges | Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:46:10:50 | String | semmle.order | 27 | | Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.label | getBase() | | Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.order | 29 | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.order | 32 | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.label | getBody() | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.order | 34 | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.order | 32 | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.label | getBody() | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.order | 34 | | Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.label | getTypeExpr() | | Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 32 | | Foo.qll:14:3:14:10 | PredicateCall | Foo.qll:14:9:14:9 | f | semmle.label | getArgument(_) | diff --git a/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected b/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected index bd6bc99489d..de23b92bafa 100644 --- a/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected +++ b/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected @@ -1,3 +1,3 @@ -| Test.qll:2:1:2:27 | ClasslessPredicate isXML | Acronyms in isXML should be PascalCase/camelCase | -| Test.qll:8:1:10:15 | NewType TXMLElements | Acronyms in TXMLElements should be PascalCase/camelCase | -| Test.qll:10:3:10:15 | NewTypeBranch TXMLElement | Acronyms in TXMLElement should be PascalCase/camelCase | +| Test.qll:2:11:2:15 | ClasslessPredicate isXML | Acronyms in isXML should be PascalCase/camelCase | +| Test.qll:8:9:8:20 | NewType TXMLElements | Acronyms in TXMLElements should be PascalCase/camelCase | +| Test.qll:10:3:10:13 | NewTypeBranch TXMLElement | Acronyms in TXMLElement should be PascalCase/camelCase | diff --git a/ql/ql/test/queries/style/DeadCode/DeadCode.expected b/ql/ql/test/queries/style/DeadCode/DeadCode.expected index d3b3115e729..39a2b034390 100644 --- a/ql/ql/test/queries/style/DeadCode/DeadCode.expected +++ b/ql/ql/test/queries/style/DeadCode/DeadCode.expected @@ -1,2 +1,2 @@ -| Foo.qll:2:11:2:38 | ClasslessPredicate dead1 | Code is dead | -| Foo.qll:6:3:6:30 | ClasslessPredicate dead2 | Code is dead | +| Foo.qll:2:21:2:25 | ClasslessPredicate dead1 | Code is dead | +| Foo.qll:6:13:6:17 | ClasslessPredicate dead2 | Code is dead | diff --git a/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected b/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected index f59b21d0d73..2ef0dd4b1ad 100644 --- a/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected +++ b/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected @@ -1 +1 @@ -| Test.qll:12:3:12:33 | ClassPredicate test | Wrong.test overrides $@ but does not have an override annotation. | Test.qll:4:3:4:40 | ClassPredicate test | Super.test | +| Test.qll:12:13:12:16 | ClassPredicate test | Wrong.test overrides $@ but does not have an override annotation. | Test.qll:4:13:4:16 | ClassPredicate test | Super.test | diff --git a/ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll b/ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll new file mode 100644 index 00000000000..13509dbe521 --- /dev/null +++ b/ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll @@ -0,0 +1,14 @@ +/** `param1`, `param2`, and `param3` are the parameters. */ +predicate test1(int param1, int param2, int param3) { none() } // OK + +/** `param1`, `par2` */ +predicate test2(int param1, int param2) { none() } // NOT OK - `par2` is not a parameter, and `param2` has no documentation + +/** `param1`, `par2 + par3` */ +predicate test3(int param1, int par2, int par3) { none() } // OK + +/** this mentions no parameters */ +predicate test4(int param1, int param2) { none() } // OK - the QLDoc mentions none of the parameters, that's OK + +/** the param1 parameter is mentioned in a non-code block, but the `par2` parameter is misspelled */ +predicate test5(int param1, int param2) { none() } // NOT OK - the `param1` parameter is "documented" in clear text, but `par2` is misspelled diff --git a/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected new file mode 100644 index 00000000000..4307178da72 --- /dev/null +++ b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected @@ -0,0 +1,2 @@ +| Foo.qll:5:11:5:15 | ClasslessPredicate test2 | The QLDoc has no documentation for param2, but the QLDoc mentions par2 | +| Foo.qll:14:11:14:15 | ClasslessPredicate test5 | The QLDoc has no documentation for param2, but the QLDoc mentions par2 | diff --git a/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref new file mode 100644 index 00000000000..0539e4f5de2 --- /dev/null +++ b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref @@ -0,0 +1 @@ +queries/style/MissingParameterInQlDoc.ql \ No newline at end of file diff --git a/ql/ql/test/queries/style/Misspelling/Misspelling.expected b/ql/ql/test/queries/style/Misspelling/Misspelling.expected index dc028c412d8..65f9f245d3b 100644 --- a/ql/ql/test/queries/style/Misspelling/Misspelling.expected +++ b/ql/ql/test/queries/style/Misspelling/Misspelling.expected @@ -1,6 +1,6 @@ | Test.qll:1:1:3:3 | QLDoc | This QLDoc comment contains the common misspelling 'mispelled', which should instead be 'misspelled'. | -| Test.qll:4:1:11:1 | Class PublicallyAccessible | This class name contains the common misspelling 'publically', which should instead be 'publicly'. | +| Test.qll:4:7:4:26 | Class PublicallyAccessible | This class name contains the common misspelling 'publically', which should instead be 'publicly'. | | Test.qll:5:3:5:20 | FieldDecl | This field name contains the common misspelling 'occurences', which should instead be 'occurrences'. | -| Test.qll:10:3:10:36 | ClassPredicate hasAgrument | This classPredicate name contains the common misspelling 'agrument', which should instead be 'argument'. | +| Test.qll:10:13:10:23 | ClassPredicate hasAgrument | This classPredicate name contains the common misspelling 'agrument', which should instead be 'argument'. | | Test.qll:13:1:16:3 | QLDoc | This QLDoc comment contains the non-US spelling 'colour', which should instead be 'color'. | -| Test.qll:17:1:22:1 | Class AnalysedInt | This class name contains the non-US spelling 'analysed', which should instead be 'analyzed'. | +| Test.qll:17:7:17:17 | Class AnalysedInt | This class name contains the non-US spelling 'analysed', which should instead be 'analyzed'. | diff --git a/ql/ql/test/queries/style/RedundantCast/Foo.qll b/ql/ql/test/queries/style/RedundantCast/Foo.qll new file mode 100644 index 00000000000..d993f654bc4 --- /dev/null +++ b/ql/ql/test/queries/style/RedundantCast/Foo.qll @@ -0,0 +1,11 @@ +class Foo extends string { + Foo() { this = "Foo" } +} + +predicate test(Foo f) { f.(Foo).toString() = "X" } + +predicate test2(Foo a, Foo b) { a.(Foo) = b } + +predicate called(Foo a) { a.toString() = "X" } + +predicate test3(string s) { called(s.(Foo)) } diff --git a/ql/ql/test/queries/style/RedundantCast/RedundantCast.expected b/ql/ql/test/queries/style/RedundantCast/RedundantCast.expected new file mode 100644 index 00000000000..e4e57083633 --- /dev/null +++ b/ql/ql/test/queries/style/RedundantCast/RedundantCast.expected @@ -0,0 +1,3 @@ +| Foo.qll:5:25:5:31 | InlineCast | Redundant cast to $@ | Foo.qll:5:28:5:30 | TypeExpr | Foo | +| Foo.qll:7:33:7:39 | InlineCast | Redundant cast to $@ | Foo.qll:7:36:7:38 | TypeExpr | Foo | +| Foo.qll:11:36:11:42 | InlineCast | Redundant cast to $@ | Foo.qll:11:39:11:41 | TypeExpr | Foo | diff --git a/ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref b/ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref new file mode 100644 index 00000000000..659062d3ae5 --- /dev/null +++ b/ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref @@ -0,0 +1 @@ +queries/style/RedundantCast.ql diff --git a/ql/ql/test/type/type.expected b/ql/ql/test/type/type.expected index 773a9244a22..fd3a34c27f6 100644 --- a/ql/ql/test/type/type.expected +++ b/ql/ql/test/type/type.expected @@ -1,6 +1,6 @@ -| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings | -| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings.Strings | -| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings.extends | +| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings | +| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings.Strings | +| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings.extends | | Test.qll:4:22:4:76 | Set | file://:0:0:0:0 | string | | Test.qll:4:23:4:24 | String | file://:0:0:0:0 | string | | Test.qll:4:27:4:29 | String | file://:0:0:0:0 | string | @@ -12,9 +12,9 @@ | Test.qll:4:61:4:63 | String | file://:0:0:0:0 | string | | Test.qll:4:66:4:69 | String | file://:0:0:0:0 | string | | Test.qll:4:72:4:75 | String | file://:0:0:0:0 | string | -| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats | -| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats.Floats | -| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats.extends | +| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats | +| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats.Floats | +| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats.extends | | Test.qll:8:21:8:70 | Set | file://:0:0:0:0 | float | | Test.qll:8:22:8:24 | Float | file://:0:0:0:0 | float | | Test.qll:8:27:8:29 | Float | file://:0:0:0:0 | float | @@ -27,28 +27,28 @@ | Test.qll:8:62:8:64 | Float | file://:0:0:0:0 | float | | Test.qll:8:67:8:69 | Float | file://:0:0:0:0 | float | | Test.qll:11:37:11:42 | result | file://:0:0:0:0 | string | -| Test.qll:11:46:11:46 | a | Test.qll:3:1:5:1 | Strings | +| Test.qll:11:46:11:46 | a | Test.qll:3:7:3:13 | Strings | | Test.qll:11:46:11:50 | AddExpr | file://:0:0:0:0 | string | -| Test.qll:11:50:11:50 | b | Test.qll:3:1:5:1 | Strings | +| Test.qll:11:50:11:50 | b | Test.qll:3:7:3:13 | Strings | | Test.qll:13:36:13:41 | result | file://:0:0:0:0 | float | -| Test.qll:13:45:13:45 | a | Test.qll:7:1:9:1 | Floats | +| Test.qll:13:45:13:45 | a | Test.qll:7:7:7:12 | Floats | | Test.qll:13:45:13:49 | AddExpr | file://:0:0:0:0 | float | -| Test.qll:13:49:13:49 | b | Test.qll:7:1:9:1 | Floats | -| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base | -| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base.Base | -| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base.extends | +| Test.qll:13:49:13:49 | b | Test.qll:7:7:7:12 | Floats | +| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base | +| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base.Base | +| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base.extends | | Test.qll:16:19:16:23 | String | file://:0:0:0:0 | string | | Test.qll:18:15:18:20 | result | file://:0:0:0:0 | int | | Test.qll:18:24:18:24 | Integer | file://:0:0:0:0 | int | -| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub | -| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub.Sub | -| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub.extends | +| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub | +| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub.Sub | +| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub.extends | | Test.qll:22:18:22:22 | String | file://:0:0:0:0 | string | | Test.qll:24:15:24:20 | result | file://:0:0:0:0 | int | -| Test.qll:24:24:24:33 | Super | Test.qll:15:1:19:1 | Base | +| Test.qll:24:24:24:33 | Super | Test.qll:15:7:15:10 | Base | | Test.qll:24:24:24:39 | MemberCall | file://:0:0:0:0 | int | | Test.qll:26:16:26:21 | result | file://:0:0:0:0 | int | -| Test.qll:26:25:26:29 | Super | Test.qll:15:1:19:1 | Base | +| Test.qll:26:25:26:29 | Super | Test.qll:15:7:15:10 | Base | | Test.qll:26:25:26:35 | MemberCall | file://:0:0:0:0 | int | | Test.qll:30:32:30:37 | result | file://:0:0:0:0 | int | | Test.qll:30:41:30:41 | a | file://:0:0:0:0 | int | diff --git a/ql/create-extractor-pack.ps1 b/ql/scripts/create-extractor-pack.ps1 similarity index 100% rename from ql/create-extractor-pack.ps1 rename to ql/scripts/create-extractor-pack.ps1 diff --git a/ql/create-extractor-pack.sh b/ql/scripts/create-extractor-pack.sh similarity index 100% rename from ql/create-extractor-pack.sh rename to ql/scripts/create-extractor-pack.sh diff --git a/ql/scripts/merge-sarif.js b/ql/scripts/merge-sarif.js new file mode 100644 index 00000000000..5c781f1b67d --- /dev/null +++ b/ql/scripts/merge-sarif.js @@ -0,0 +1,23 @@ +var fs = require("fs"); + +// first a list of files to merge, and the last argument is the output file. +async function main(files) { + const inputs = files + .slice(0, -1) + .map((file) => fs.readFileSync(file)) + .map((data) => JSON.parse(data)); + const out = inputs[0]; // just arbitrarily take the first one + const outFile = files[files.length - 1]; + + const combinedResults = []; + + for (const sarif of inputs) { + combinedResults.push(...sarif.runs[0].results); + } + + out.runs[0].artifacts = []; // the indexes in these won't make sense, so I hope this works. + out.runs[0].results = combinedResults; + + fs.writeFileSync(outFile, JSON.stringify(out, null, 2)); +} +main(process.argv.splice(2)); diff --git a/ql/scripts/split-sarif.js b/ql/scripts/split-sarif.js new file mode 100644 index 00000000000..d09989abf8a --- /dev/null +++ b/ql/scripts/split-sarif.js @@ -0,0 +1,30 @@ +var fs = require("fs"); + +// the .sarif file to split, and then the directory to put the split files in. +async function main(inputs) { + const sarifFile = JSON.parse(fs.readFileSync(inputs[0])); + const outFolder = inputs[1]; + + const out = {}; + + for (const result of sarifFile.runs[0].results) { + const lang = getLanguage(result); + if (!out[lang]) { + out[lang] = []; + } + out[lang].push(result); + } + + for (const lang in out) { + const outSarif = JSON.parse(JSON.stringify(sarifFile)); + outSarif.runs[0].results = out[lang]; + fs.writeFileSync(`${outFolder}/${lang}.sarif`, JSON.stringify(outSarif, null, 2)); + } +} + +function getLanguage(result) { + return result.locations[0].physicalLocation.artifactLocation.uri.split( + "/" + )[0]; +} +main(process.argv.splice(2)); diff --git a/ruby/Cargo.lock b/ruby/Cargo.lock index 3ea76573fa4..2e2f205ce02 100644 Binary files a/ruby/Cargo.lock and b/ruby/Cargo.lock differ diff --git a/ruby/autobuilder/src/main.rs b/ruby/autobuilder/src/main.rs index 18892ae2d5c..ae4aa816190 100644 --- a/ruby/autobuilder/src/main.rs +++ b/ruby/autobuilder/src/main.rs @@ -19,6 +19,7 @@ fn main() -> std::io::Result<()> { .arg("--include-extension=.erb") .arg("--include-extension=.gemspec") .arg("--include=**/Gemfile") + .arg("--exclude=**/.git") .arg("--size-limit=5m") .arg("--language=ruby") .arg("--working-dir=.") @@ -29,9 +30,9 @@ fn main() -> std::io::Result<()> { .split('\n') { if let Some(stripped) = line.strip_prefix("include:") { - cmd.arg("--include").arg(stripped); + cmd.arg("--also-match=".to_owned() + stripped); } else if let Some(stripped) = line.strip_prefix("exclude:") { - cmd.arg("--exclude").arg(stripped); + cmd.arg("--exclude=".to_owned() + stripped); } } let exit = &cmd.spawn()?.wait()?; diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index 1aa67c412e2..c1a7c4424b9 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -11,10 +11,12 @@ flate2 = "1.0" node-types = { path = "../node-types" } tree-sitter = "0.19" tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "1a538da253d73f896b9f6c0c7d79cda58791ac5c" } -tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "6334d6ab3d04a5672da695d3b155ca3301511f8d" } +tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "e75d04404c9dd71ad68850d5c672b226d5e694f3" } clap = "3.0" tracing = "0.1" tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } rayon = "1.5.0" num_cpus = "1.13.0" regex = "1.5.5" +encoding = "0.2" +lazy_static = "1.4.0" diff --git a/ruby/extractor/src/extractor.rs b/ruby/extractor/src/extractor.rs index 8cdaff1b738..db280634ae5 100644 --- a/ruby/extractor/src/extractor.rs +++ b/ruby/extractor/src/extractor.rs @@ -1,161 +1,112 @@ +use crate::trap; use node_types::{EntryKind, Field, NodeTypeMap, Storage, TypeName}; -use std::borrow::Cow; use std::collections::BTreeMap as Map; use std::collections::BTreeSet as Set; use std::fmt; -use std::io::Write; use std::path::Path; use tracing::{error, info, span, Level}; use tree_sitter::{Language, Node, Parser, Range, Tree}; -pub struct TrapWriter { - /// The accumulated trap entries - trap_output: Vec, - /// A counter for generating fresh labels - counter: u32, - /// cache of global keys - global_keys: std::collections::HashMap, +pub fn populate_file(writer: &mut trap::Writer, absolute_path: &Path) -> trap::Label { + let (file_label, fresh) = + writer.global_id(&trap::full_id_for_file(&normalize_path(absolute_path))); + if fresh { + writer.add_tuple( + "files", + vec![ + trap::Arg::Label(file_label), + trap::Arg::String(normalize_path(absolute_path)), + ], + ); + populate_parent_folders(writer, file_label, absolute_path.parent()); + } + file_label } -pub fn new_trap_writer() -> TrapWriter { - TrapWriter { - counter: 0, - trap_output: Vec::new(), - global_keys: std::collections::HashMap::new(), +fn populate_empty_file(writer: &mut trap::Writer) -> trap::Label { + let (file_label, fresh) = writer.global_id("empty;sourcefile"); + if fresh { + writer.add_tuple( + "files", + vec![ + trap::Arg::Label(file_label), + trap::Arg::String("".to_string()), + ], + ); } + file_label } -impl TrapWriter { - /// Gets a label that will hold the unique ID of the passed string at import time. - /// This can be used for incrementally importable TRAP files -- use globally unique - /// strings to compute a unique ID for table tuples. - /// - /// Note: You probably want to make sure that the key strings that you use are disjoint - /// for disjoint column types; the standard way of doing this is to prefix (or append) - /// the column type name to the ID. Thus, you might identify methods in Java by the - /// full ID "methods_com.method.package.DeclaringClass.method(argumentList)". +pub fn populate_empty_location(writer: &mut trap::Writer) { + let file_label = populate_empty_file(writer); + location(writer, file_label, 0, 0, 0, 0); +} - fn fresh_id(&mut self) -> Label { - let label = Label(self.counter); - self.counter += 1; - self.trap_output.push(TrapEntry::FreshId(label)); - label - } - - fn global_id(&mut self, key: &str) -> (Label, bool) { - if let Some(label) = self.global_keys.get(key) { - return (*label, false); - } - let label = Label(self.counter); - self.counter += 1; - self.global_keys.insert(key.to_owned(), label); - self.trap_output - .push(TrapEntry::MapLabelToKey(label, key.to_owned())); - (label, true) - } - - fn add_tuple(&mut self, table_name: &str, args: Vec) { - self.trap_output - .push(TrapEntry::GenericTuple(table_name.to_owned(), args)) - } - - fn populate_file(&mut self, absolute_path: &Path) -> Label { - let (file_label, fresh) = self.global_id(&full_id_for_file(absolute_path)); - if fresh { - self.add_tuple( - "files", - vec![ - Arg::Label(file_label), - Arg::String(normalize_path(absolute_path)), - ], - ); - self.populate_parent_folders(file_label, absolute_path.parent()); - } - file_label - } - - fn populate_empty_file(&mut self) -> Label { - let (file_label, fresh) = self.global_id("empty;sourcefile"); - if fresh { - self.add_tuple( - "files", - vec![Arg::Label(file_label), Arg::String("".to_string())], - ); - } - file_label - } - - pub fn populate_empty_location(&mut self) { - let file_label = self.populate_empty_file(); - self.location(file_label, 0, 0, 0, 0); - } - - fn populate_parent_folders(&mut self, child_label: Label, path: Option<&Path>) { - let mut path = path; - let mut child_label = child_label; - loop { - match path { - None => break, - Some(folder) => { - let (folder_label, fresh) = self.global_id(&full_id_for_folder(folder)); - self.add_tuple( - "containerparent", - vec![Arg::Label(folder_label), Arg::Label(child_label)], +pub fn populate_parent_folders( + writer: &mut trap::Writer, + child_label: trap::Label, + path: Option<&Path>, +) { + let mut path = path; + let mut child_label = child_label; + loop { + match path { + None => break, + Some(folder) => { + let (folder_label, fresh) = + writer.global_id(&trap::full_id_for_folder(&normalize_path(folder))); + writer.add_tuple( + "containerparent", + vec![ + trap::Arg::Label(folder_label), + trap::Arg::Label(child_label), + ], + ); + if fresh { + writer.add_tuple( + "folders", + vec![ + trap::Arg::Label(folder_label), + trap::Arg::String(normalize_path(folder)), + ], ); - if fresh { - self.add_tuple( - "folders", - vec![ - Arg::Label(folder_label), - Arg::String(normalize_path(folder)), - ], - ); - path = folder.parent(); - child_label = folder_label; - } else { - break; - } + path = folder.parent(); + child_label = folder_label; + } else { + break; } } } } +} - fn location( - &mut self, - file_label: Label, - start_line: usize, - start_column: usize, - end_line: usize, - end_column: usize, - ) -> Label { - let (loc_label, fresh) = self.global_id(&format!( - "loc,{{{}}},{},{},{},{}", - file_label, start_line, start_column, end_line, end_column - )); - if fresh { - self.add_tuple( - "locations_default", - vec![ - Arg::Label(loc_label), - Arg::Label(file_label), - Arg::Int(start_line), - Arg::Int(start_column), - Arg::Int(end_line), - Arg::Int(end_column), - ], - ); - } - loc_label - } - - fn comment(&mut self, text: String) { - self.trap_output.push(TrapEntry::Comment(text)); - } - - pub fn output(self, writer: &mut dyn Write) -> std::io::Result<()> { - write!(writer, "{}", Program(self.trap_output)) +fn location( + writer: &mut trap::Writer, + file_label: trap::Label, + start_line: usize, + start_column: usize, + end_line: usize, + end_column: usize, +) -> trap::Label { + let (loc_label, fresh) = writer.global_id(&format!( + "loc,{{{}}},{},{},{},{}", + file_label, start_line, start_column, end_line, end_column + )); + if fresh { + writer.add_tuple( + "locations_default", + vec![ + trap::Arg::Label(loc_label), + trap::Arg::Label(file_label), + trap::Arg::Int(start_line), + trap::Arg::Int(start_column), + trap::Arg::Int(end_line), + trap::Arg::Int(end_column), + ], + ); } + loc_label } /// Extracts the source file at `path`, which is assumed to be canonicalized. @@ -163,71 +114,43 @@ pub fn extract( language: Language, language_prefix: &str, schema: &NodeTypeMap, - trap_writer: &mut TrapWriter, + trap_writer: &mut trap::Writer, path: &Path, source: &[u8], ranges: &[Range], ) -> std::io::Result<()> { + let path_str = format!("{}", path.display()); let span = span!( Level::TRACE, "extract", - file = %path.display() + file = %path_str ); let _enter = span.enter(); - info!("extracting: {}", path.display()); + info!("extracting: {}", path_str); let mut parser = Parser::new(); parser.set_language(language).unwrap(); parser.set_included_ranges(ranges).unwrap(); let tree = parser.parse(&source, None).expect("Failed to parse file"); - trap_writer.comment(format!("Auto-generated TRAP file for {}", path.display())); - let file_label = &trap_writer.populate_file(path); - let mut visitor = Visitor { + trap_writer.comment(format!("Auto-generated TRAP file for {}", path_str)); + let file_label = populate_file(trap_writer, path); + let mut visitor = Visitor::new( source, trap_writer, // TODO: should we handle path strings that are not valid UTF8 better? - path: format!("{}", path.display()), - file_label: *file_label, - toplevel_child_counter: 0, - stack: Vec::new(), + &path_str, + file_label, language_prefix, schema, - }; + ); traverse(&tree, &mut visitor); parser.reset(); Ok(()) } -/// Escapes a string for use in a TRAP key, by replacing special characters with -/// HTML entities. -fn escape_key<'a, S: Into>>(key: S) -> Cow<'a, str> { - fn needs_escaping(c: char) -> bool { - matches!(c, '&' | '{' | '}' | '"' | '@' | '#') - } - - let key = key.into(); - if key.contains(needs_escaping) { - let mut escaped = String::with_capacity(2 * key.len()); - for c in key.chars() { - match c { - '&' => escaped.push_str("&"), - '{' => escaped.push_str("{"), - '}' => escaped.push_str("}"), - '"' => escaped.push_str("""), - '@' => escaped.push_str("@"), - '#' => escaped.push_str("#"), - _ => escaped.push(c), - } - } - Cow::Owned(escaped) - } else { - key - } -} - /// Normalizes the path according the common CodeQL specification. Assumes that /// `path` has already been canonicalized using `std::fs::canonicalize`. fn normalize_path(path: &Path) -> String { @@ -267,34 +190,28 @@ fn normalize_path(path: &Path) -> String { } } -fn full_id_for_file(path: &Path) -> String { - format!("{};sourcefile", escape_key(&normalize_path(path))) -} - -fn full_id_for_folder(path: &Path) -> String { - format!("{};folder", escape_key(&normalize_path(path))) -} - struct ChildNode { field_name: Option<&'static str>, - label: Label, + label: trap::Label, type_name: TypeName, } struct Visitor<'a> { /// The file path of the source code (as string) - path: String, + path: &'a str, /// The label to use whenever we need to refer to the `@file` entity of this /// source file. - file_label: Label, + file_label: trap::Label, /// The source code as a UTF-8 byte array source: &'a [u8], - /// A TrapWriter to accumulate trap entries - trap_writer: &'a mut TrapWriter, + /// A trap::Writer to accumulate trap entries + trap_writer: &'a mut trap::Writer, /// A counter for top-level child nodes toplevel_child_counter: usize, - /// Language prefix - language_prefix: &'a str, + /// Language-specific name of the AST info table + ast_node_info_table_name: String, + /// Language-specific name of the tokeninfo table + tokeninfo_table_name: String, /// A lookup table from type name to node types schema: &'a NodeTypeMap, /// A stack for gathering information from child nodes. Whenever a node is @@ -303,27 +220,48 @@ struct Visitor<'a> { /// node the list containing the child data is popped from the stack and /// matched against the dbscheme for the node. If the expectations are met /// the corresponding row definitions are added to the trap_output. - stack: Vec<(Label, usize, Vec)>, + stack: Vec<(trap::Label, usize, Vec)>, } -impl Visitor<'_> { +impl<'a> Visitor<'a> { + fn new( + source: &'a [u8], + trap_writer: &'a mut trap::Writer, + path: &'a str, + file_label: trap::Label, + language_prefix: &str, + schema: &'a NodeTypeMap, + ) -> Visitor<'a> { + Visitor { + path, + file_label, + source, + trap_writer, + toplevel_child_counter: 0, + ast_node_info_table_name: format!("{}_ast_node_info", language_prefix), + tokeninfo_table_name: format!("{}_tokeninfo", language_prefix), + schema, + stack: Vec::new(), + } + } + fn record_parse_error( &mut self, error_message: String, full_error_message: String, - loc: Label, + loc: trap::Label, ) { error!("{}", full_error_message); let id = self.trap_writer.fresh_id(); self.trap_writer.add_tuple( "diagnostics", vec![ - Arg::Label(id), - Arg::Int(40), // severity 40 = error - Arg::String("parse_error".to_string()), - Arg::String(error_message), - Arg::String(full_error_message), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Int(40), // severity 40 = error + trap::Arg::String("parse_error".to_string()), + trap::Arg::String(error_message), + trap::Arg::String(full_error_message), + trap::Arg::Label(loc), ], ); } @@ -335,7 +273,8 @@ impl Visitor<'_> { node: Node, ) { let (start_line, start_column, end_line, end_column) = location_for(self.source, node); - let loc = self.trap_writer.location( + let loc = location( + self.trap_writer, self.file_label, start_line, start_column, @@ -374,7 +313,8 @@ impl Visitor<'_> { } let (id, _, child_nodes) = self.stack.pop().expect("Vistor: empty stack"); let (start_line, start_column, end_line, end_column) = location_for(self.source, node); - let loc = self.trap_writer.location( + let loc = location( + self.trap_writer, self.file_label, start_line, start_column, @@ -402,19 +342,19 @@ impl Visitor<'_> { match &table.kind { EntryKind::Token { kind_id, .. } => { self.trap_writer.add_tuple( - &format!("{}_ast_node_info", self.language_prefix), + &self.ast_node_info_table_name, vec![ - Arg::Label(id), - Arg::Label(parent_id), - Arg::Int(parent_index), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Label(parent_id), + trap::Arg::Int(parent_index), + trap::Arg::Label(loc), ], ); self.trap_writer.add_tuple( - &format!("{}_tokeninfo", self.language_prefix), + &self.tokeninfo_table_name, vec![ - Arg::Label(id), - Arg::Int(*kind_id), + trap::Arg::Label(id), + trap::Arg::Int(*kind_id), sliced_source_arg(self.source, node), ], ); @@ -425,15 +365,15 @@ impl Visitor<'_> { } => { if let Some(args) = self.complex_node(&node, fields, &child_nodes, id) { self.trap_writer.add_tuple( - &format!("{}_ast_node_info", self.language_prefix), + &self.ast_node_info_table_name, vec![ - Arg::Label(id), - Arg::Label(parent_id), - Arg::Int(parent_index), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Label(parent_id), + trap::Arg::Int(parent_index), + trap::Arg::Label(loc), ], ); - let mut all_args = vec![Arg::Label(id)]; + let mut all_args = vec![trap::Arg::Label(id)]; all_args.extend(args); self.trap_writer.add_tuple(table_name, all_args); } @@ -472,9 +412,9 @@ impl Visitor<'_> { node: &Node, fields: &[Field], child_nodes: &[ChildNode], - parent_id: Label, - ) -> Option> { - let mut map: Map<&Option, (&Field, Vec)> = Map::new(); + parent_id: trap::Label, + ) -> Option> { + let mut map: Map<&Option, (&Field, Vec)> = Map::new(); for field in fields { map.insert(&field.name, (field, Vec::new())); } @@ -488,9 +428,9 @@ impl Visitor<'_> { { // We can safely unwrap because type_matches checks the key is in the map. let (int_value, _) = int_mapping.get(&child_node.type_name.kind).unwrap(); - values.push(Arg::Int(*int_value)); + values.push(trap::Arg::Int(*int_value)); } else { - values.push(Arg::Label(child_node.label)); + values.push(trap::Arg::Label(child_node.label)); } } else if field.name.is_some() { let error_message = format!( @@ -569,9 +509,9 @@ impl Visitor<'_> { ); break; } - let mut args = vec![Arg::Label(parent_id)]; + let mut args = vec![trap::Arg::Label(parent_id)]; if *has_index { - args.push(Arg::Int(index)) + args.push(trap::Arg::Int(index)) } args.push(child_value.clone()); self.trap_writer.add_tuple(table_name, args); @@ -625,9 +565,9 @@ impl Visitor<'_> { } // Emit a slice of a source file as an Arg. -fn sliced_source_arg(source: &[u8], n: Node) -> Arg { +fn sliced_source_arg(source: &[u8], n: Node) -> trap::Arg { let range = n.byte_range(); - Arg::String(String::from_utf8_lossy(&source[range.start..range.end]).into_owned()) + trap::Arg::String(String::from_utf8_lossy(&source[range.start..range.end]).into_owned()) } // Emit a pair of `TrapEntry`s for the provided node, appropriately calibrated. @@ -699,59 +639,6 @@ fn traverse(tree: &Tree, visitor: &mut Visitor) { } } -pub struct Program(Vec); - -impl fmt::Display for Program { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut text = String::new(); - for trap_entry in &self.0 { - text.push_str(&format!("{}\n", trap_entry)); - } - write!(f, "{}", text) - } -} - -enum TrapEntry { - /// Maps the label to a fresh id, e.g. `#123=*`. - FreshId(Label), - /// Maps the label to a key, e.g. `#7=@"foo"`. - MapLabelToKey(Label, String), - /// foo_bar(arg*) - GenericTuple(String, Vec), - Comment(String), -} -impl fmt::Display for TrapEntry { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - TrapEntry::FreshId(label) => write!(f, "{}=*", label), - TrapEntry::MapLabelToKey(label, key) => { - write!(f, "{}=@\"{}\"", label, key.replace("\"", "\"\"")) - } - TrapEntry::GenericTuple(name, args) => { - write!(f, "{}(", name)?; - for (index, arg) in args.iter().enumerate() { - if index > 0 { - write!(f, ",")?; - } - write!(f, "{}", arg)?; - } - write!(f, ")") - } - TrapEntry::Comment(line) => write!(f, "// {}", line), - } - } -} - -#[derive(Debug, Copy, Clone)] -// Identifiers of the form #0, #1... -struct Label(u32); - -impl fmt::Display for Label { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "#{:x}", self.0) - } -} - // Numeric indices. #[derive(Debug, Copy, Clone)] struct Index(usize); @@ -761,69 +648,3 @@ impl fmt::Display for Index { write!(f, "{}", self.0) } } - -// Some untyped argument to a TrapEntry. -#[derive(Debug, Clone)] -enum Arg { - Label(Label), - Int(usize), - String(String), -} - -const MAX_STRLEN: usize = 1048576; - -impl fmt::Display for Arg { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Arg::Label(x) => write!(f, "{}", x), - Arg::Int(x) => write!(f, "{}", x), - Arg::String(x) => write!( - f, - "\"{}\"", - limit_string(x, MAX_STRLEN).replace("\"", "\"\"") - ), - } - } -} - -/// Limit the length (in bytes) of a string. If the string's length in bytes is -/// less than or equal to the limit then the entire string is returned. Otherwise -/// the string is sliced at the provided limit. If there is a multi-byte character -/// at the limit then the returned slice will be slightly shorter than the limit to -/// avoid splitting that multi-byte character. -fn limit_string(string: &str, max_size: usize) -> &str { - if string.len() <= max_size { - return string; - } - let p = string.as_bytes(); - let mut index = max_size; - // We want to clip the string at [max_size]; however, the character at that position - // may span several bytes. We need to find the first byte of the character. In UTF-8 - // encoded data any byte that matches the bit pattern 10XXXXXX is not a start byte. - // Therefore we decrement the index as long as there are bytes matching this pattern. - // This ensures we cut the string at the border between one character and another. - while index > 0 && (p[index] & 0b11000000) == 0b10000000 { - index -= 1; - } - &string[0..index] -} - -#[test] -fn limit_string_test() { - assert_eq!("hello", limit_string(&"hello world".to_owned(), 5)); - assert_eq!("hi ☹", limit_string(&"hi ☹☹".to_owned(), 6)); - assert_eq!("hi ", limit_string(&"hi ☹☹".to_owned(), 5)); -} - -#[test] -fn escape_key_test() { - assert_eq!("foo!", escape_key("foo!")); - assert_eq!("foo{}", escape_key("foo{}")); - assert_eq!("{}", escape_key("{}")); - assert_eq!("", escape_key("")); - assert_eq!("/path/to/foo.rb", escape_key("/path/to/foo.rb")); - assert_eq!( - "/path/to/foo&{}"@#.rb", - escape_key("/path/to/foo&{}\"@#.rb") - ); -} diff --git a/ruby/extractor/src/main.rs b/ruby/extractor/src/main.rs index 7e4aa973518..ca1039e4e0d 100644 --- a/ruby/extractor/src/main.rs +++ b/ruby/extractor/src/main.rs @@ -1,51 +1,19 @@ mod extractor; +mod trap; +#[macro_use] +extern crate lazy_static; extern crate num_cpus; use clap::arg; -use flate2::write::GzEncoder; +use encoding::{self}; use rayon::prelude::*; +use std::borrow::Cow; use std::fs; -use std::io::{BufRead, BufWriter}; +use std::io::BufRead; use std::path::{Path, PathBuf}; use tree_sitter::{Language, Parser, Range}; -enum TrapCompression { - None, - Gzip, -} - -impl TrapCompression { - fn from_env() -> TrapCompression { - match std::env::var("CODEQL_RUBY_TRAP_COMPRESSION") { - Ok(method) => match TrapCompression::from_string(&method) { - Some(c) => c, - None => { - tracing::error!("Unknown compression method '{}'; using gzip.", &method); - TrapCompression::Gzip - } - }, - // Default compression method if the env var isn't set: - Err(_) => TrapCompression::Gzip, - } - } - - fn from_string(s: &str) -> Option { - match s.to_lowercase().as_ref() { - "none" => Some(TrapCompression::None), - "gzip" => Some(TrapCompression::Gzip), - _ => None, - } - } - - fn extension(&self) -> &str { - match self { - TrapCompression::None => "trap", - TrapCompression::Gzip => "trap.gz", - } - } -} - /** * Gets the number of threads the extractor should use, by reading the * CODEQL_THREADS environment variable and using it as described in the @@ -75,6 +43,21 @@ fn num_codeql_threads() -> usize { } } +lazy_static! { + static ref CP_NUMBER: regex::Regex = regex::Regex::new("cp([0-9]+)").unwrap(); +} + +fn encoding_from_name(encoding_name: &str) -> Option<&(dyn encoding::Encoding + Send + Sync)> { + match encoding::label::encoding_from_whatwg_label(encoding_name) { + s @ Some(_) => s, + None => CP_NUMBER.captures(encoding_name).and_then(|cap| { + encoding::label::encoding_from_windows_code_page( + str::parse(cap.get(1).unwrap().as_str()).unwrap(), + ) + }), + } +} + fn main() -> std::io::Result<()> { tracing_subscriber::fmt() .with_target(false) @@ -118,7 +101,7 @@ fn main() -> std::io::Result<()> { .value_of("output-dir") .expect("missing --output-dir"); let trap_dir = PathBuf::from(trap_dir); - let trap_compression = TrapCompression::from_env(); + let trap_compression = trap::Compression::from_env("CODEQL_RUBY_TRAP_COMPRESSION"); let file_list = matches.value_of("file-list").expect("missing --file-list"); let file_list = fs::File::open(file_list)?; @@ -140,8 +123,9 @@ fn main() -> std::io::Result<()> { let path = PathBuf::from(line).canonicalize()?; let src_archive_file = path_for(&src_archive_dir, &path, ""); let mut source = std::fs::read(&path)?; + let mut needs_conversion = false; let code_ranges; - let mut trap_writer = extractor::new_trap_writer(); + let mut trap_writer = trap::Writer::new(); if path.extension().map_or(false, |x| x == "erb") { tracing::info!("scanning: {}", path.display()); extractor::extract( @@ -168,6 +152,43 @@ fn main() -> std::io::Result<()> { } code_ranges = ranges; } else { + if let Some(encoding_name) = scan_coding_comment(&source) { + // If the input is already UTF-8 then there is no need to recode the source + // If the declared encoding is 'binary' or 'ascii-8bit' then it is not clear how + // to interpret characters. In this case it is probably best to leave the input + // unchanged. + if !encoding_name.eq_ignore_ascii_case("utf-8") + && !encoding_name.eq_ignore_ascii_case("ascii-8bit") + && !encoding_name.eq_ignore_ascii_case("binary") + { + if let Some(encoding) = encoding_from_name(&encoding_name) { + needs_conversion = + encoding.whatwg_name().unwrap_or_default() != "utf-8"; + if needs_conversion { + match encoding + .decode(&source, encoding::types::DecoderTrap::Replace) + { + Ok(str) => source = str.as_bytes().to_owned(), + Err(msg) => { + needs_conversion = false; + tracing::warn!( + "{}: character decoding failure: {} ({})", + &path.to_string_lossy(), + msg, + &encoding_name + ); + } + } + } + } else { + tracing::warn!( + "{}: unknown character encoding: '{}'", + &path.to_string_lossy(), + &encoding_name + ); + } + } + } code_ranges = vec![]; } extractor::extract( @@ -180,34 +201,30 @@ fn main() -> std::io::Result<()> { &code_ranges, )?; std::fs::create_dir_all(&src_archive_file.parent().unwrap())?; - std::fs::copy(&path, &src_archive_file)?; - write_trap(&trap_dir, path, trap_writer, &trap_compression) + if needs_conversion { + std::fs::write(&src_archive_file, &source)?; + } else { + std::fs::copy(&path, &src_archive_file)?; + } + write_trap(&trap_dir, path, &trap_writer, trap_compression) }) .expect("failed to extract files"); let path = PathBuf::from("extras"); - let mut trap_writer = extractor::new_trap_writer(); - trap_writer.populate_empty_location(); - write_trap(&trap_dir, path, trap_writer, &trap_compression) + let mut trap_writer = trap::Writer::new(); + extractor::populate_empty_location(&mut trap_writer); + write_trap(&trap_dir, path, &trap_writer, trap_compression) } fn write_trap( trap_dir: &Path, path: PathBuf, - trap_writer: extractor::TrapWriter, - trap_compression: &TrapCompression, + trap_writer: &trap::Writer, + trap_compression: trap::Compression, ) -> std::io::Result<()> { let trap_file = path_for(trap_dir, &path, trap_compression.extension()); std::fs::create_dir_all(&trap_file.parent().unwrap())?; - let trap_file = std::fs::File::create(&trap_file)?; - let mut trap_file = BufWriter::new(trap_file); - match trap_compression { - TrapCompression::None => trap_writer.output(&mut trap_file), - TrapCompression::Gzip => { - let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast()); - trap_writer.output(&mut compressed_writer) - } - } + trap_writer.write_to_file(&trap_file, trap_compression) } fn scan_erb( @@ -299,3 +316,143 @@ fn path_for(dir: &Path, path: &Path, ext: &str) -> PathBuf { } result } + +fn skip_space(content: &[u8], index: usize) -> usize { + let mut index = index; + while index < content.len() { + let c = content[index] as char; + // white space except \n + let is_space = c == ' ' || ('\t'..='\r').contains(&c) && c != '\n'; + if !is_space { + break; + } + index += 1; + } + index +} + +fn scan_coding_comment(content: &[u8]) -> std::option::Option> { + let mut index = 0; + // skip UTF-8 BOM marker if there is one + if content.len() >= 3 && content[0] == 0xef && content[1] == 0xbb && content[2] == 0xbf { + index += 3; + } + // skip #! line if there is one + if index + 1 < content.len() + && content[index] as char == '#' + && content[index + 1] as char == '!' + { + index += 2; + while index < content.len() && content[index] as char != '\n' { + index += 1 + } + index += 1 + } + index = skip_space(content, index); + + if index >= content.len() || content[index] as char != '#' { + return None; + } + index += 1; + + const CODING: [char; 12] = ['C', 'c', 'O', 'o', 'D', 'd', 'I', 'i', 'N', 'n', 'G', 'g']; + let mut word_index = 0; + while index < content.len() && word_index < CODING.len() && content[index] as char != '\n' { + if content[index] as char == CODING[word_index] + || content[index] as char == CODING[word_index + 1] + { + word_index += 2 + } else { + word_index = 0; + } + index += 1; + } + if word_index < CODING.len() { + return None; + } + index = skip_space(content, index); + + if index < content.len() && content[index] as char != ':' && content[index] as char != '=' { + return None; + } + index += 1; + index = skip_space(content, index); + + let start = index; + while index < content.len() { + let c = content[index] as char; + if c == '-' || c == '_' || c.is_ascii_alphanumeric() { + index += 1; + } else { + break; + } + } + if index > start { + return Some(String::from_utf8_lossy(&content[start..index])); + } + None +} + +#[test] +fn test_scan_coding_comment() { + let text = "# encoding: utf-8"; + let result = scan_coding_comment(text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "#coding:utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "# foo\n# encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, None); + + let text = "# encoding: latin1 encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("latin1".into())); + + let text = "# encoding: nonsense"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("nonsense".into())); + + let text = "# coding = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "# CODING = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "# CoDiNg = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "# blah blahblahcoding = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + // unicode BOM is ignored + let text = "\u{FEFF}# encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "\u{FEFF} # encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "#! /usr/bin/env ruby\n # encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "\u{FEFF}#! /usr/bin/env ruby\n # encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + // A #! must be the first thing on a line, otherwise it's a normal comment + let text = " #! /usr/bin/env ruby encoding = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + let text = " #! /usr/bin/env ruby \n # encoding = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, None); +} diff --git a/ruby/extractor/src/trap.rs b/ruby/extractor/src/trap.rs new file mode 100644 index 00000000000..35a9b69f255 --- /dev/null +++ b/ruby/extractor/src/trap.rs @@ -0,0 +1,275 @@ +use std::borrow::Cow; +use std::fmt; +use std::io::{BufWriter, Write}; +use std::path::Path; + +use flate2::write::GzEncoder; + +pub struct Writer { + /// The accumulated trap entries + trap_output: Vec, + /// A counter for generating fresh labels + counter: u32, + /// cache of global keys + global_keys: std::collections::HashMap, +} + +impl Writer { + pub fn new() -> Writer { + Writer { + counter: 0, + trap_output: Vec::new(), + global_keys: std::collections::HashMap::new(), + } + } + + pub fn fresh_id(&mut self) -> Label { + let label = Label(self.counter); + self.counter += 1; + self.trap_output.push(Entry::FreshId(label)); + label + } + + /// Gets a label that will hold the unique ID of the passed string at import time. + /// This can be used for incrementally importable TRAP files -- use globally unique + /// strings to compute a unique ID for table tuples. + /// + /// Note: You probably want to make sure that the key strings that you use are disjoint + /// for disjoint column types; the standard way of doing this is to prefix (or append) + /// the column type name to the ID. Thus, you might identify methods in Java by the + /// full ID "methods_com.method.package.DeclaringClass.method(argumentList)". + pub fn global_id(&mut self, key: &str) -> (Label, bool) { + if let Some(label) = self.global_keys.get(key) { + return (*label, false); + } + let label = Label(self.counter); + self.counter += 1; + self.global_keys.insert(key.to_owned(), label); + self.trap_output + .push(Entry::MapLabelToKey(label, key.to_owned())); + (label, true) + } + + pub fn add_tuple(&mut self, table_name: &str, args: Vec) { + self.trap_output + .push(Entry::GenericTuple(table_name.to_owned(), args)) + } + + pub fn comment(&mut self, text: String) { + self.trap_output.push(Entry::Comment(text)); + } + + pub fn write_to_file(&self, path: &Path, compression: Compression) -> std::io::Result<()> { + let trap_file = std::fs::File::create(path)?; + match compression { + Compression::None => { + let mut trap_file = BufWriter::new(trap_file); + self.write_trap_entries(&mut trap_file) + } + Compression::Gzip => { + let trap_file = GzEncoder::new(trap_file, flate2::Compression::fast()); + let mut trap_file = BufWriter::new(trap_file); + self.write_trap_entries(&mut trap_file) + } + } + } + + fn write_trap_entries(&self, file: &mut W) -> std::io::Result<()> { + for trap_entry in &self.trap_output { + writeln!(file, "{}", trap_entry)?; + } + std::io::Result::Ok(()) + } +} + +pub enum Entry { + /// Maps the label to a fresh id, e.g. `#123=*`. + FreshId(Label), + /// Maps the label to a key, e.g. `#7=@"foo"`. + MapLabelToKey(Label, String), + /// foo_bar(arg*) + GenericTuple(String, Vec), + Comment(String), +} + +impl fmt::Display for Entry { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Entry::FreshId(label) => write!(f, "{}=*", label), + Entry::MapLabelToKey(label, key) => { + write!(f, "{}=@\"{}\"", label, key.replace("\"", "\"\"")) + } + Entry::GenericTuple(name, args) => { + write!(f, "{}(", name)?; + for (index, arg) in args.iter().enumerate() { + if index > 0 { + write!(f, ",")?; + } + write!(f, "{}", arg)?; + } + write!(f, ")") + } + Entry::Comment(line) => write!(f, "// {}", line), + } + } +} + +#[derive(Debug, Copy, Clone)] +// Identifiers of the form #0, #1... +pub struct Label(u32); + +impl fmt::Display for Label { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "#{:x}", self.0) + } +} + +// Some untyped argument to a TrapEntry. +#[derive(Debug, Clone)] +pub enum Arg { + Label(Label), + Int(usize), + String(String), +} + +const MAX_STRLEN: usize = 1048576; + +impl fmt::Display for Arg { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Arg::Label(x) => write!(f, "{}", x), + Arg::Int(x) => write!(f, "{}", x), + Arg::String(x) => write!( + f, + "\"{}\"", + limit_string(x, MAX_STRLEN).replace("\"", "\"\"") + ), + } + } +} + +pub struct Program(Vec); + +impl fmt::Display for Program { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut text = String::new(); + for trap_entry in &self.0 { + text.push_str(&format!("{}\n", trap_entry)); + } + write!(f, "{}", text) + } +} + +pub fn full_id_for_file(normalized_path: &str) -> String { + format!("{};sourcefile", escape_key(normalized_path)) +} + +pub fn full_id_for_folder(normalized_path: &str) -> String { + format!("{};folder", escape_key(normalized_path)) +} + +/// Escapes a string for use in a TRAP key, by replacing special characters with +/// HTML entities. +fn escape_key<'a, S: Into>>(key: S) -> Cow<'a, str> { + fn needs_escaping(c: char) -> bool { + matches!(c, '&' | '{' | '}' | '"' | '@' | '#') + } + + let key = key.into(); + if key.contains(needs_escaping) { + let mut escaped = String::with_capacity(2 * key.len()); + for c in key.chars() { + match c { + '&' => escaped.push_str("&"), + '{' => escaped.push_str("{"), + '}' => escaped.push_str("}"), + '"' => escaped.push_str("""), + '@' => escaped.push_str("@"), + '#' => escaped.push_str("#"), + _ => escaped.push(c), + } + } + Cow::Owned(escaped) + } else { + key + } +} + +/// Limit the length (in bytes) of a string. If the string's length in bytes is +/// less than or equal to the limit then the entire string is returned. Otherwise +/// the string is sliced at the provided limit. If there is a multi-byte character +/// at the limit then the returned slice will be slightly shorter than the limit to +/// avoid splitting that multi-byte character. +fn limit_string(string: &str, max_size: usize) -> &str { + if string.len() <= max_size { + return string; + } + let p = string.as_bytes(); + let mut index = max_size; + // We want to clip the string at [max_size]; however, the character at that position + // may span several bytes. We need to find the first byte of the character. In UTF-8 + // encoded data any byte that matches the bit pattern 10XXXXXX is not a start byte. + // Therefore we decrement the index as long as there are bytes matching this pattern. + // This ensures we cut the string at the border between one character and another. + while index > 0 && (p[index] & 0b11000000) == 0b10000000 { + index -= 1; + } + &string[0..index] +} + +#[derive(Clone, Copy)] +pub enum Compression { + None, + Gzip, +} + +impl Compression { + pub fn from_env(var_name: &str) -> Compression { + match std::env::var(var_name) { + Ok(method) => match Compression::from_string(&method) { + Some(c) => c, + None => { + tracing::error!("Unknown compression method '{}'; using gzip.", &method); + Compression::Gzip + } + }, + // Default compression method if the env var isn't set: + Err(_) => Compression::Gzip, + } + } + + pub fn from_string(s: &str) -> Option { + match s.to_lowercase().as_ref() { + "none" => Some(Compression::None), + "gzip" => Some(Compression::Gzip), + _ => None, + } + } + + pub fn extension(&self) -> &str { + match self { + Compression::None => "trap", + Compression::Gzip => "trap.gz", + } + } +} + +#[test] +fn limit_string_test() { + assert_eq!("hello", limit_string(&"hello world".to_owned(), 5)); + assert_eq!("hi ☹", limit_string(&"hi ☹☹".to_owned(), 6)); + assert_eq!("hi ", limit_string(&"hi ☹☹".to_owned(), 5)); +} + +#[test] +fn escape_key_test() { + assert_eq!("foo!", escape_key("foo!")); + assert_eq!("foo{}", escape_key("foo{}")); + assert_eq!("{}", escape_key("{}")); + assert_eq!("", escape_key("")); + assert_eq!("/path/to/foo.rb", escape_key("/path/to/foo.rb")); + assert_eq!( + "/path/to/foo&{}"@#.rb", + escape_key("/path/to/foo&{}\"@#.rb") + ); +} diff --git a/ruby/generator/Cargo.toml b/ruby/generator/Cargo.toml index 19c4862d4d1..5a70c43d7b3 100644 --- a/ruby/generator/Cargo.toml +++ b/ruby/generator/Cargo.toml @@ -12,4 +12,4 @@ node-types = { path = "../node-types" } tracing = "0.1" tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "1a538da253d73f896b9f6c0c7d79cda58791ac5c" } -tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "6334d6ab3d04a5672da695d3b155ca3301511f8d" } +tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "e75d04404c9dd71ad68850d5c672b226d5e694f3" } diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 2da583dd23c..fe8a12aa938 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,5 +1,24 @@ +## 0.3.1 + +### Minor Analysis Improvements + +* Fixed a bug causing every expression in the database to be considered a system-command execution sink when calls to any of the following methods exist: + * The `spawn`, `fspawn`, `popen4`, `pspawn`, `system`, `_pspawn` methods and the backtick operator from the `POSIX::spawn` gem. + * The `execute_command`, `rake`, `rails_command`, and `git` methods in `Rails::Generation::Actions`. +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). + +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + ## 0.2.3 +### Minor Analysis Improvements + +- Calls to `Zip::File.open` and `Zip::File.new` have been added as `FileSystemAccess` sinks. As a result queries like `rb/path-injection` now flag up cases where users may access arbitrary archive files. + ## 0.2.2 ### Major Analysis Improvements diff --git a/ruby/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/ruby/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md deleted file mode 100644 index 2bd95798f89..00000000000 --- a/ruby/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -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/ruby/ql/lib/change-notes/2022-06-22-sensitive-common-words.md b/ruby/ql/lib/change-notes/2022-06-22-sensitive-common-words.md deleted file mode 100644 index 9102d58abdb..00000000000 --- a/ruby/ql/lib/change-notes/2022-06-22-sensitive-common-words.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). diff --git a/ruby/ql/lib/change-notes/2022-07-18-sqli-in-activerecord-relation-annotate.md b/ruby/ql/lib/change-notes/2022-07-18-sqli-in-activerecord-relation-annotate.md new file mode 100644 index 00000000000..60ab137f8b2 --- /dev/null +++ b/ruby/ql/lib/change-notes/2022-07-18-sqli-in-activerecord-relation-annotate.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- + +- Calls to `ActiveRecord::Relation#annotate` are now recognized as`SqlExecution`s so that it will be considered as a sink for queries like rb/sql-injection. \ No newline at end of file diff --git a/ruby/ql/lib/change-notes/2022-07-19-arel.md b/ruby/ql/lib/change-notes/2022-07-19-arel.md new file mode 100644 index 00000000000..3dda3d4b1f6 --- /dev/null +++ b/ruby/ql/lib/change-notes/2022-07-19-arel.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Calls to `Arel.sql` are now recognised as propagating taint from their argument. diff --git a/csharp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/ruby/ql/lib/change-notes/released/0.3.0.md similarity index 83% rename from csharp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md rename to ruby/ql/lib/change-notes/released/0.3.0.md index 2bd95798f89..54af6e00ac0 100644 --- a/csharp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ b/ruby/ql/lib/change-notes/released/0.3.0.md @@ -1,4 +1,5 @@ ---- -category: deprecated ---- +## 0.3.0 + +### Deprecated APIs + * The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/ruby/ql/lib/change-notes/released/0.3.1.md b/ruby/ql/lib/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..59f378bbb32 --- /dev/null +++ b/ruby/ql/lib/change-notes/released/0.3.1.md @@ -0,0 +1,8 @@ +## 0.3.1 + +### Minor Analysis Improvements + +* Fixed a bug causing every expression in the database to be considered a system-command execution sink when calls to any of the following methods exist: + * The `spawn`, `fspawn`, `popen4`, `pspawn`, `system`, `_pspawn` methods and the backtick operator from the `POSIX::spawn` gem. + * The `execute_command`, `rake`, `rails_command`, and `git` methods in `Rails::Generation::Actions`. +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 0b605901b42..bb106b1cb63 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.3 +lastReleaseVersion: 0.3.1 diff --git a/ruby/ql/lib/codeql/ruby/Frameworks.qll b/ruby/ql/lib/codeql/ruby/Frameworks.qll index 87b8a3f61a2..69ba758a767 100644 --- a/ruby/ql/lib/codeql/ruby/Frameworks.qll +++ b/ruby/ql/lib/codeql/ruby/Frameworks.qll @@ -10,6 +10,7 @@ private import codeql.ruby.frameworks.ActiveStorage private import codeql.ruby.frameworks.ActionView private import codeql.ruby.frameworks.ActiveSupport private import codeql.ruby.frameworks.Archive +private import codeql.ruby.frameworks.Arel private import codeql.ruby.frameworks.GraphQL private import codeql.ruby.frameworks.Rails private import codeql.ruby.frameworks.Railties diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll index fb7cb3737b9..53355695e57 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll @@ -36,7 +36,7 @@ private import ExprNodes * constant value in some cases. */ private module Propagation { - private ExprCfgNode getSource(VariableReadAccessCfgNode read) { + ExprCfgNode getSource(VariableReadAccessCfgNode read) { exists(Ssa::WriteDefinition def | def.assigns(result) and read = def.getARead() @@ -509,3 +509,53 @@ private module Cached { } import Cached + +/** + * Holds if the control flow node `e` refers to an array constructed from the + * array literal `arr`. + * Example: + * ```rb + * [1, 2, 3] + * C = [1, 2, 3]; C + * x = [1, 2, 3]; x + * ``` + */ +predicate isArrayConstant(ExprCfgNode e, ArrayLiteralCfgNode arr) { + // [...] + e = arr + or + // e = [...]; e + isArrayConstant(getSource(e), arr) + or + isArrayExpr(e.getExpr(), arr) +} + +/** + * Holds if the expression `e` refers to an array constructed from the array literal `arr`. + */ +private predicate isArrayExpr(Expr e, ArrayLiteralCfgNode arr) { + // e = [...] + e = arr.getExpr() + or + // Like above, but handles the desugaring of array literals to Array.[] calls. + e.getDesugared() = arr.getExpr() + or + // A = [...]; A + // A = a; A + isArrayExpr(e.(ConstantReadAccess).getValue(), arr) + or + // Recurse via CFG nodes. Necessary for example in: + // a = [...] + // A = a + // A + // + // We map from A to a via ConstantReadAccess::getValue, yielding the Expr a. + // To get to [...] we need to go via getSource(ExprCfgNode e), so we find a + // CFG node for a and call `isArrayConstant`. + // + // The use of `forex` is intended to ensure that a is an array constant in all + // control flow paths. + // Note(hmac): I don't think this is necessary, as `getSource` will not return + // results if the source is a phi node. + forex(ExprCfgNode n | n = e.getAControlFlowNode() | isArrayConstant(n, arr)) +} diff --git a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll index efb69af39eb..29668b82e70 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll @@ -374,6 +374,9 @@ module ExprNodes { MethodCallCfgNode() { super.getExpr() instanceof MethodCall } override MethodCall getExpr() { result = super.getExpr() } + + /** Gets the name of this method call. */ + string getMethodName() { result = this.getExpr().getMethodName() } } private class CaseExprChildMapping extends ExprChildMapping, CaseExpr { diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll index 47fcd24883c..7d0dd10c084 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll @@ -881,7 +881,12 @@ import Cached * graph is restricted to nodes from `RelevantNode`. */ module TestOutput { - abstract class RelevantNode extends Node { } + abstract class RelevantNode extends Node { + /** + * Gets a string used to resolve ties in node and edge ordering. + */ + string getOrderDisambuigation() { result = "" } + } query predicate nodes(RelevantNode n, string attr, string val) { attr = "semmle.order" and @@ -894,7 +899,8 @@ module TestOutput { p order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString(), + p.getOrderDisambuigation() ) ).toString() } @@ -916,7 +922,8 @@ module TestOutput { s order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString(), + s.getOrderDisambuigation() ) ).toString() } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index d55bd9af278..c79e4311489 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -3,6 +3,10 @@ private import ruby private import codeql.ruby.DataFlow private import codeql.ruby.CFG +private import codeql.ruby.controlflow.CfgNodes +private import codeql.ruby.dataflow.SSA +private import codeql.ruby.ast.internal.Constant +private import codeql.ruby.InclusionTests private predicate stringConstCompare(CfgNodes::ExprCfgNode g, CfgNode e, boolean branch) { exists(CfgNodes::ExprNodes::ComparisonOperationCfgNode c | @@ -61,19 +65,7 @@ deprecated class StringConstCompare extends DataFlow::BarrierGuard, // The value of the condition that results in the node being validated. private boolean checkedBranch; - StringConstCompare() { - exists(CfgNodes::ExprNodes::StringLiteralCfgNode strLitNode | - this.getExpr() instanceof EqExpr and checkedBranch = true - or - this.getExpr() instanceof CaseEqExpr and checkedBranch = true - or - this.getExpr() instanceof NEExpr and checkedBranch = false - | - this.getLeftOperand() = strLitNode and this.getRightOperand() = checkedNode - or - this.getLeftOperand() = checkedNode and this.getRightOperand() = strLitNode - ) - } + StringConstCompare() { stringConstCompare(this, checkedNode, checkedBranch) } override predicate checks(CfgNode expr, boolean branch) { expr = checkedNode and branch = checkedBranch @@ -81,15 +73,19 @@ deprecated class StringConstCompare extends DataFlow::BarrierGuard, } private predicate stringConstArrayInclusionCall(CfgNodes::ExprCfgNode g, CfgNode e, boolean branch) { - exists(CfgNodes::ExprNodes::MethodCallCfgNode mc, ArrayLiteral aLit | - mc = g and - mc.getExpr().getMethodName() = "include?" and - [mc.getExpr().getReceiver(), mc.getExpr().getReceiver().(ConstantReadAccess).getValue()] = aLit + exists(InclusionTest t | + t.asExpr() = g and + e = t.getContainedNode().asExpr() and + branch = t.getPolarity() | - forall(Expr elem | elem = aLit.getAnElement() | elem instanceof StringLiteral) and - mc.getArgument(0) = e - ) and - branch = true + exists(ExprNodes::ArrayLiteralCfgNode arr | + isArrayConstant(t.getContainerNode().asExpr(), arr) + | + forall(ExprCfgNode elem | elem = arr.getAnArgument() | + elem instanceof ExprNodes::StringLiteralCfgNode + ) + ) + ) } /** @@ -132,16 +128,7 @@ deprecated class StringConstArrayInclusionCall extends DataFlow::BarrierGuard, CfgNodes::ExprNodes::MethodCallCfgNode { private CfgNode checkedNode; - StringConstArrayInclusionCall() { - exists(ArrayLiteral aLit | - this.getExpr().getMethodName() = "include?" and - [this.getExpr().getReceiver(), this.getExpr().getReceiver().(ConstantReadAccess).getValue()] = - aLit - | - forall(Expr elem | elem = aLit.getAnElement() | elem instanceof StringLiteral) and - this.getArgument(0) = checkedNode - ) - } + StringConstArrayInclusionCall() { stringConstArrayInclusionCall(this, checkedNode, true) } override predicate checks(CfgNode expr, boolean branch) { expr = checkedNode and branch = true } } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 7b9e78d2c4b..a076f7a2e45 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index 7b9e78d2c4b..a076f7a2e45 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll index 7b9e78d2c4b..a076f7a2e45 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index b69a7cdb5c2..142d1455ce4 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -133,6 +133,11 @@ private Expr sqlFragmentArgument(MethodCall call) { or methodName = "reload" and result = call.getKeywordArgument("lock") + or + // Calls to `annotate` can be used to add block comments to SQL queries. These are potentially vulnerable to + // SQLi if user supplied input is passed in as an argument. + methodName = "annotate" and + result = call.getArgument(_) ) ) } @@ -330,12 +335,13 @@ class ActiveRecordInstance extends DataFlow::Node { ActiveRecordModelClass getClass() { result = instantiation.getClass() } } -// A call whose receiver may be an active record model object -private class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { +/** A call whose receiver may be an active record model object */ +class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { private ActiveRecordInstance instance; ActiveRecordInstanceMethodCall() { this.getReceiver() = instance } + /** Gets the `ActiveRecordInstance` that is the receiver of this call. */ ActiveRecordInstance getInstance() { result = instance } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll b/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll new file mode 100644 index 00000000000..9fa17f4e5a5 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll @@ -0,0 +1,31 @@ +/** + * Provides modeling for Arel, a low level SQL library that powers ActiveRecord. + * Version: 7.0.3 + * https://api.rubyonrails.org/classes/Arel.html + */ + +private import codeql.ruby.ApiGraphs +private import codeql.ruby.dataflow.FlowSummary + +/** + * Provides modeling for Arel, a low level SQL library that powers ActiveRecord. + * Version: 7.0.3 + * https://api.rubyonrails.org/classes/Arel.html + */ +module Arel { + /** + * Flow summary for `Arel.sql`. This method wraps a SQL string, marking it as + * safe. + */ + private class SqlSummary extends SummarizedCallable { + SqlSummary() { this = "Arel.sql" } + + override MethodCall getACall() { + result = API::getTopLevelMember("Arel").getAMethodCall("sql").asExpr().getExpr() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and output = "ReturnValue" and preservesValue = false + } + } +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll b/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll index 6a27018fcf5..6c4d2ab1a47 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll @@ -62,9 +62,9 @@ module PosixSpawn { // is shell interpreted unless there is another argument with a string // constant value. override predicate isShellInterpreted(DataFlow::Node arg) { + this.argument(arg) and not exists(DataFlow::Node otherArg | otherArg != arg and - this.argument(arg) and this.argument(otherArg) and otherArg.asExpr().getConstantValue().isString(_) ) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll b/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll index 4a61eb1dd20..807cc9f9c51 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll @@ -43,7 +43,7 @@ module Railties { override DataFlow::Node getAnArgument() { result = this.getArgument([0, 1]) } - override predicate isShellInterpreted(DataFlow::Node arg) { any() } + override predicate isShellInterpreted(DataFlow::Node arg) { arg = this.getAnArgument() } } /** @@ -57,6 +57,6 @@ module Railties { override DataFlow::Node getAnArgument() { result = this.getArgument(0) } - override predicate isShellInterpreted(DataFlow::Node arg) { any() } + override predicate isShellInterpreted(DataFlow::Node arg) { arg = this.getAnArgument() } } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Stdlib.qll b/ruby/ql/lib/codeql/ruby/frameworks/Stdlib.qll index 11c993b1170..f735f9daf8b 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Stdlib.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Stdlib.qll @@ -4,3 +4,4 @@ import stdlib.Open3 import stdlib.Logger +import stdlib.Pathname diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll new file mode 100644 index 00000000000..b6381c448ec --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll @@ -0,0 +1,188 @@ +/** Modeling of the `Pathname` class from the Ruby standard library. */ + +private import codeql.ruby.AST +private import codeql.ruby.ApiGraphs +private import codeql.ruby.Concepts +private import codeql.ruby.DataFlow +private import codeql.ruby.dataflow.FlowSummary +private import codeql.ruby.dataflow.internal.DataFlowDispatch +private import codeql.ruby.frameworks.data.ModelsAsData + +/** + * Modeling of the `Pathname` class from the Ruby standard library. + * + * https://docs.ruby-lang.org/en/3.1/Pathname.html + */ +module Pathname { + /** + * An instance of the `Pathname` class. For example, in + * + * ```rb + * pn = Pathname.new "foo.txt'" + * puts pn.read + * ``` + * + * there are three `PathnameInstance`s - the call to `Pathname.new`, the + * assignment `pn = ...`, and the read access to `pn` on the second line. + * + * Every `PathnameInstance` is considered to be a `FileNameSource`. + */ + class PathnameInstance extends FileNameSource, DataFlow::Node { + PathnameInstance() { this = pathnameInstance() } + } + + private DataFlow::Node pathnameInstance() { + // A call to `Pathname.new`. + result = API::getTopLevelMember("Pathname").getAnInstantiation() + or + // Class methods on `Pathname` that return a new `Pathname`. + result = API::getTopLevelMember("Pathname").getAMethodCall(["getwd", "pwd",]) + or + // Instance methods on `Pathname` that return a new `Pathname`. + exists(DataFlow::CallNode c | result = c | + c.getReceiver() = pathnameInstance() and + c.getMethodName() = + [ + "+", "/", "basename", "cleanpath", "expand_path", "join", "realpath", + "relative_path_from", "sub", "sub_ext", "to_path" + ] + ) + or + exists(DataFlow::Node inst | + inst = pathnameInstance() and + inst.(DataFlow::LocalSourceNode).flowsTo(result) + ) + } + + /** A call where the receiver is a `Pathname`. */ + class PathnameCall extends DataFlow::CallNode { + PathnameCall() { this.getReceiver() instanceof PathnameInstance } + } + + /** + * A call to `Pathname#open` or `Pathname#opendir`, considered as a + * `FileSystemAccess`. + */ + class PathnameOpen extends FileSystemAccess::Range, PathnameCall { + PathnameOpen() { this.getMethodName() = ["open", "opendir"] } + + override DataFlow::Node getAPathArgument() { result = this.getReceiver() } + } + + /** A call to `Pathname#read`, considered as a `FileSystemReadAccess`. */ + class PathnameRead extends FileSystemReadAccess::Range, PathnameCall { + PathnameRead() { this.getMethodName() = "read" } + + // The path is the receiver (the `Pathname` object). + override DataFlow::Node getAPathArgument() { result = this.getReceiver() } + + // The read data is the return value of the call. + override DataFlow::Node getADataNode() { result = this } + } + + /** A call to `Pathname#write`, considered as a `FileSystemWriteAccess`. */ + class PathnameWrite extends FileSystemWriteAccess::Range, PathnameCall { + PathnameWrite() { this.getMethodName() = "write" } + + // The path is the receiver (the `Pathname` object). + override DataFlow::Node getAPathArgument() { result = this.getReceiver() } + + // The data to write is the 0th argument. + override DataFlow::Node getADataNode() { result = this.getArgument(0) } + } + + /** A call to `Pathname#to_s`, considered as a `FileNameSource`. */ + class PathnameToSFilenameSource extends FileNameSource, PathnameCall { + PathnameToSFilenameSource() { this.getMethodName() = "to_s" } + } + + private class PathnamePermissionModification extends FileSystemPermissionModification::Range, + PathnameCall { + private DataFlow::Node permissionArg; + + PathnamePermissionModification() { + exists(string methodName | this.getMethodName() = methodName | + methodName = ["chmod", "mkdir"] and permissionArg = this.getArgument(0) + or + methodName = "mkpath" and permissionArg = this.getKeywordArgument("mode") + or + methodName = "open" and permissionArg = this.getArgument(1) + // TODO: defaults for optional args? This may depend on the umask + ) + } + + override DataFlow::Node getAPermissionNode() { result = permissionArg } + } + + /** + * Type summaries for the `Pathname` class, i.e. method calls that produce new + * `Pathname` instances. + */ + private class PathnameTypeSummary extends ModelInput::TypeModelCsv { + override predicate row(string row) { + // package1;type1;package2;type2;path + row = + [ + // Pathname.new : Pathname + ";Pathname;;;Member[Pathname].Instance", + // Pathname#+(path) : Pathname + ";Pathname;;Pathname;Method[+].ReturnValue", + // Pathname#/(path) : Pathname + ";Pathname;;Pathname;Method[/].ReturnValue", + // Pathname#basename(path) : Pathname + ";Pathname;;Pathname;Method[basename].ReturnValue", + // Pathname#cleanpath(path) : Pathname + ";Pathname;;Pathname;Method[cleanpath].ReturnValue", + // Pathname#expand_path(path) : Pathname + ";Pathname;;Pathname;Method[expand_path].ReturnValue", + // Pathname#join(path) : Pathname + ";Pathname;;Pathname;Method[join].ReturnValue", + // Pathname#realpath(path) : Pathname + ";Pathname;;Pathname;Method[realpath].ReturnValue", + // Pathname#relative_path_from(path) : Pathname + ";Pathname;;Pathname;Method[relative_path_from].ReturnValue", + // Pathname#sub(path) : Pathname + ";Pathname;;Pathname;Method[sub].ReturnValue", + // Pathname#sub_ext(path) : Pathname + ";Pathname;;Pathname;Method[sub_ext].ReturnValue", + // Pathname#to_path(path) : Pathname + ";Pathname;;Pathname;Method[to_path].ReturnValue", + ] + } + } + + /** Taint flow summaries for the `Pathname` class. */ + private class PathnameTaintSummary extends ModelInput::SummaryModelCsv { + override predicate row(string row) { + row = + [ + // Pathname.new(path) + ";;Member[Pathname].Method[new];Argument[0];ReturnValue;taint", + // Pathname#dirname + ";Pathname;Method[dirname];Argument[self];ReturnValue;taint", + // Pathname#each_filename + ";Pathname;Method[each_filename];Argument[self];Argument[block].Parameter[0];taint", + // Pathname#expand_path + ";Pathname;Method[expand_path];Argument[self];ReturnValue;taint", + // Pathname#join + ";Pathname;Method[join];Argument[self,any];ReturnValue;taint", + // Pathname#parent + ";Pathname;Method[parent];Argument[self];ReturnValue;taint", + // Pathname#realpath + ";Pathname;Method[realpath];Argument[self];ReturnValue;taint", + // Pathname#relative_path_from + ";Pathname;Method[relative_path_from];Argument[self];ReturnValue;taint", + // Pathname#to_path + ";Pathname;Method[to_path];Argument[self];ReturnValue;taint", + // Pathname#basename + ";Pathname;Method[basename];Argument[self];ReturnValue;taint", + // Pathname#cleanpath + ";Pathname;Method[cleanpath];Argument[self];ReturnValue;taint", + // Pathname#sub + ";Pathname;Method[sub];Argument[self];ReturnValue;taint", + // Pathname#sub_ext + ";Pathname;Method[sub_ext];Argument[self];ReturnValue;taint", + ] + } + } +} diff --git a/ruby/ql/src/ide-contextual-queries/localDefinitions.ql b/ruby/ql/lib/ide-contextual-queries/localDefinitions.ql similarity index 100% rename from ruby/ql/src/ide-contextual-queries/localDefinitions.ql rename to ruby/ql/lib/ide-contextual-queries/localDefinitions.ql diff --git a/ruby/ql/src/ide-contextual-queries/localReferences.ql b/ruby/ql/lib/ide-contextual-queries/localReferences.ql similarity index 100% rename from ruby/ql/src/ide-contextual-queries/localReferences.ql rename to ruby/ql/lib/ide-contextual-queries/localReferences.ql diff --git a/ruby/ql/src/ide-contextual-queries/printAst.ql b/ruby/ql/lib/ide-contextual-queries/printAst.ql similarity index 100% rename from ruby/ql/src/ide-contextual-queries/printAst.ql rename to ruby/ql/lib/ide-contextual-queries/printAst.ql diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index cf53cc3484e..8216fedd9d2 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.3.0-dev +version: 0.3.2-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index d507f26cb11..9f227fdc843 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,19 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/ruby-all` package. + +## 0.2.0 + +### New Queries + +* Added a new query, `rb/improper-memoization`. The query finds cases where the parameter of a memoization method is not used in the memoization key. + +### Minor Analysis Improvements + +* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now reports if a cryptographic operation is potentially insecure due to use of a weak block mode. + ## 0.1.4 ## 0.1.3 diff --git a/ruby/ql/src/change-notes/2022-05-16-broken-crypto-message.md b/ruby/ql/src/change-notes/2022-05-16-broken-crypto-message.md deleted file mode 100644 index 9f851c54819..00000000000 --- a/ruby/ql/src/change-notes/2022-05-16-broken-crypto-message.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. diff --git a/ruby/ql/src/change-notes/2022-05-24-improper-memoization.md b/ruby/ql/src/change-notes/2022-05-24-improper-memoization.md deleted file mode 100644 index 940c6ab102a..00000000000 --- a/ruby/ql/src/change-notes/2022-05-24-improper-memoization.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: newQuery ---- -* Added a new query, `rb/improper-memoization`. The query finds cases where the parameter of a memoization method is not used in the memoization key. diff --git a/ruby/ql/src/change-notes/2022-07-21-check-http-verb.md b/ruby/ql/src/change-notes/2022-07-21-check-http-verb.md new file mode 100644 index 00000000000..4a670ba1092 --- /dev/null +++ b/ruby/ql/src/change-notes/2022-07-21-check-http-verb.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new experimental query, `rb/manually-checking-http-verb`, to detect cases when the HTTP verb for an incoming request is checked and then used as part of control flow. \ No newline at end of file diff --git a/ruby/ql/src/change-notes/2022-07-21-weak-params.md b/ruby/ql/src/change-notes/2022-07-21-weak-params.md new file mode 100644 index 00000000000..08b8f153989 --- /dev/null +++ b/ruby/ql/src/change-notes/2022-07-21-weak-params.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new experimental query, `rb/weak-params`, to detect cases when the rails strong parameters pattern isn't followed and values flow into persistent store writes. \ No newline at end of file diff --git a/ruby/ql/src/change-notes/released/0.2.0.md b/ruby/ql/src/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..4e00c192dce --- /dev/null +++ b/ruby/ql/src/change-notes/released/0.2.0.md @@ -0,0 +1,9 @@ +## 0.2.0 + +### New Queries + +* Added a new query, `rb/improper-memoization`. The query finds cases where the parameter of a memoization method is not used in the memoization key. + +### Minor Analysis Improvements + +* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now reports if a cryptographic operation is potentially insecure due to use of a weak block mode. diff --git a/ruby/ql/src/change-notes/released/0.3.0.md b/ruby/ql/src/change-notes/released/0.3.0.md new file mode 100644 index 00000000000..717a3a27aa5 --- /dev/null +++ b/ruby/ql/src/change-notes/released/0.3.0.md @@ -0,0 +1,5 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/ruby-all` package. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index e8ee3af8ef9..95f6e3a0ba6 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.3.0 diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp new file mode 100644 index 00000000000..d50c7f0bf30 --- /dev/null +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp @@ -0,0 +1,23 @@ + + + +

    + Manually checking the HTTP request verb inside of a controller method can lead to + CSRF bypass if GET or HEAD requests are handled improperly. +

    +
    + +

    + It is better to use different controller methods for each resource/http verb combination + and configure the Rails routes in your application to call them accordingly. +

    +
    + + +
  • + See https://guides.rubyonrails.org/routing.html for more information. +
  • +
    +
    diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql new file mode 100644 index 00000000000..2ddf7fe87b3 --- /dev/null +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -0,0 +1,96 @@ +/** + * @name Manually checking http verb instead of using built in rails routes and protections + * @description Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. + * @kind path-problem + * @problem.severity error + * @security-severity 5.0 + * @precision low + * @id rb/manually-checking-http-verb + * @tags security + */ + +import ruby +import codeql.ruby.DataFlow +import codeql.ruby.controlflow.CfgNodes +import codeql.ruby.frameworks.ActionController +import codeql.ruby.TaintTracking +import DataFlow::PathGraph + +// any `request` calls in an action method +class Request extends DataFlow::CallNode { + Request() { + this.getMethodName() = "request" and + this.asExpr().getExpr().getEnclosingMethod() instanceof ActionControllerActionMethod + } +} + +// `request.env` +class RequestEnvMethod extends DataFlow::CallNode { + RequestEnvMethod() { + this.getMethodName() = "env" and + any(Request r).flowsTo(this.getReceiver()) + } +} + +// `request.request_method` +class RequestRequestMethod extends DataFlow::CallNode { + RequestRequestMethod() { + this.getMethodName() = "request_method" and + any(Request r).flowsTo(this.getReceiver()) + } +} + +// `request.method` +class RequestMethod extends DataFlow::CallNode { + RequestMethod() { + this.getMethodName() = "method" and + any(Request r).flowsTo(this.getReceiver()) + } +} + +// `request.raw_request_method` +class RequestRawRequestMethod extends DataFlow::CallNode { + RequestRawRequestMethod() { + this.getMethodName() = "raw_request_method" and + any(Request r).flowsTo(this.getReceiver()) + } +} + +// `request.request_method_symbol` +class RequestRequestMethodSymbol extends DataFlow::CallNode { + RequestRequestMethodSymbol() { + this.getMethodName() = "request_method_symbol" and + any(Request r).flowsTo(this.getReceiver()) + } +} + +// `request.get?` +class RequestGet extends DataFlow::CallNode { + RequestGet() { + this.getMethodName() = "get?" and + any(Request r).flowsTo(this.getReceiver()) + } +} + +class HttpVerbConfig extends TaintTracking::Configuration { + HttpVerbConfig() { this = "HttpVerbConfig" } + + override predicate isSource(DataFlow::Node source) { + source instanceof RequestMethod or + source instanceof RequestRequestMethod or + source instanceof RequestEnvMethod or + source instanceof RequestRawRequestMethod or + source instanceof RequestRequestMethodSymbol or + source instanceof RequestGet + } + + override predicate isSink(DataFlow::Node sink) { + exists(ExprNodes::ConditionalExprCfgNode c | c.getCondition() = sink.asExpr()) or + exists(ExprNodes::CaseExprCfgNode c | c.getValue() = sink.asExpr()) + } +} + +from HttpVerbConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, + "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.qhelp b/ruby/ql/src/experimental/weak-params/WeakParams.qhelp new file mode 100644 index 00000000000..9bccf15d03d --- /dev/null +++ b/ruby/ql/src/experimental/weak-params/WeakParams.qhelp @@ -0,0 +1,28 @@ + + + +

    + Directly checking request parameters without following a strong params + pattern can lead to unintentional avenues for injection attacks. +

    +
    + +

    + Instead of manually checking parameters from the `param` object, it is + recommended that you follow the strong parameters pattern established in + Rails: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html +

    +

    + In the strong parameters pattern, you are able to specify required and allowed + parameters for each action called by your controller methods. This acts as an + additional layer of data validation before being passed along to other areas + of your application, such as the model. +

    +
    + + + + +
    diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql new file mode 100644 index 00000000000..0c6d9db5644 --- /dev/null +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -0,0 +1,61 @@ +/** + * @name Weak or direct parameter references are used + * @description Directly checking request parameters without following a strong params pattern can lead to unintentional avenues for injection attacks. + * @kind path-problem + * @problem.severity error + * @security-severity 5.0 + * @precision medium + * @id rb/weak-params + * @tags security + */ + +import ruby +import codeql.ruby.Concepts +import codeql.ruby.DataFlow +import codeql.ruby.TaintTracking +import codeql.ruby.frameworks.ActionController +import DataFlow::PathGraph + +/** + * A call to `request` in an ActionController controller class. + * This probably refers to the incoming HTTP request object. + */ +class ActionControllerRequest extends DataFlow::Node { + ActionControllerRequest() { + exists(DataFlow::CallNode c | + c.asExpr().getExpr().getEnclosingModule() instanceof ActionControllerControllerClass and + c.getMethodName() = "request" + | + c.flowsTo(this) + ) + } +} + +/** + * A direct parameters reference that happens inside a controller class. + */ +class WeakParams extends DataFlow::CallNode { + WeakParams() { + this.getReceiver() instanceof ActionControllerRequest and + this.getMethodName() = + ["path_parameters", "query_parameters", "request_parameters", "GET", "POST"] + } +} + +/** + * A Taint tracking config where the source is a weak params access in a controller and the sink + * is a method call of a model class + */ +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "WeakParamsConfiguration" } + + override predicate isSource(DataFlow::Node node) { node instanceof WeakParams } + + // the sink is an instance of a Model class that receives a method call + override predicate isSink(DataFlow::Node node) { node = any(PersistentWriteAccess a).getValue() } +} + +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, + "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html" diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 914fb852b4e..6715fc61912 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.2.0-dev +version: 0.3.1-dev groups: - ruby - queries diff --git a/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll b/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll index 2192951f76d..5e9bc406512 100644 --- a/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll +++ b/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll @@ -53,7 +53,7 @@ predicate matchesBeginningOfString(RegExpTerm term) { } /** - * Holds if the given sequence contains top-level domain preceded by a dot, such as `.com`, + * Holds if the given sequence `seq` contains top-level domain preceded by a dot, such as `.com`, * excluding cases where this is at the very beginning of the regexp. * * `i` is bound to the index of the last child in the top-level domain part. diff --git a/ruby/ql/test/library-tests/ast/Ast.expected b/ruby/ql/test/library-tests/ast/Ast.expected index ebfd53fd551..4cb29e0f033 100644 --- a/ruby/ql/test/library-tests/ast/Ast.expected +++ b/ruby/ql/test/library-tests/ast/Ast.expected @@ -1556,6 +1556,35 @@ constants/constants.rb: # 73| getAnOperand/getLeftOperand: [ClassVariableAccess] @@fourty_six # 73| getAnOperand/getRightOperand: [ConstantReadAccess] FOURTY_SIX # 73| getScopeExpr: [ConstantReadAccess] Mod3 +# 78| getStmt: [AssignExpr] ... = ... +# 78| getAnOperand/getLeftOperand: [LocalVariableAccess] a +# 78| getAnOperand/getRightOperand: [ArrayLiteral] [...] +# 78| getElement: [IntegerLiteral] 1 +# 78| getElement: [IntegerLiteral] 2 +# 78| getElement: [IntegerLiteral] 3 +# 79| getStmt: [AssignExpr] ... = ... +# 79| getAnOperand/getLeftOperand: [ConstantAssignment] A +# 79| getAnOperand/getRightOperand: [ArrayLiteral] [...] +# 79| getElement: [IntegerLiteral] 1 +# 79| getElement: [IntegerLiteral] 2 +# 79| getElement: [IntegerLiteral] 3 +# 80| getStmt: [AssignExpr] ... = ... +# 80| getAnOperand/getLeftOperand: [ConstantAssignment] B +# 80| getAnOperand/getRightOperand: [LocalVariableAccess] a +# 81| getStmt: [AssignExpr] ... = ... +# 81| getAnOperand/getLeftOperand: [ConstantAssignment] C +# 81| getAnOperand/getRightOperand: [ConstantReadAccess] A +# 82| getStmt: [AssignExpr] ... = ... +# 82| getAnOperand/getLeftOperand: [LocalVariableAccess] b +# 82| getAnOperand/getRightOperand: [ConstantReadAccess] B +# 84| getStmt: [IfExpr] if ... +# 84| getCondition: [MethodCall] call to condition +# 84| getReceiver: [SelfVariableAccess] self +# 84| getBranch/getThen: [StmtSequence] then ... +# 85| getStmt: [AssignExpr] ... = ... +# 85| getAnOperand/getLeftOperand: [LocalVariableAccess] c +# 85| getAnOperand/getRightOperand: [LocalVariableAccess] b +# 87| getStmt: [LocalVariableAccess] c escape_sequences/escapes.rb: # 1| [Toplevel] escapes.rb # 6| getStmt: [StringLiteral] "\'" @@ -1733,6 +1762,12 @@ escape_sequences/escapes.rb: # 93| getStmt: [SymbolLiteral] :"\C-?" # 93| getComponent: [StringEscapeSequenceComponent] \C # 93| getComponent: [StringTextComponent] -? +misc/iso-8859-15.rb: +# 1| [Toplevel] iso-8859-15.rb +# 4| getStmt: [MethodCall] call to print +# 4| getReceiver: [SelfVariableAccess] self +# 4| getArgument: [StringLiteral] "EUR = €" +# 4| getComponent: [StringTextComponent] EUR = € literals/literals.rb: # 1| [Toplevel] literals.rb # 2| getStmt: [NilLiteral] nil diff --git a/ruby/ql/test/library-tests/ast/AstDesugar.expected b/ruby/ql/test/library-tests/ast/AstDesugar.expected index 0e6a0694105..956893e944f 100644 --- a/ruby/ql/test/library-tests/ast/AstDesugar.expected +++ b/ruby/ql/test/library-tests/ast/AstDesugar.expected @@ -336,6 +336,18 @@ constants/constants.rb: # 20| getComponent: [StringTextComponent] Chuck # 20| getArgument: [StringLiteral] "Dave" # 20| getComponent: [StringTextComponent] Dave +# 78| [ArrayLiteral] [...] +# 78| getDesugared: [MethodCall] call to [] +# 78| getReceiver: [ConstantReadAccess] Array +# 78| getArgument: [IntegerLiteral] 1 +# 78| getArgument: [IntegerLiteral] 2 +# 78| getArgument: [IntegerLiteral] 3 +# 79| [ArrayLiteral] [...] +# 79| getDesugared: [MethodCall] call to [] +# 79| getReceiver: [ConstantReadAccess] Array +# 79| getArgument: [IntegerLiteral] 1 +# 79| getArgument: [IntegerLiteral] 2 +# 79| getArgument: [IntegerLiteral] 3 escape_sequences/escapes.rb: # 58| [ArrayLiteral] %w(...) # 58| getDesugared: [MethodCall] call to [] diff --git a/ruby/ql/test/library-tests/ast/TreeSitter.expected b/ruby/ql/test/library-tests/ast/TreeSitter.expected index 0a2ecda8d28..cb5a17ebebb 100644 --- a/ruby/ql/test/library-tests/ast/TreeSitter.expected +++ b/ruby/ql/test/library-tests/ast/TreeSitter.expected @@ -1656,10 +1656,56 @@ constants/constants.rb: # 73| 1: [ReservedWord] :: # 73| 2: [Constant] FOURTY_SIX # 74| 5: [ReservedWord] end +# 78| 13: [Assignment] Assignment +# 78| 0: [Identifier] a +# 78| 1: [ReservedWord] = +# 78| 2: [Array] Array +# 78| 0: [ReservedWord] [ +# 78| 1: [Integer] 1 +# 78| 2: [ReservedWord] , +# 78| 3: [Integer] 2 +# 78| 4: [ReservedWord] , +# 78| 5: [Integer] 3 +# 78| 6: [ReservedWord] ] +# 79| 14: [Assignment] Assignment +# 79| 0: [Constant] A +# 79| 1: [ReservedWord] = +# 79| 2: [Array] Array +# 79| 0: [ReservedWord] [ +# 79| 1: [Integer] 1 +# 79| 2: [ReservedWord] , +# 79| 3: [Integer] 2 +# 79| 4: [ReservedWord] , +# 79| 5: [Integer] 3 +# 79| 6: [ReservedWord] ] +# 80| 15: [Assignment] Assignment +# 80| 0: [Constant] B +# 80| 1: [ReservedWord] = +# 80| 2: [Identifier] a +# 81| 16: [Assignment] Assignment +# 81| 0: [Constant] C +# 81| 1: [ReservedWord] = +# 81| 2: [Constant] A +# 82| 17: [Assignment] Assignment +# 82| 0: [Identifier] b +# 82| 1: [ReservedWord] = +# 82| 2: [Constant] B +# 84| 18: [If] If +# 84| 0: [ReservedWord] if +# 84| 1: [Identifier] condition +# 84| 2: [Then] Then +# 85| 0: [Assignment] Assignment +# 85| 0: [Identifier] c +# 85| 1: [ReservedWord] = +# 85| 2: [Identifier] b +# 86| 3: [ReservedWord] end +# 87| 19: [Identifier] c # 26| [Comment] # A call to Kernel::Array; despite beginning with an upper-case character, # 27| [Comment] # we don't consider this to be a constant access. # 55| [Comment] # refers to ::ModuleA::FOURTY_FOUR # 57| [Comment] # refers to ::ModuleA::ModuleB::ClassB::FOURTY_FOUR +# 76| [Comment] # Array constants +# 87| [Comment] # not recognised control/cases.rb: # 1| [Program] Program # 2| 0: [Assignment] Assignment @@ -4558,6 +4604,17 @@ literals/literals.rb: # 193| cat file.txt # 193| # 195| 1: [HeredocEnd] SCRIPT +misc/iso-8859-15.rb: +# 1| [Program] Program +# 4| 0: [Call] Call +# 4| 0: [Identifier] print +# 4| 1: [ArgumentList] ArgumentList +# 4| 0: [String] String +# 4| 0: [ReservedWord] " +# 4| 1: [StringContent] EUR = € +# 4| 2: [ReservedWord] " +# 1| [Comment] #! /usr/bin/ruby +# 2| [Comment] # coding: iso-8859-15 misc/misc.erb: # 2| [Program] Program # 2| 0: [Call] Call diff --git a/ruby/ql/test/library-tests/ast/ValueText.expected b/ruby/ql/test/library-tests/ast/ValueText.expected index 6225b1b2e90..e66838fbe2c 100644 --- a/ruby/ql/test/library-tests/ast/ValueText.expected +++ b/ruby/ql/test/library-tests/ast/ValueText.expected @@ -109,6 +109,12 @@ exprValue | constants/constants.rb:63:19:63:20 | 45 | 45 | int | | constants/constants.rb:65:19:65:35 | FOURTY_FIVE | 45 | int | | constants/constants.rb:71:18:71:19 | 46 | 46 | int | +| constants/constants.rb:78:6:78:6 | 1 | 1 | int | +| constants/constants.rb:78:9:78:9 | 2 | 2 | int | +| constants/constants.rb:78:12:78:12 | 3 | 3 | int | +| constants/constants.rb:79:6:79:6 | 1 | 1 | int | +| constants/constants.rb:79:9:79:9 | 2 | 2 | int | +| constants/constants.rb:79:12:79:12 | 3 | 3 | int | | control/cases.rb:2:5:2:5 | 0 | 0 | int | | control/cases.rb:3:5:3:5 | 0 | 0 | int | | control/cases.rb:4:5:4:5 | 0 | 0 | int | @@ -711,6 +717,7 @@ exprValue | literals/literals.rb:198:8:198:8 | 5 | 5 | int | | literals/literals.rb:199:2:199:2 | :y | :y | symbol | | literals/literals.rb:199:7:199:7 | :Z | :Z | symbol | +| misc/iso-8859-15.rb:4:7:4:17 | "EUR = \u20ac" | EUR = \u20ac | string | | misc/misc.erb:2:15:2:37 | "main_include_admin.js" | main_include_admin.js | string | | misc/misc.rb:1:7:1:11 | "bar" | bar | string | | misc/misc.rb:3:7:3:9 | foo | foo | string | @@ -1004,6 +1011,12 @@ exprCfgNodeValue | constants/constants.rb:63:19:63:20 | 45 | 45 | int | | constants/constants.rb:65:19:65:35 | FOURTY_FIVE | 45 | int | | constants/constants.rb:71:18:71:19 | 46 | 46 | int | +| constants/constants.rb:78:6:78:6 | 1 | 1 | int | +| constants/constants.rb:78:9:78:9 | 2 | 2 | int | +| constants/constants.rb:78:12:78:12 | 3 | 3 | int | +| constants/constants.rb:79:6:79:6 | 1 | 1 | int | +| constants/constants.rb:79:9:79:9 | 2 | 2 | int | +| constants/constants.rb:79:12:79:12 | 3 | 3 | int | | control/cases.rb:2:5:2:5 | 0 | 0 | int | | control/cases.rb:3:5:3:5 | 0 | 0 | int | | control/cases.rb:4:5:4:5 | 0 | 0 | int | @@ -1580,6 +1593,7 @@ exprCfgNodeValue | literals/literals.rb:198:8:198:8 | 5 | 5 | int | | literals/literals.rb:199:2:199:2 | :y | :y | symbol | | literals/literals.rb:199:7:199:7 | :Z | :Z | symbol | +| misc/iso-8859-15.rb:4:7:4:17 | "EUR = \u20ac" | EUR = \u20ac | string | | misc/misc.erb:2:15:2:37 | "main_include_admin.js" | main_include_admin.js | string | | misc/misc.rb:1:7:1:11 | "bar" | bar | string | | misc/misc.rb:3:7:3:9 | foo | foo | string | diff --git a/ruby/ql/test/library-tests/ast/constants/constants.expected b/ruby/ql/test/library-tests/ast/constants/constants.expected index 89b5512921c..3f189cc26fd 100644 --- a/ruby/ql/test/library-tests/ast/constants/constants.expected +++ b/ruby/ql/test/library-tests/ast/constants/constants.expected @@ -61,6 +61,13 @@ constantAccess | constants.rb:71:5:71:14 | FOURTY_SIX | write | FOURTY_SIX | ConstantAssignment | | constants.rb:73:18:73:21 | Mod3 | read | Mod3 | ConstantReadAccess | | constants.rb:73:18:73:33 | FOURTY_SIX | read | FOURTY_SIX | ConstantReadAccess | +| constants.rb:78:5:78:13 | Array | read | Array | ConstantReadAccess | +| constants.rb:79:1:79:1 | A | write | A | ConstantAssignment | +| constants.rb:79:5:79:13 | Array | read | Array | ConstantReadAccess | +| constants.rb:80:1:80:1 | B | write | B | ConstantAssignment | +| constants.rb:81:1:81:1 | C | write | C | ConstantAssignment | +| constants.rb:81:5:81:5 | A | read | A | ConstantReadAccess | +| constants.rb:82:5:82:5 | B | read | B | ConstantReadAccess | getConst | constants.rb:1:1:15:3 | ModuleA | CONST_B | constants.rb:6:15:6:23 | "const_b" | | constants.rb:1:1:15:3 | ModuleA | FOURTY_FOUR | constants.rb:53:17:53:29 | "fourty-four" | @@ -71,23 +78,41 @@ getConst | constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | FOURTY_ONE | constants.rb:48:18:48:19 | 41 | | constants.rb:62:3:64:5 | Mod1::Mod3 | FOURTY_FIVE | constants.rb:63:19:63:20 | 45 | | constants.rb:70:3:72:5 | Mod1::Mod3::Mod5 | FOURTY_SIX | constants.rb:71:18:71:19 | 46 | +| file://:0:0:0:0 | Object | A | constants.rb:79:5:79:13 | [...] | +| file://:0:0:0:0 | Object | B | constants.rb:80:5:80:5 | a | +| file://:0:0:0:0 | Object | C | constants.rb:81:5:81:5 | A | | file://:0:0:0:0 | Object | GREETING | constants.rb:17:12:17:64 | ... + ... | lookupConst | constants.rb:1:1:15:3 | ModuleA | CONST_B | constants.rb:6:15:6:23 | "const_b" | | constants.rb:1:1:15:3 | ModuleA | FOURTY_FOUR | constants.rb:53:17:53:29 | "fourty-four" | +| constants.rb:2:5:4:7 | ModuleA::ClassA | A | constants.rb:79:5:79:13 | [...] | +| constants.rb:2:5:4:7 | ModuleA::ClassA | B | constants.rb:80:5:80:5 | a | +| constants.rb:2:5:4:7 | ModuleA::ClassA | C | constants.rb:81:5:81:5 | A | | constants.rb:2:5:4:7 | ModuleA::ClassA | CONST_A | constants.rb:3:19:3:27 | "const_a" | | constants.rb:2:5:4:7 | ModuleA::ClassA | GREETING | constants.rb:17:12:17:64 | ... + ... | | constants.rb:8:5:14:7 | ModuleA::ModuleB | MAX_SIZE | constants.rb:39:30:39:33 | 1024 | +| constants.rb:12:9:13:11 | ModuleA::ModuleB::ClassC | A | constants.rb:79:5:79:13 | [...] | +| constants.rb:12:9:13:11 | ModuleA::ModuleB::ClassC | B | constants.rb:80:5:80:5 | a | +| constants.rb:12:9:13:11 | ModuleA::ModuleB::ClassC | C | constants.rb:81:5:81:5 | A | | constants.rb:12:9:13:11 | ModuleA::ModuleB::ClassC | GREETING | constants.rb:17:12:17:64 | ... + ... | +| constants.rb:31:1:33:3 | ModuleA::ClassD | A | constants.rb:79:5:79:13 | [...] | +| constants.rb:31:1:33:3 | ModuleA::ClassD | B | constants.rb:80:5:80:5 | a | +| constants.rb:31:1:33:3 | ModuleA::ClassD | C | constants.rb:81:5:81:5 | A | | constants.rb:31:1:33:3 | ModuleA::ClassD | CONST_A | constants.rb:3:19:3:27 | "const_a" | | constants.rb:31:1:33:3 | ModuleA::ClassD | FOURTY_TWO | constants.rb:32:16:32:17 | 42 | | constants.rb:31:1:33:3 | ModuleA::ClassD | GREETING | constants.rb:17:12:17:64 | ... + ... | | constants.rb:35:1:37:3 | ModuleA::ModuleC | FOURTY_THREE | constants.rb:36:18:36:19 | 43 | +| constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | A | constants.rb:79:5:79:13 | [...] | +| constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | B | constants.rb:80:5:80:5 | a | +| constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | C | constants.rb:81:5:81:5 | A | | constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | FOURTY_FOUR | constants.rb:56:19:56:20 | 44 | | constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | FOURTY_ONE | constants.rb:48:18:48:19 | 41 | | constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | GREETING | constants.rb:17:12:17:64 | ... + ... | | constants.rb:62:3:64:5 | Mod1::Mod3 | FOURTY_FIVE | constants.rb:63:19:63:20 | 45 | | constants.rb:70:3:72:5 | Mod1::Mod3::Mod5 | FOURTY_SIX | constants.rb:71:18:71:19 | 46 | +| file://:0:0:0:0 | Object | A | constants.rb:79:5:79:13 | [...] | +| file://:0:0:0:0 | Object | B | constants.rb:80:5:80:5 | a | +| file://:0:0:0:0 | Object | C | constants.rb:81:5:81:5 | A | | file://:0:0:0:0 | Object | GREETING | constants.rb:17:12:17:64 | ... + ... | constantValue | constants.rb:17:22:17:45 | CONST_A | constants.rb:3:19:3:27 | "const_a" | @@ -101,6 +126,8 @@ constantValue | constants.rb:57:21:57:31 | FOURTY_FOUR | constants.rb:53:17:53:29 | "fourty-four" | | constants.rb:57:21:57:31 | FOURTY_FOUR | constants.rb:56:19:56:20 | 44 | | constants.rb:65:19:65:35 | FOURTY_FIVE | constants.rb:63:19:63:20 | 45 | +| constants.rb:81:5:81:5 | A | constants.rb:79:5:79:13 | [...] | +| constants.rb:82:5:82:5 | B | constants.rb:80:5:80:5 | a | constantWriteAccessQualifiedName | constants.rb:1:1:15:3 | ModuleA | ModuleA | | constants.rb:2:5:4:7 | ClassA | ModuleA::ClassA | @@ -133,3 +160,14 @@ constantWriteAccessQualifiedName | constants.rb:70:3:72:5 | Mod5 | Mod3::Mod5 | | constants.rb:71:5:71:14 | FOURTY_SIX | Mod1::Mod3::Mod5::FOURTY_SIX | | constants.rb:71:5:71:14 | FOURTY_SIX | Mod3::Mod5::FOURTY_SIX | +| constants.rb:79:1:79:1 | A | A | +| constants.rb:80:1:80:1 | B | B | +| constants.rb:81:1:81:1 | C | C | +arrayConstant +| constants.rb:20:13:20:37 | call to [] | constants.rb:20:13:20:37 | call to [] | +| constants.rb:78:5:78:13 | call to [] | constants.rb:78:5:78:13 | call to [] | +| constants.rb:79:5:79:13 | call to [] | constants.rb:79:5:79:13 | call to [] | +| constants.rb:80:5:80:5 | a | constants.rb:78:5:78:13 | call to [] | +| constants.rb:81:5:81:5 | A | constants.rb:79:5:79:13 | call to [] | +| constants.rb:82:5:82:5 | B | constants.rb:78:5:78:13 | call to [] | +| constants.rb:85:7:85:7 | b | constants.rb:78:5:78:13 | call to [] | diff --git a/ruby/ql/test/library-tests/ast/constants/constants.ql b/ruby/ql/test/library-tests/ast/constants/constants.ql index 66c0d230d99..37140a957a3 100644 --- a/ruby/ql/test/library-tests/ast/constants/constants.ql +++ b/ruby/ql/test/library-tests/ast/constants/constants.ql @@ -1,5 +1,6 @@ import ruby import codeql.ruby.ast.internal.Module as M +import codeql.ruby.ast.internal.Constant query predicate constantAccess(ConstantAccess a, string kind, string name, string cls) { ( @@ -20,3 +21,5 @@ query predicate constantValue(ConstantReadAccess a, Expr e) { e = a.getValue() } query predicate constantWriteAccessQualifiedName(ConstantWriteAccess w, string qualifiedName) { w.getAQualifiedName() = qualifiedName } + +query predicate arrayConstant = isArrayConstant/2; diff --git a/ruby/ql/test/library-tests/ast/constants/constants.rb b/ruby/ql/test/library-tests/ast/constants/constants.rb index 08e0d4216a9..359a861eb1e 100644 --- a/ruby/ql/test/library-tests/ast/constants/constants.rb +++ b/ruby/ql/test/library-tests/ast/constants/constants.rb @@ -72,3 +72,16 @@ module Mod4 end @@fourty_six = Mod3::FOURTY_SIX end + +# Array constants + +a = [1, 2, 3] +A = [1, 2, 3] +B = a +C = A +b = B + +if condition + c = b +end +c # not recognised diff --git a/ruby/ql/test/library-tests/ast/misc/iso-8859-15.rb b/ruby/ql/test/library-tests/ast/misc/iso-8859-15.rb new file mode 100644 index 00000000000..d5fd8ae9456 --- /dev/null +++ b/ruby/ql/test/library-tests/ast/misc/iso-8859-15.rb @@ -0,0 +1,4 @@ +#! /usr/bin/ruby +# coding: iso-8859-15 + +print "EUR = ¤" \ No newline at end of file diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected new file mode 100644 index 00000000000..783d414dad6 --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected @@ -0,0 +1,22 @@ +WARNING: Type BarrierGuard has been deprecated and may be removed in future (barrier-guards.ql:8,3-15) +oldStyleBarrierGuards +| barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:4:5:4:7 | foo | barrier-guards.rb:3:4:3:6 | foo | true | +| barrier-guards.rb:9:4:9:24 | call to include? | barrier-guards.rb:10:5:10:7 | foo | barrier-guards.rb:9:21:9:23 | foo | true | +| barrier-guards.rb:15:4:15:15 | ... != ... | barrier-guards.rb:18:5:18:7 | foo | barrier-guards.rb:15:4:15:6 | foo | false | +| barrier-guards.rb:21:8:21:19 | ... == ... | barrier-guards.rb:24:5:24:7 | foo | barrier-guards.rb:21:8:21:10 | foo | true | +| barrier-guards.rb:27:8:27:19 | ... != ... | barrier-guards.rb:28:5:28:7 | foo | barrier-guards.rb:27:8:27:10 | foo | false | +| barrier-guards.rb:37:4:37:20 | call to include? | barrier-guards.rb:38:5:38:7 | foo | barrier-guards.rb:37:17:37:19 | foo | true | +| barrier-guards.rb:43:4:43:15 | ... == ... | barrier-guards.rb:45:9:45:11 | foo | barrier-guards.rb:43:4:43:6 | foo | true | +| barrier-guards.rb:70:4:70:21 | call to include? | barrier-guards.rb:71:5:71:7 | foo | barrier-guards.rb:70:18:70:20 | foo | true | +| barrier-guards.rb:82:4:82:25 | ... != ... | barrier-guards.rb:83:5:83:7 | foo | barrier-guards.rb:82:15:82:17 | foo | true | +newStyleBarrierGuards +| barrier-guards.rb:4:5:4:7 | foo | +| barrier-guards.rb:10:5:10:7 | foo | +| barrier-guards.rb:18:5:18:7 | foo | +| barrier-guards.rb:24:5:24:7 | foo | +| barrier-guards.rb:28:5:28:7 | foo | +| barrier-guards.rb:38:5:38:7 | foo | +| barrier-guards.rb:45:9:45:11 | foo | +| barrier-guards.rb:71:5:71:7 | foo | +| barrier-guards.rb:83:5:83:7 | foo | +| barrier-guards.rb:91:5:91:7 | foo | diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql new file mode 100644 index 00000000000..84a962ade35 --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql @@ -0,0 +1,16 @@ +import codeql.ruby.dataflow.internal.DataFlowPublic +import codeql.ruby.dataflow.BarrierGuards +import codeql.ruby.controlflow.CfgNodes +import codeql.ruby.controlflow.ControlFlowGraph +import codeql.ruby.DataFlow + +query predicate oldStyleBarrierGuards( + BarrierGuard g, DataFlow::Node guardedNode, ExprCfgNode expr, boolean branch +) { + g.checks(expr, branch) and guardedNode = g.getAGuardedNode() +} + +query predicate newStyleBarrierGuards(DataFlow::Node n) { + n instanceof StringConstCompareBarrier or + n instanceof StringConstArrayInclusionCallBarrier +} diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb new file mode 100644 index 00000000000..47b96da22dd --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb @@ -0,0 +1,104 @@ +foo = "foo" + +if foo == "foo" + foo +else + foo +end + +if ["foo"].include?(foo) + foo +else + foo +end + +if foo != "foo" + foo +else + foo +end + +unless foo == "foo" + foo +else + foo +end + +unless foo != "foo" + foo +else + foo +end + +foo + +FOO = ["foo"] + +if FOO.include?(foo) + foo +else + foo +end + +if foo == "foo" + capture { + foo # guarded + } +end + +if foo == "foo" + capture { + foo = "bar" + foo # not guarded + } +end + +if foo == "foo" + my_lambda = -> () { + foo # not guarded + } + + foo = "bar" + + my_lambda() +end + +foos = nil +foos = ["foo"] +bars = NotAnArray.new + +if foos.include?(foo) + foo +else + foo +end + +if bars.include?(foo) + foo +else + foo +end + +if foos.index(foo) != nil + foo +else + foo +end + +if foos.index(foo)r == nil + foo +else + foo +end + +bars = ["bar"] + +if condition + bars = nil +end + +if bars.include?(foo) + foo +else + foo +end diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected new file mode 100644 index 00000000000..a13e860bd04 --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected @@ -0,0 +1,219 @@ +failures +edges +| pathname_flow.rb:4:10:4:33 | call to new : | pathname_flow.rb:5:10:5:11 | pn | +| pathname_flow.rb:4:23:4:32 | call to source : | pathname_flow.rb:4:10:4:33 | call to new : | +| pathname_flow.rb:9:7:9:30 | call to new : | pathname_flow.rb:11:8:11:12 | ... + ... | +| pathname_flow.rb:9:20:9:29 | call to source : | pathname_flow.rb:9:7:9:30 | call to new : | +| pathname_flow.rb:10:7:10:30 | call to new : | pathname_flow.rb:11:8:11:12 | ... + ... | +| pathname_flow.rb:10:20:10:29 | call to source : | pathname_flow.rb:10:7:10:30 | call to new : | +| pathname_flow.rb:15:8:15:31 | call to new : | pathname_flow.rb:16:8:16:9 | pn : | +| pathname_flow.rb:15:21:15:30 | call to source : | pathname_flow.rb:15:8:15:31 | call to new : | +| pathname_flow.rb:16:8:16:9 | pn : | pathname_flow.rb:16:8:16:17 | call to dirname | +| pathname_flow.rb:20:7:20:30 | call to new : | pathname_flow.rb:21:3:21:3 | a : | +| pathname_flow.rb:20:20:20:29 | call to source : | pathname_flow.rb:20:7:20:30 | call to new : | +| pathname_flow.rb:21:3:21:3 | a : | pathname_flow.rb:21:23:21:23 | x : | +| pathname_flow.rb:21:23:21:23 | x : | pathname_flow.rb:22:10:22:10 | x | +| pathname_flow.rb:27:7:27:30 | call to new : | pathname_flow.rb:28:8:28:8 | a : | +| pathname_flow.rb:27:20:27:29 | call to source : | pathname_flow.rb:27:7:27:30 | call to new : | +| pathname_flow.rb:28:8:28:8 | a : | pathname_flow.rb:28:8:28:22 | call to expand_path | +| pathname_flow.rb:32:7:32:30 | call to new : | pathname_flow.rb:35:8:35:8 | a : | +| pathname_flow.rb:32:20:32:29 | call to source : | pathname_flow.rb:32:7:32:30 | call to new : | +| pathname_flow.rb:34:7:34:30 | call to new : | pathname_flow.rb:35:18:35:18 | c : | +| pathname_flow.rb:34:20:34:29 | call to source : | pathname_flow.rb:34:7:34:30 | call to new : | +| pathname_flow.rb:35:8:35:8 | a : | pathname_flow.rb:35:8:35:19 | call to join | +| pathname_flow.rb:35:18:35:18 | c : | pathname_flow.rb:35:8:35:19 | call to join | +| pathname_flow.rb:39:7:39:30 | call to new : | pathname_flow.rb:40:8:40:8 | a : | +| pathname_flow.rb:39:20:39:29 | call to source : | pathname_flow.rb:39:7:39:30 | call to new : | +| pathname_flow.rb:40:8:40:8 | a : | pathname_flow.rb:40:8:40:17 | call to parent | +| pathname_flow.rb:44:7:44:30 | call to new : | pathname_flow.rb:45:8:45:8 | a : | +| pathname_flow.rb:44:20:44:29 | call to source : | pathname_flow.rb:44:7:44:30 | call to new : | +| pathname_flow.rb:45:8:45:8 | a : | pathname_flow.rb:45:8:45:19 | call to realpath | +| pathname_flow.rb:49:7:49:30 | call to new : | pathname_flow.rb:50:8:50:8 | a : | +| pathname_flow.rb:49:20:49:29 | call to source : | pathname_flow.rb:49:7:49:30 | call to new : | +| pathname_flow.rb:50:8:50:8 | a : | pathname_flow.rb:50:8:50:39 | call to relative_path_from | +| pathname_flow.rb:54:7:54:30 | call to new : | pathname_flow.rb:55:8:55:8 | a : | +| pathname_flow.rb:54:20:54:29 | call to source : | pathname_flow.rb:54:7:54:30 | call to new : | +| pathname_flow.rb:55:8:55:8 | a : | pathname_flow.rb:55:8:55:16 | call to to_path | +| pathname_flow.rb:59:7:59:30 | call to new : | pathname_flow.rb:60:8:60:8 | a : | +| pathname_flow.rb:59:20:59:29 | call to source : | pathname_flow.rb:59:7:59:30 | call to new : | +| pathname_flow.rb:60:8:60:8 | a : | pathname_flow.rb:60:8:60:13 | call to to_s | +| pathname_flow.rb:64:7:64:30 | call to new : | pathname_flow.rb:66:8:66:8 | b | +| pathname_flow.rb:64:20:64:29 | call to source : | pathname_flow.rb:64:7:64:30 | call to new : | +| pathname_flow.rb:70:7:70:30 | call to new : | pathname_flow.rb:72:8:72:8 | b | +| pathname_flow.rb:70:20:70:29 | call to source : | pathname_flow.rb:70:7:70:30 | call to new : | +| pathname_flow.rb:76:7:76:30 | call to new : | pathname_flow.rb:77:7:77:7 | a : | +| pathname_flow.rb:76:20:76:29 | call to source : | pathname_flow.rb:76:7:76:30 | call to new : | +| pathname_flow.rb:77:7:77:7 | a : | pathname_flow.rb:77:7:77:16 | call to basename : | +| pathname_flow.rb:77:7:77:16 | call to basename : | pathname_flow.rb:78:8:78:8 | b | +| pathname_flow.rb:82:7:82:30 | call to new : | pathname_flow.rb:83:7:83:7 | a : | +| pathname_flow.rb:82:20:82:29 | call to source : | pathname_flow.rb:82:7:82:30 | call to new : | +| pathname_flow.rb:83:7:83:7 | a : | pathname_flow.rb:83:7:83:17 | call to cleanpath : | +| pathname_flow.rb:83:7:83:17 | call to cleanpath : | pathname_flow.rb:84:8:84:8 | b | +| pathname_flow.rb:88:7:88:30 | call to new : | pathname_flow.rb:89:7:89:7 | a : | +| pathname_flow.rb:88:20:88:29 | call to source : | pathname_flow.rb:88:7:88:30 | call to new : | +| pathname_flow.rb:89:7:89:7 | a : | pathname_flow.rb:89:7:89:25 | call to sub : | +| pathname_flow.rb:89:7:89:25 | call to sub : | pathname_flow.rb:90:8:90:8 | b | +| pathname_flow.rb:94:7:94:30 | call to new : | pathname_flow.rb:95:7:95:7 | a : | +| pathname_flow.rb:94:20:94:29 | call to source : | pathname_flow.rb:94:7:94:30 | call to new : | +| pathname_flow.rb:95:7:95:7 | a : | pathname_flow.rb:95:7:95:23 | call to sub_ext : | +| pathname_flow.rb:95:7:95:23 | call to sub_ext : | pathname_flow.rb:96:8:96:8 | b | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:104:8:104:8 | b : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:107:8:107:8 | c : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:109:7:109:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:112:7:112:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:115:7:115:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:118:7:118:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:121:7:121:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:124:7:124:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:127:7:127:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:130:7:130:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:133:7:133:7 | a : | +| pathname_flow.rb:101:20:101:29 | call to source : | pathname_flow.rb:101:7:101:30 | call to new : | +| pathname_flow.rb:104:8:104:8 | b : | pathname_flow.rb:104:8:104:17 | call to realpath | +| pathname_flow.rb:107:8:107:8 | c : | pathname_flow.rb:107:8:107:17 | call to realpath | +| pathname_flow.rb:109:7:109:7 | a : | pathname_flow.rb:109:7:109:16 | call to basename : | +| pathname_flow.rb:109:7:109:16 | call to basename : | pathname_flow.rb:110:8:110:8 | d : | +| pathname_flow.rb:110:8:110:8 | d : | pathname_flow.rb:110:8:110:17 | call to realpath | +| pathname_flow.rb:112:7:112:7 | a : | pathname_flow.rb:112:7:112:17 | call to cleanpath : | +| pathname_flow.rb:112:7:112:17 | call to cleanpath : | pathname_flow.rb:113:8:113:8 | e : | +| pathname_flow.rb:113:8:113:8 | e : | pathname_flow.rb:113:8:113:17 | call to realpath | +| pathname_flow.rb:115:7:115:7 | a : | pathname_flow.rb:115:7:115:19 | call to expand_path : | +| pathname_flow.rb:115:7:115:19 | call to expand_path : | pathname_flow.rb:116:8:116:8 | f : | +| pathname_flow.rb:116:8:116:8 | f : | pathname_flow.rb:116:8:116:17 | call to realpath | +| pathname_flow.rb:118:7:118:7 | a : | pathname_flow.rb:118:7:118:19 | call to join : | +| pathname_flow.rb:118:7:118:19 | call to join : | pathname_flow.rb:119:8:119:8 | g : | +| pathname_flow.rb:119:8:119:8 | g : | pathname_flow.rb:119:8:119:17 | call to realpath | +| pathname_flow.rb:121:7:121:7 | a : | pathname_flow.rb:121:7:121:16 | call to realpath : | +| pathname_flow.rb:121:7:121:16 | call to realpath : | pathname_flow.rb:122:8:122:8 | h : | +| pathname_flow.rb:122:8:122:8 | h : | pathname_flow.rb:122:8:122:17 | call to realpath | +| pathname_flow.rb:124:7:124:7 | a : | pathname_flow.rb:124:7:124:38 | call to relative_path_from : | +| pathname_flow.rb:124:7:124:38 | call to relative_path_from : | pathname_flow.rb:125:8:125:8 | i : | +| pathname_flow.rb:125:8:125:8 | i : | pathname_flow.rb:125:8:125:17 | call to realpath | +| pathname_flow.rb:127:7:127:7 | a : | pathname_flow.rb:127:7:127:25 | call to sub : | +| pathname_flow.rb:127:7:127:25 | call to sub : | pathname_flow.rb:128:8:128:8 | j : | +| pathname_flow.rb:128:8:128:8 | j : | pathname_flow.rb:128:8:128:17 | call to realpath | +| pathname_flow.rb:130:7:130:7 | a : | pathname_flow.rb:130:7:130:23 | call to sub_ext : | +| pathname_flow.rb:130:7:130:23 | call to sub_ext : | pathname_flow.rb:131:8:131:8 | k : | +| pathname_flow.rb:131:8:131:8 | k : | pathname_flow.rb:131:8:131:17 | call to realpath | +| pathname_flow.rb:133:7:133:7 | a : | pathname_flow.rb:133:7:133:15 | call to to_path : | +| pathname_flow.rb:133:7:133:15 | call to to_path : | pathname_flow.rb:134:8:134:8 | l : | +| pathname_flow.rb:134:8:134:8 | l : | pathname_flow.rb:134:8:134:17 | call to realpath | +nodes +| pathname_flow.rb:4:10:4:33 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:4:23:4:32 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:5:10:5:11 | pn | semmle.label | pn | +| pathname_flow.rb:9:7:9:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:9:20:9:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:10:7:10:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:10:20:10:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:11:8:11:12 | ... + ... | semmle.label | ... + ... | +| pathname_flow.rb:15:8:15:31 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:15:21:15:30 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:16:8:16:9 | pn : | semmle.label | pn : | +| pathname_flow.rb:16:8:16:17 | call to dirname | semmle.label | call to dirname | +| pathname_flow.rb:20:7:20:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:20:20:20:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:21:3:21:3 | a : | semmle.label | a : | +| pathname_flow.rb:21:23:21:23 | x : | semmle.label | x : | +| pathname_flow.rb:22:10:22:10 | x | semmle.label | x | +| pathname_flow.rb:27:7:27:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:27:20:27:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:28:8:28:8 | a : | semmle.label | a : | +| pathname_flow.rb:28:8:28:22 | call to expand_path | semmle.label | call to expand_path | +| pathname_flow.rb:32:7:32:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:32:20:32:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:34:7:34:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:34:20:34:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:35:8:35:8 | a : | semmle.label | a : | +| pathname_flow.rb:35:8:35:19 | call to join | semmle.label | call to join | +| pathname_flow.rb:35:18:35:18 | c : | semmle.label | c : | +| pathname_flow.rb:39:7:39:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:39:20:39:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:40:8:40:8 | a : | semmle.label | a : | +| pathname_flow.rb:40:8:40:17 | call to parent | semmle.label | call to parent | +| pathname_flow.rb:44:7:44:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:44:20:44:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:45:8:45:8 | a : | semmle.label | a : | +| pathname_flow.rb:45:8:45:19 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:49:7:49:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:49:20:49:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:50:8:50:8 | a : | semmle.label | a : | +| pathname_flow.rb:50:8:50:39 | call to relative_path_from | semmle.label | call to relative_path_from | +| pathname_flow.rb:54:7:54:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:54:20:54:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:55:8:55:8 | a : | semmle.label | a : | +| pathname_flow.rb:55:8:55:16 | call to to_path | semmle.label | call to to_path | +| pathname_flow.rb:59:7:59:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:59:20:59:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:60:8:60:8 | a : | semmle.label | a : | +| pathname_flow.rb:60:8:60:13 | call to to_s | semmle.label | call to to_s | +| pathname_flow.rb:64:7:64:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:64:20:64:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:66:8:66:8 | b | semmle.label | b | +| pathname_flow.rb:70:7:70:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:70:20:70:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:72:8:72:8 | b | semmle.label | b | +| pathname_flow.rb:76:7:76:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:76:20:76:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:77:7:77:7 | a : | semmle.label | a : | +| pathname_flow.rb:77:7:77:16 | call to basename : | semmle.label | call to basename : | +| pathname_flow.rb:78:8:78:8 | b | semmle.label | b | +| pathname_flow.rb:82:7:82:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:82:20:82:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:83:7:83:7 | a : | semmle.label | a : | +| pathname_flow.rb:83:7:83:17 | call to cleanpath : | semmle.label | call to cleanpath : | +| pathname_flow.rb:84:8:84:8 | b | semmle.label | b | +| pathname_flow.rb:88:7:88:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:88:20:88:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:89:7:89:7 | a : | semmle.label | a : | +| pathname_flow.rb:89:7:89:25 | call to sub : | semmle.label | call to sub : | +| pathname_flow.rb:90:8:90:8 | b | semmle.label | b | +| pathname_flow.rb:94:7:94:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:94:20:94:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:95:7:95:7 | a : | semmle.label | a : | +| pathname_flow.rb:95:7:95:23 | call to sub_ext : | semmle.label | call to sub_ext : | +| pathname_flow.rb:96:8:96:8 | b | semmle.label | b | +| pathname_flow.rb:101:7:101:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:101:20:101:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:104:8:104:8 | b : | semmle.label | b : | +| pathname_flow.rb:104:8:104:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:107:8:107:8 | c : | semmle.label | c : | +| pathname_flow.rb:107:8:107:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:109:7:109:7 | a : | semmle.label | a : | +| pathname_flow.rb:109:7:109:16 | call to basename : | semmle.label | call to basename : | +| pathname_flow.rb:110:8:110:8 | d : | semmle.label | d : | +| pathname_flow.rb:110:8:110:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:112:7:112:7 | a : | semmle.label | a : | +| pathname_flow.rb:112:7:112:17 | call to cleanpath : | semmle.label | call to cleanpath : | +| pathname_flow.rb:113:8:113:8 | e : | semmle.label | e : | +| pathname_flow.rb:113:8:113:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:115:7:115:7 | a : | semmle.label | a : | +| pathname_flow.rb:115:7:115:19 | call to expand_path : | semmle.label | call to expand_path : | +| pathname_flow.rb:116:8:116:8 | f : | semmle.label | f : | +| pathname_flow.rb:116:8:116:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:118:7:118:7 | a : | semmle.label | a : | +| pathname_flow.rb:118:7:118:19 | call to join : | semmle.label | call to join : | +| pathname_flow.rb:119:8:119:8 | g : | semmle.label | g : | +| pathname_flow.rb:119:8:119:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:121:7:121:7 | a : | semmle.label | a : | +| pathname_flow.rb:121:7:121:16 | call to realpath : | semmle.label | call to realpath : | +| pathname_flow.rb:122:8:122:8 | h : | semmle.label | h : | +| pathname_flow.rb:122:8:122:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:124:7:124:7 | a : | semmle.label | a : | +| pathname_flow.rb:124:7:124:38 | call to relative_path_from : | semmle.label | call to relative_path_from : | +| pathname_flow.rb:125:8:125:8 | i : | semmle.label | i : | +| pathname_flow.rb:125:8:125:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:127:7:127:7 | a : | semmle.label | a : | +| pathname_flow.rb:127:7:127:25 | call to sub : | semmle.label | call to sub : | +| pathname_flow.rb:128:8:128:8 | j : | semmle.label | j : | +| pathname_flow.rb:128:8:128:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:130:7:130:7 | a : | semmle.label | a : | +| pathname_flow.rb:130:7:130:23 | call to sub_ext : | semmle.label | call to sub_ext : | +| pathname_flow.rb:131:8:131:8 | k : | semmle.label | k : | +| pathname_flow.rb:131:8:131:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:133:7:133:7 | a : | semmle.label | a : | +| pathname_flow.rb:133:7:133:15 | call to to_path : | semmle.label | call to to_path : | +| pathname_flow.rb:134:8:134:8 | l : | semmle.label | l : | +| pathname_flow.rb:134:8:134:17 | call to realpath | semmle.label | call to realpath | +subpaths +#select diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql new file mode 100644 index 00000000000..4e812d32daa --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql @@ -0,0 +1,11 @@ +/** + * @kind path-problem + */ + +import ruby +import TestUtilities.InlineFlowTest +import PathGraph + +from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf +where conf.hasFlowPath(source, sink) +select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb new file mode 100644 index 00000000000..dab4adec6c6 --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb @@ -0,0 +1,135 @@ +require 'pathname' + +def m_new + pn = Pathname.new(source 'a') + sink pn # $ hasTaintFlow=a +end + +def m_plus + a = Pathname.new(source 'a') + b = Pathname.new(source 'b') + sink(a + b) # $ hasTaintFlow=a $ hasTaintFlow=b +end + +def m_dirname + pn = Pathname.new(source 'a') + sink pn.dirname # $ hasTaintFlow=a +end + +def m_each_filename + a = Pathname.new(source 'a') + a.each_filename do |x| + sink x # $ hasTaintFlow=a + end +end + +def m_expand_path + a = Pathname.new(source 'a') + sink a.expand_path() # $ hasTaintFlow=a +end + +def m_join + a = Pathname.new(source 'a') + b = Pathname.new('foo') + c = Pathname.new(source 'c') + sink a.join(b, c) # $ hasTaintFlow=a $ hasTaintFlow=c +end + +def m_parent + a = Pathname.new(source 'a') + sink a.parent() # $ hasTaintFlow=a +end + +def m_realpath + a = Pathname.new(source 'a') + sink a.realpath() # $ hasTaintFlow=a +end + +def m_relative_path_from + a = Pathname.new(source 'a') + sink a.relative_path_from('/foo/bar') # $ hasTaintFlow=a +end + +def m_to_path + a = Pathname.new(source 'a') + sink a.to_path # $ hasTaintFlow=a +end + +def m_to_s + a = Pathname.new(source 'a') + sink a.to_s # $ hasTaintFlow=a +end + +def m_plus + a = Pathname.new(source 'a') + b = a + 'foo' + sink b # $ hasTaintFlow=a +end + +def m_slash + a = Pathname.new(source 'a') + b = a / 'foo' + sink b # $ hasTaintFlow=a +end + +def m_basename + a = Pathname.new(source 'a') + b = a.basename + sink b # $ hasTaintFlow=a +end + +def m_cleanpath + a = Pathname.new(source 'a') + b = a.cleanpath + sink b # $ hasTaintFlow=a +end + +def m_sub + a = Pathname.new(source 'a') + b = a.sub('foo', 'bar') + sink b # $ hasTaintFlow=a +end + +def m_sub_ext + a = Pathname.new(source 'a') + b = a.sub_ext('.txt') + sink b # $ hasTaintFlow=a +end + +# Test flow through intermediate pathnames +def intermediate_pathnames + a = Pathname.new(source 'a') + + b = a + 'foo' + sink b.realpath # $ hasTaintFlow=a + + c = a / 'foo' + sink c.realpath # $ hasTaintFlow=a + + d = a.basename + sink d.realpath # $ hasTaintFlow=a + + e = a.cleanpath + sink e.realpath # $ hasTaintFlow=a + + f = a.expand_path + sink f.realpath # $ hasTaintFlow=a + + g = a.join('foo') + sink g.realpath # $ hasTaintFlow=a + + h = a.realpath + sink h.realpath # $ hasTaintFlow=a + + i = a.relative_path_from('/foo/bar') + sink i.realpath # $ hasTaintFlow=a + + j = a.sub('foo', 'bar') + sink j.realpath # $ hasTaintFlow=a + + k = a.sub_ext('.txt') + sink k.realpath # $ hasTaintFlow=a + + l = a.to_path + sink l.realpath # $ hasTaintFlow=a +end \ No newline at end of file diff --git a/ruby/ql/test/library-tests/frameworks/ActionController.expected b/ruby/ql/test/library-tests/frameworks/ActionController.expected index d306f09b64b..52ab15995c7 100644 --- a/ruby/ql/test/library-tests/frameworks/ActionController.expected +++ b/ruby/ql/test/library-tests/frameworks/ActionController.expected @@ -2,6 +2,7 @@ actionControllerControllerClasses | ActiveRecord.rb:23:1:39:3 | FooController | | ActiveRecord.rb:41:1:64:3 | BarController | | ActiveRecord.rb:66:1:70:3 | BazController | +| ActiveRecord.rb:72:1:80:3 | AnnotatedController | | app/controllers/comments_controller.rb:1:1:7:3 | CommentsController | | app/controllers/foo/bars_controller.rb:3:1:39:3 | BarsController | | app/controllers/photos_controller.rb:1:1:4:3 | PhotosController | @@ -12,6 +13,8 @@ actionControllerActionMethods | ActiveRecord.rb:42:3:47:5 | some_other_request_handler | | ActiveRecord.rb:49:3:63:5 | safe_paths | | ActiveRecord.rb:67:3:69:5 | yet_another_handler | +| ActiveRecord.rb:73:3:75:5 | index | +| ActiveRecord.rb:77:3:79:5 | unsafe_action | | app/controllers/comments_controller.rb:2:3:3:5 | index | | app/controllers/comments_controller.rb:5:3:6:5 | show | | app/controllers/foo/bars_controller.rb:5:3:7:5 | index | @@ -38,6 +41,7 @@ paramsCalls | ActiveRecord.rb:59:12:59:17 | call to params | | ActiveRecord.rb:62:15:62:20 | call to params | | ActiveRecord.rb:68:21:68:26 | call to params | +| ActiveRecord.rb:78:59:78:64 | call to params | | app/controllers/foo/bars_controller.rb:13:21:13:26 | call to params | | app/controllers/foo/bars_controller.rb:14:10:14:15 | call to params | | app/controllers/foo/bars_controller.rb:21:21:21:26 | call to params | @@ -57,6 +61,7 @@ paramsSources | ActiveRecord.rb:59:12:59:17 | call to params | | ActiveRecord.rb:62:15:62:20 | call to params | | ActiveRecord.rb:68:21:68:26 | call to params | +| ActiveRecord.rb:78:59:78:64 | call to params | | app/controllers/foo/bars_controller.rb:13:21:13:26 | call to params | | app/controllers/foo/bars_controller.rb:14:10:14:15 | call to params | | app/controllers/foo/bars_controller.rb:21:21:21:26 | call to params | diff --git a/ruby/ql/test/library-tests/frameworks/ActiveRecord.expected b/ruby/ql/test/library-tests/frameworks/ActiveRecord.expected index d8509f6a218..b416d853440 100644 --- a/ruby/ql/test/library-tests/frameworks/ActiveRecord.expected +++ b/ruby/ql/test/library-tests/frameworks/ActiveRecord.expected @@ -22,6 +22,7 @@ activeRecordSqlExecutionRanges | ActiveRecord.rb:46:20:46:32 | ... + ... | | ActiveRecord.rb:52:16:52:28 | "name #{...}" | | ActiveRecord.rb:56:20:56:39 | "username = #{...}" | +| ActiveRecord.rb:78:27:78:76 | "this is an unsafe annotation:..." | activeRecordModelClassMethodCalls | ActiveRecord.rb:2:3:2:17 | call to has_many | | ActiveRecord.rb:6:3:6:24 | call to belongs_to | @@ -44,6 +45,8 @@ activeRecordModelClassMethodCalls | ActiveRecord.rb:60:5:60:33 | call to find_by | | ActiveRecord.rb:62:5:62:34 | call to find | | ActiveRecord.rb:68:5:68:45 | call to delete_by | +| ActiveRecord.rb:74:13:74:54 | call to annotate | +| ActiveRecord.rb:78:13:78:77 | call to annotate | potentiallyUnsafeSqlExecutingMethodCall | ActiveRecord.rb:9:5:9:68 | call to find | | ActiveRecord.rb:19:5:19:25 | call to destroy_by | @@ -55,6 +58,7 @@ potentiallyUnsafeSqlExecutingMethodCall | ActiveRecord.rb:46:5:46:33 | call to delete_by | | ActiveRecord.rb:52:5:52:29 | call to order | | ActiveRecord.rb:56:7:56:40 | call to find_by | +| ActiveRecord.rb:78:13:78:77 | call to annotate | activeRecordModelInstantiations | ActiveRecord.rb:9:5:9:68 | call to find | ActiveRecord.rb:5:1:15:3 | User | | ActiveRecord.rb:13:5:13:40 | call to find_by | ActiveRecord.rb:1:1:3:3 | UserGroup | diff --git a/ruby/ql/test/library-tests/frameworks/ActiveRecord.rb b/ruby/ql/test/library-tests/frameworks/ActiveRecord.rb index 5045a5c2264..d25cbf901c3 100644 --- a/ruby/ql/test/library-tests/frameworks/ActiveRecord.rb +++ b/ruby/ql/test/library-tests/frameworks/ActiveRecord.rb @@ -68,3 +68,13 @@ class BazController < BarController Admin.delete_by(params[:admin_condition]) end end + +class AnnotatedController < ActionController::Base + def index + users = User.annotate("this is a safe annotation") + end + + def unsafe_action + users = User.annotate("this is an unsafe annotation:#{params[:comment]}") + end +end diff --git a/ruby/ql/test/library-tests/frameworks/PosixSpawn.ql b/ruby/ql/test/library-tests/frameworks/PosixSpawn.ql index 12fb445cf15..994f0d162f0 100644 --- a/ruby/ql/test/library-tests/frameworks/PosixSpawn.ql +++ b/ruby/ql/test/library-tests/frameworks/PosixSpawn.ql @@ -5,11 +5,13 @@ import codeql.ruby.DataFlow query predicate systemCalls( PosixSpawn::SystemCall call, DataFlow::Node arg, boolean shellInterpreted ) { - arg = call.getAnArgument() and - if call.isShellInterpreted(arg) then shellInterpreted = true else shellInterpreted = false + call.isShellInterpreted(arg) and shellInterpreted = true + or + not call.isShellInterpreted(arg) and arg = call.getAnArgument() and shellInterpreted = false } query predicate childCalls(PosixSpawn::ChildCall call, DataFlow::Node arg, boolean shellInterpreted) { - arg = call.getAnArgument() and - if call.isShellInterpreted(arg) then shellInterpreted = true else shellInterpreted = false + call.isShellInterpreted(arg) and shellInterpreted = true + or + not call.isShellInterpreted(arg) and arg = call.getAnArgument() and shellInterpreted = false } diff --git a/ruby/ql/test/library-tests/frameworks/arel/Arel.expected b/ruby/ql/test/library-tests/frameworks/arel/Arel.expected new file mode 100644 index 00000000000..63cd556e836 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/arel/Arel.expected @@ -0,0 +1,3 @@ +failures +#select +| arel.rb:3:8:3:18 | call to sql | arel.rb:2:7:2:14 | call to source : | arel.rb:3:8:3:18 | call to sql | $@ | arel.rb:2:7:2:14 | call to source : | call to source : | diff --git a/ruby/ql/test/library-tests/frameworks/arel/Arel.ql b/ruby/ql/test/library-tests/frameworks/arel/Arel.ql new file mode 100644 index 00000000000..197a710803e --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/arel/Arel.ql @@ -0,0 +1,11 @@ +/** + * @kind path-problem + */ + +import codeql.ruby.frameworks.Arel +import ruby +import TestUtilities.InlineFlowTest + +from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf +where conf.hasFlowPath(source, sink) +select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/frameworks/arel/arel.rb b/ruby/ql/test/library-tests/frameworks/arel/arel.rb new file mode 100644 index 00000000000..7e7bc51f9a8 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/arel/arel.rb @@ -0,0 +1,14 @@ +def m1 + x = source 1 + sink(Arel.sql(x)) # $hasTaintFlow=1 +end + +def m2 + x = 1 + sink(Arel.sql(x)) +end + +def m3 + x = source 1 + sink(Unrelated.method(x)) +end diff --git a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected new file mode 100644 index 00000000000..2550c5b4f0d --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected @@ -0,0 +1,134 @@ +pathnameInstances +| Pathname.rb:2:1:2:33 | ... = ... | +| Pathname.rb:2:1:2:33 | ... = ... | +| Pathname.rb:2:12:2:33 | call to new | +| Pathname.rb:3:1:3:20 | ... = ... | +| Pathname.rb:3:13:3:20 | foo_path | +| Pathname.rb:4:1:4:8 | foo_path | +| Pathname.rb:6:1:6:29 | ... = ... | +| Pathname.rb:6:1:6:29 | ... = ... | +| Pathname.rb:6:12:6:29 | call to new | +| Pathname.rb:9:1:9:21 | ... = ... | +| Pathname.rb:9:1:9:21 | ... = ... | +| Pathname.rb:9:8:9:21 | call to getwd | +| Pathname.rb:10:1:10:21 | ... = ... | +| Pathname.rb:10:7:10:10 | pwd1 | +| Pathname.rb:10:7:10:21 | ... + ... | +| Pathname.rb:10:14:10:21 | foo_path | +| Pathname.rb:11:1:11:21 | ... = ... | +| Pathname.rb:11:1:11:21 | ... = ... | +| Pathname.rb:11:7:11:10 | pwd1 | +| Pathname.rb:11:7:11:21 | ... / ... | +| Pathname.rb:11:14:11:21 | bar_path | +| Pathname.rb:12:1:12:19 | ... = ... | +| Pathname.rb:12:7:12:10 | pwd1 | +| Pathname.rb:12:7:12:19 | call to basename | +| Pathname.rb:13:1:13:46 | ... = ... | +| Pathname.rb:13:7:13:36 | call to new | +| Pathname.rb:13:7:13:46 | call to cleanpath | +| Pathname.rb:14:1:14:26 | ... = ... | +| Pathname.rb:14:7:14:14 | foo_path | +| Pathname.rb:14:7:14:26 | call to expand_path | +| Pathname.rb:15:1:15:39 | ... = ... | +| Pathname.rb:15:7:15:10 | pwd1 | +| Pathname.rb:15:7:15:39 | call to join | +| Pathname.rb:16:1:16:23 | ... = ... | +| Pathname.rb:16:7:16:14 | foo_path | +| Pathname.rb:16:7:16:23 | call to realpath | +| Pathname.rb:17:1:17:59 | ... = ... | +| Pathname.rb:17:7:17:33 | call to new | +| Pathname.rb:17:7:17:59 | call to relative_path_from | +| Pathname.rb:18:1:18:33 | ... = ... | +| Pathname.rb:18:1:18:33 | ... = ... | +| Pathname.rb:18:7:18:10 | pwd1 | +| Pathname.rb:18:7:18:33 | call to sub | +| Pathname.rb:19:1:19:29 | ... = ... | +| Pathname.rb:19:7:19:14 | foo_path | +| Pathname.rb:19:7:19:29 | call to sub_ext | +| Pathname.rb:20:1:20:22 | ... = ... | +| Pathname.rb:20:7:20:14 | foo_path | +| Pathname.rb:20:7:20:22 | call to to_path | +| Pathname.rb:23:14:23:21 | foo_path | +| Pathname.rb:26:12:26:19 | foo_path | +| Pathname.rb:28:11:28:14 | pwd1 | +| Pathname.rb:32:12:32:19 | foo_path | +| Pathname.rb:35:1:35:8 | foo_path | +| Pathname.rb:38:1:38:8 | foo_path | +| Pathname.rb:39:12:39:19 | foo_path | +| Pathname.rb:41:1:41:3 | p08 | +| Pathname.rb:42:1:42:3 | p01 | +fileSystemAccesses +| Pathname.rb:26:12:26:24 | call to open | Pathname.rb:26:12:26:19 | foo_path | +| Pathname.rb:28:11:28:22 | call to opendir | Pathname.rb:28:11:28:14 | pwd1 | +| Pathname.rb:32:12:32:24 | call to read | Pathname.rb:32:12:32:19 | foo_path | +| Pathname.rb:35:1:35:23 | call to write | Pathname.rb:35:1:35:8 | foo_path | +| Pathname.rb:39:12:39:34 | call to open | Pathname.rb:39:12:39:19 | foo_path | +fileNameSources +| Pathname.rb:2:1:2:33 | ... = ... | +| Pathname.rb:2:1:2:33 | ... = ... | +| Pathname.rb:2:12:2:33 | call to new | +| Pathname.rb:3:1:3:20 | ... = ... | +| Pathname.rb:3:13:3:20 | foo_path | +| Pathname.rb:4:1:4:8 | foo_path | +| Pathname.rb:6:1:6:29 | ... = ... | +| Pathname.rb:6:1:6:29 | ... = ... | +| Pathname.rb:6:12:6:29 | call to new | +| Pathname.rb:9:1:9:21 | ... = ... | +| Pathname.rb:9:1:9:21 | ... = ... | +| Pathname.rb:9:8:9:21 | call to getwd | +| Pathname.rb:10:1:10:21 | ... = ... | +| Pathname.rb:10:7:10:10 | pwd1 | +| Pathname.rb:10:7:10:21 | ... + ... | +| Pathname.rb:10:14:10:21 | foo_path | +| Pathname.rb:11:1:11:21 | ... = ... | +| Pathname.rb:11:1:11:21 | ... = ... | +| Pathname.rb:11:7:11:10 | pwd1 | +| Pathname.rb:11:7:11:21 | ... / ... | +| Pathname.rb:11:14:11:21 | bar_path | +| Pathname.rb:12:1:12:19 | ... = ... | +| Pathname.rb:12:7:12:10 | pwd1 | +| Pathname.rb:12:7:12:19 | call to basename | +| Pathname.rb:13:1:13:46 | ... = ... | +| Pathname.rb:13:7:13:36 | call to new | +| Pathname.rb:13:7:13:46 | call to cleanpath | +| Pathname.rb:14:1:14:26 | ... = ... | +| Pathname.rb:14:7:14:14 | foo_path | +| Pathname.rb:14:7:14:26 | call to expand_path | +| Pathname.rb:15:1:15:39 | ... = ... | +| Pathname.rb:15:7:15:10 | pwd1 | +| Pathname.rb:15:7:15:39 | call to join | +| Pathname.rb:16:1:16:23 | ... = ... | +| Pathname.rb:16:7:16:14 | foo_path | +| Pathname.rb:16:7:16:23 | call to realpath | +| Pathname.rb:17:1:17:59 | ... = ... | +| Pathname.rb:17:7:17:33 | call to new | +| Pathname.rb:17:7:17:59 | call to relative_path_from | +| Pathname.rb:18:1:18:33 | ... = ... | +| Pathname.rb:18:1:18:33 | ... = ... | +| Pathname.rb:18:7:18:10 | pwd1 | +| Pathname.rb:18:7:18:33 | call to sub | +| Pathname.rb:19:1:19:29 | ... = ... | +| Pathname.rb:19:7:19:14 | foo_path | +| Pathname.rb:19:7:19:29 | call to sub_ext | +| Pathname.rb:20:1:20:22 | ... = ... | +| Pathname.rb:20:7:20:14 | foo_path | +| Pathname.rb:20:7:20:22 | call to to_path | +| Pathname.rb:23:14:23:21 | foo_path | +| Pathname.rb:23:14:23:26 | call to to_s | +| Pathname.rb:26:12:26:19 | foo_path | +| Pathname.rb:28:11:28:14 | pwd1 | +| Pathname.rb:32:12:32:19 | foo_path | +| Pathname.rb:35:1:35:8 | foo_path | +| Pathname.rb:38:1:38:8 | foo_path | +| Pathname.rb:39:12:39:19 | foo_path | +| Pathname.rb:41:1:41:3 | p08 | +| Pathname.rb:42:1:42:3 | p01 | +fileSystemReadAccesses +| Pathname.rb:32:12:32:24 | call to read | Pathname.rb:32:12:32:24 | call to read | +fileSystemWriteAccesses +| Pathname.rb:35:1:35:23 | call to write | Pathname.rb:35:16:35:23 | "output" | +fileSystemPermissionModifications +| Pathname.rb:38:1:38:19 | call to chmod | Pathname.rb:38:16:38:19 | 0644 | +| Pathname.rb:39:12:39:34 | call to open | Pathname.rb:39:31:39:34 | 0666 | +| Pathname.rb:41:1:41:14 | call to mkdir | Pathname.rb:41:11:41:14 | 0755 | +| Pathname.rb:42:1:42:22 | call to mkpath | Pathname.rb:42:18:42:21 | 0644 | diff --git a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql new file mode 100644 index 00000000000..71150ae5376 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql @@ -0,0 +1,26 @@ +private import ruby +private import codeql.ruby.Concepts +private import codeql.ruby.DataFlow +private import codeql.ruby.frameworks.stdlib.Pathname + +query predicate pathnameInstances(Pathname::PathnameInstance i) { any() } + +query predicate fileSystemAccesses(FileSystemAccess a, DataFlow::Node p) { + p = a.getAPathArgument() +} + +query predicate fileNameSources(FileNameSource s) { any() } + +query predicate fileSystemReadAccesses(FileSystemReadAccess a, DataFlow::Node d) { + d = a.getADataNode() +} + +query predicate fileSystemWriteAccesses(FileSystemWriteAccess a, DataFlow::Node d) { + d = a.getADataNode() +} + +query predicate fileSystemPermissionModifications( + FileSystemPermissionModification m, DataFlow::Node p +) { + p = m.getAPermissionNode() +} diff --git a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.rb b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.rb new file mode 100644 index 00000000000..ea8f9812281 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.rb @@ -0,0 +1,42 @@ + +foo_path = Pathname.new "foo.txt" +foo_path2 = foo_path +foo_path + +bar_path = Pathname.new 'bar' + +# All these calls return new `Pathname` instances +pwd1 = Pathname.getwd +p00 = pwd1 + foo_path +p01 = pwd1 / bar_path +p02 = pwd1.basename +p03 = Pathname.new('bar/../baz.txt').cleanpath +p04 = foo_path.expand_path +p05 = pwd1.join 'bar', 'baz', 'qux.txt' +p06 = foo_path.realpath +p07 = Pathname.new('foo/bar.txt').relative_path_from('foo') +p08 = pwd1.sub 'wibble', 'wobble' +p09 = foo_path.sub_ext '.log' +p10 = foo_path.to_path + +# `Pathname#to_s` returns a string that we consider to be a filename source. +foo_string = foo_path.to_s + +# File-system accesses +foo_file = foo_path.open +foo_file.close +pwd_dir = pwd1.opendir +pwd_dir.close + +# Read from a file +foo_data = foo_path.read + +# Write to a file +foo_path.write 'output' + +# Permission modifications +foo_path.chmod 0644 +foo_file = foo_path.open 'w', 0666 +foo_file.close +p08.mkdir 0755 +p01.mkpath(mode: 0644) diff --git a/ruby/ql/test/library-tests/frameworks/railties/Railties.expected b/ruby/ql/test/library-tests/frameworks/railties/Railties.expected index c012090bbe1..42cac29b7c5 100644 --- a/ruby/ql/test/library-tests/frameworks/railties/Railties.expected +++ b/ruby/ql/test/library-tests/frameworks/railties/Railties.expected @@ -1,5 +1,14 @@ +systemCommandExecutions | Railties.rb:5:5:5:34 | call to execute_command | | Railties.rb:6:5:6:37 | call to execute_command | | Railties.rb:8:5:8:16 | call to rake | | Railties.rb:10:5:10:27 | call to rails_command | | Railties.rb:12:5:12:17 | call to git | +shellInterpretedArguments +| Railties.rb:5:5:5:34 | call to execute_command | Railties.rb:5:21:5:25 | :rake | +| Railties.rb:5:5:5:34 | call to execute_command | Railties.rb:5:28:5:33 | "test" | +| Railties.rb:6:5:6:37 | call to execute_command | Railties.rb:6:21:6:26 | :rails | +| Railties.rb:6:5:6:37 | call to execute_command | Railties.rb:6:29:6:36 | "server" | +| Railties.rb:8:5:8:16 | call to rake | Railties.rb:8:10:8:15 | "test" | +| Railties.rb:10:5:10:27 | call to rails_command | Railties.rb:10:19:10:26 | "server" | +| Railties.rb:12:5:12:17 | call to git | Railties.rb:12:9:12:16 | "status" | diff --git a/ruby/ql/test/library-tests/frameworks/railties/Railties.ql b/ruby/ql/test/library-tests/frameworks/railties/Railties.ql index 9a9731befb4..4dee50abcd5 100644 --- a/ruby/ql/test/library-tests/frameworks/railties/Railties.ql +++ b/ruby/ql/test/library-tests/frameworks/railties/Railties.ql @@ -1,5 +1,10 @@ private import ruby private import codeql.ruby.Concepts private import codeql.ruby.frameworks.Railties +private import codeql.ruby.DataFlow query predicate systemCommandExecutions(SystemCommandExecution e) { any() } + +query predicate shellInterpretedArguments(SystemCommandExecution e, DataFlow::Node arg) { + e.isShellInterpreted(arg) +} diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected new file mode 100644 index 00000000000..1fdf8045c23 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected @@ -0,0 +1,32 @@ +edges +| ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] : | +| ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] : | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | +| ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | +nodes +| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | semmle.label | call to get? | +| ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | semmle.label | call to env : | +| ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] : | semmle.label | ...[...] : | +| ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | semmle.label | call to request_method : | +| ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | semmle.label | call to method : | +| ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | semmle.label | call to raw_request_method : | +| ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | semmle.label | call to request_method_symbol : | +| ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | semmle.label | call to env : | +| ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | semmle.label | ...[...] | +subpaths +#select +| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qlref b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qlref new file mode 100644 index 00000000000..463c21cd0f2 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qlref @@ -0,0 +1 @@ +experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb new file mode 100644 index 00000000000..055e9d98638 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb @@ -0,0 +1,117 @@ +class ExampleController < ActionController::Base + # Should find + def example_action + if request.get? + Resource.find(id: params[:example_id]) + end + end + + # Should find + def other_action + method = request.env['REQUEST_METHOD'] + if method == "GET" + Resource.find(id: params[:id]) + end + end + + # Should find + def foo + method = request.request_method + if method == "GET" + Resource.find(id: params[:id]) + end + end + + # Should find + def bar + method = request.method + if method == "GET" + Resource.find(id: params[:id]) + end + end + + # Should find + def baz + method = request.raw_request_method + if method == "GET" + Resource.find(id: params[:id]) + end + end + + # Should not find + def baz2 + method = request.raw_request_method + if some_other_function == "GET" + Resource.find(id: params[:id]) + end + end + + # Should find + def foobarbaz + method = request.request_method_symbol + if method == :GET + Resource.find(id: params[:id]) + end + end + + # Should find + def resource_action + case request.env['REQUEST_METHOD'] + when "GET" + Resource.find(id: params[:id]) + when "POST" + Resource.new(id: params[:id], details: params[:details]) + end + end + + # Should not find + def resource_action + case request.random_method + when "GET" + Resource.find(id: params[:id]) + when "POST" + Resource.new(id: params[:id], details: params[:details]) + end + end +end + +class SafeController < ActionController::Base + # this class should have no hits because controllers rely on conventional Rails routes + def index + Resource.find(id: params[:id]) + end + + def create + Resource.new(id: params[:id], details: params[:details]) + end + + def update + Resource.update(id: params[:id], details: params[:details]) + end + + def delete + s = Resource.find(id: params[:id]) + s.delete + end +end + +# There should be no hits from this class because it does not inherit from ActionController +class NotAController + def example_action + if request.get? + Resource.find(params[:example_id]) + end + end + + def resource_action + case env['REQUEST_METHOD'] + when "GET" + Resource.find(params[:id]) + when "POST" + Resource.new(params[:id], params[:details]) + end + end +end + +class Resource < ActiveRecord::Base +end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected new file mode 100644 index 00000000000..14bd3e4e13f --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected @@ -0,0 +1,20 @@ +edges +| WeakParams.rb:5:28:5:53 | call to request_parameters : | WeakParams.rb:5:28:5:59 | ...[...] | +| WeakParams.rb:10:28:10:51 | call to query_parameters : | WeakParams.rb:10:28:10:57 | ...[...] | +| WeakParams.rb:15:28:15:39 | call to POST : | WeakParams.rb:15:28:15:45 | ...[...] | +| WeakParams.rb:20:28:20:38 | call to GET : | WeakParams.rb:20:28:20:44 | ...[...] | +nodes +| WeakParams.rb:5:28:5:53 | call to request_parameters : | semmle.label | call to request_parameters : | +| WeakParams.rb:5:28:5:59 | ...[...] | semmle.label | ...[...] | +| WeakParams.rb:10:28:10:51 | call to query_parameters : | semmle.label | call to query_parameters : | +| WeakParams.rb:10:28:10:57 | ...[...] | semmle.label | ...[...] | +| WeakParams.rb:15:28:15:39 | call to POST : | semmle.label | call to POST : | +| WeakParams.rb:15:28:15:45 | ...[...] | semmle.label | ...[...] | +| WeakParams.rb:20:28:20:38 | call to GET : | semmle.label | call to GET : | +| WeakParams.rb:20:28:20:44 | ...[...] | semmle.label | ...[...] | +subpaths +#select +| WeakParams.rb:5:28:5:59 | ...[...] | WeakParams.rb:5:28:5:53 | call to request_parameters : | WeakParams.rb:5:28:5:59 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | +| WeakParams.rb:10:28:10:57 | ...[...] | WeakParams.rb:10:28:10:51 | call to query_parameters : | WeakParams.rb:10:28:10:57 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | +| WeakParams.rb:15:28:15:45 | ...[...] | WeakParams.rb:15:28:15:39 | call to POST : | WeakParams.rb:15:28:15:45 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | +| WeakParams.rb:20:28:20:44 | ...[...] | WeakParams.rb:20:28:20:38 | call to GET : | WeakParams.rb:20:28:20:44 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | diff --git a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.qlref b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.qlref new file mode 100644 index 00000000000..5350e4bf40a --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.qlref @@ -0,0 +1 @@ +experimental/weak-params/WeakParams.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb new file mode 100644 index 00000000000..a5edef2e6dc --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb @@ -0,0 +1,40 @@ +class TestController < ActionController::Base + + # Should catch + def create + TestObject.create(foo: request.request_parameters[:foo]) + end + + # Should catch + def create_query + TestObject.create(foo: request.query_parameters[:foo]) + end + + # Should catch + def update_unsafe + TestObject.update(foo: request.POST[:foo]) + end + + # Should catch + def update_unsafe_get + TestObject.update(foo: request.GET[:foo]) + end + + # Should not catch + def update + TestObject.update(object_params) + end + + # strong params method + def object_params + params.require(:uuid).permit(:notes) + end + + # Should not catch + def test_non_sink + puts request.request_parameters + end +end + +class TestObject < ActiveRecord::Base +end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb b/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb index 9c314a82b34..4c8dfcca10d 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb +++ b/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb @@ -137,3 +137,17 @@ class BazController < BarController Admin.delete_by(params[:admin_condition]) end end + +class AnnotatedController < ActionController::Base + def index + name = params[:user_name] + # GOOD: string literal arguments not controlled by user are safe for annotations + users = User.annotate("this is a safe annotation").find_by(user_name: name) + end + + def unsafe_action + name = params[:user_name] + # BAD: user input passed into annotations are vulnerable to SQLi + users = User.annotate("this is an unsafe annotation:#{params[:comment]}").find_by(user_name: name) + end +end diff --git a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected index 6a9f5f771fb..dc814977cae 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected @@ -31,6 +31,8 @@ edges | ActiveRecordInjection.rb:99:11:99:17 | ...[...] : | ActiveRecordInjection.rb:104:20:104:32 | ... + ... | | ActiveRecordInjection.rb:137:21:137:26 | call to params : | ActiveRecordInjection.rb:137:21:137:44 | ...[...] : | | ActiveRecordInjection.rb:137:21:137:44 | ...[...] : | ActiveRecordInjection.rb:20:22:20:30 | condition : | +| ActiveRecordInjection.rb:151:59:151:64 | call to params : | ActiveRecordInjection.rb:151:59:151:74 | ...[...] : | +| ActiveRecordInjection.rb:151:59:151:74 | ...[...] : | ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | nodes | ActiveRecordInjection.rb:8:25:8:28 | name : | semmle.label | name : | | ActiveRecordInjection.rb:8:31:8:34 | pass : | semmle.label | pass : | @@ -80,6 +82,9 @@ nodes | ActiveRecordInjection.rb:104:20:104:32 | ... + ... | semmle.label | ... + ... | | ActiveRecordInjection.rb:137:21:137:26 | call to params : | semmle.label | call to params : | | ActiveRecordInjection.rb:137:21:137:44 | ...[...] : | semmle.label | ...[...] : | +| ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | semmle.label | "this is an unsafe annotation:..." | +| ActiveRecordInjection.rb:151:59:151:64 | call to params : | semmle.label | call to params : | +| ActiveRecordInjection.rb:151:59:151:74 | ...[...] : | semmle.label | ...[...] : | subpaths #select | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:70:23:70:28 | call to params : | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:70:23:70:28 | call to params | a user-provided value | @@ -99,3 +104,4 @@ subpaths | ActiveRecordInjection.rb:88:18:88:35 | ...[...] | ActiveRecordInjection.rb:88:18:88:23 | call to params : | ActiveRecordInjection.rb:88:18:88:35 | ...[...] | This SQL query depends on $@. | ActiveRecordInjection.rb:88:18:88:23 | call to params | a user-provided value | | ActiveRecordInjection.rb:92:21:92:35 | ...[...] | ActiveRecordInjection.rb:92:21:92:26 | call to params : | ActiveRecordInjection.rb:92:21:92:35 | ...[...] | This SQL query depends on $@. | ActiveRecordInjection.rb:92:21:92:26 | call to params | a user-provided value | | ActiveRecordInjection.rb:104:20:104:32 | ... + ... | ActiveRecordInjection.rb:98:10:98:15 | call to params : | ActiveRecordInjection.rb:104:20:104:32 | ... + ... | This SQL query depends on $@. | ActiveRecordInjection.rb:98:10:98:15 | call to params | a user-provided value | +| ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | ActiveRecordInjection.rb:151:59:151:64 | call to params : | ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | This SQL query depends on $@. | ActiveRecordInjection.rb:151:59:151:64 | call to params | a user-provided value | diff --git a/swift/codegen/generators/cppgen.py b/swift/codegen/generators/cppgen.py index ef042f42dbd..420e82605e1 100644 --- a/swift/codegen/generators/cppgen.py +++ b/swift/codegen/generators/cppgen.py @@ -65,7 +65,7 @@ class Processor: return cpp.Class( name=name, bases=[self._get_class(b) for b in cls.bases], - fields=[_get_field(cls, p) for p in cls.properties], + fields=[_get_field(cls, p) for p in cls.properties if "cpp_skip" not in p.pragmas], final=not cls.derived, trap_name=trap_name, ) diff --git a/swift/codegen/generators/qlgen.py b/swift/codegen/generators/qlgen.py index 26cce2ec430..b2e65cf86cb 100755 --- a/swift/codegen/generators/qlgen.py +++ b/swift/codegen/generators/qlgen.py @@ -30,7 +30,7 @@ class ModifiedStubMarkedAsGeneratedError(Error): def get_ql_property(cls: schema.Class, prop: schema.Property): common_args = dict( type=prop.type if not prop.is_predicate else "predicate", - skip_qltest="skip_qltest" in prop.pragmas, + qltest_skip="qltest_skip" in prop.pragmas, is_child=prop.is_child, is_optional=prop.is_optional, is_predicate=prop.is_predicate, @@ -69,13 +69,14 @@ def get_ql_property(cls: schema.Class, prop: schema.Property): def get_ql_class(cls: schema.Class): + pragmas = {k: True for k in cls.pragmas if k.startswith("ql")} return ql.Class( name=cls.name, bases=cls.bases, final=not cls.derived, properties=[get_ql_property(cls, p) for p in cls.properties], dir=cls.dir, - skip_qltest="skip_qltest" in cls.pragmas, + **pragmas, ) @@ -143,7 +144,7 @@ def _get_all_properties_to_be_tested(cls: ql.Class, lookup: typing.Dict[str, ql. # deduplicate using id already_seen = set() for c, p in _get_all_properties(cls, lookup): - if not (c.skip_qltest or p.skip_qltest or id(p) in already_seen): + if not (c.qltest_skip or p.qltest_skip or id(p) in already_seen): already_seen.add(id(p)) yield ql.PropertyForTest(p.getter, p.type, p.is_single, p.is_predicate, p.is_repeated) @@ -156,6 +157,20 @@ def _partition(l, pred): return res +def _is_in_qltest_collapsed_hierachy(cls: ql.Class, lookup: typing.Dict[str, ql.Class]): + return cls.qltest_collapse_hierarchy or _is_under_qltest_collapsed_hierachy(cls, lookup) + + +def _is_under_qltest_collapsed_hierachy(cls: ql.Class, lookup: typing.Dict[str, ql.Class]): + return not cls.qltest_uncollapse_hierarchy and any( + _is_in_qltest_collapsed_hierachy(lookup[b], lookup) for b in cls.bases) + + +def _should_skip_qltest(cls: ql.Class, lookup: typing.Dict[str, ql.Class]): + return cls.qltest_skip or not (cls.final or cls.qltest_collapse_hierarchy) or _is_under_qltest_collapsed_hierachy( + cls, lookup) + + def generate(opts, renderer): input = opts.schema out = opts.ql_output @@ -196,7 +211,7 @@ def generate(opts, renderer): classes), out / 'GetImmediateParent.qll') for c in classes: - if not c.final or c.skip_qltest: + if _should_skip_qltest(c, lookup): continue test_dir = test_out / c.path test_dir.mkdir(parents=True, exist_ok=True) diff --git a/swift/codegen/generators/trapgen.py b/swift/codegen/generators/trapgen.py index eb701b629ef..22c46e6e146 100755 --- a/swift/codegen/generators/trapgen.py +++ b/swift/codegen/generators/trapgen.py @@ -86,11 +86,10 @@ def generate(opts, renderer): renderer.render(cpp.TrapList(entries, opts.dbscheme), out / dir / "TrapEntries") tags = [] - for index, tag in enumerate(toposort_flatten(tag_graph)): + for tag in toposort_flatten(tag_graph): tags.append(cpp.Tag( name=get_tag_name(tag), bases=[get_tag_name(b) for b in sorted(tag_graph[tag])], - index=index, id=tag, )) renderer.render(cpp.TagList(tags, opts.dbscheme), out / "TrapTags") diff --git a/swift/codegen/lib/cpp.py b/swift/codegen/lib/cpp.py index 9eb5f78af58..3542efcdee9 100644 --- a/swift/codegen/lib/cpp.py +++ b/swift/codegen/lib/cpp.py @@ -83,7 +83,6 @@ class TagBase: class Tag: name: str bases: List[TagBase] - index: int id: str def __post_init__(self): diff --git a/swift/codegen/lib/ql.py b/swift/codegen/lib/ql.py index ce8dbed3a90..1635fd70689 100644 --- a/swift/codegen/lib/ql.py +++ b/swift/codegen/lib/ql.py @@ -37,7 +37,7 @@ class Property: is_optional: bool = False is_predicate: bool = False is_child: bool = False - skip_qltest: bool = False + qltest_skip: bool = False def __post_init__(self): if self.tableparams: @@ -79,7 +79,9 @@ class Class: properties: List[Property] = field(default_factory=list) dir: pathlib.Path = pathlib.Path() imports: List[str] = field(default_factory=list) - skip_qltest: bool = False + qltest_skip: bool = False + qltest_collapse_hierarchy: bool = False + qltest_uncollapse_hierarchy: bool = False def __post_init__(self): self.bases = sorted(self.bases) diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index ce071b930d2..83e2c87ef4e 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -7,21 +7,24 @@ _includes: _directories: decl: Decl$|Context$ pattern: Pattern$ - type: Type$ - typerepr: TypeRepr$ + type: Type(Repr)?$ expr: Expr$ stmt: Stmt$ Element: - is_unknown: predicate - _pragma: skip_qltest + is_unknown: + type: predicate + _pragma: cpp_skip # this is emitted using trap entries directly + _pragma: qltest_skip File: name: string Locatable: - location: Location? - _pragma: skip_qltest + location: + type: Location? + _pragma: cpp_skip # this is emitted using trap entries directly + _pragma: qltest_skip Location: file: File @@ -29,10 +32,10 @@ Location: start_column: int end_line: int end_column: int - _pragma: skip_qltest + _pragma: qltest_skip Type: - diagnostics_name: string + name: string canonical_type: Type IterableDeclContext: @@ -85,6 +88,7 @@ AnyMetatypeType: BuiltinType: _extends: Type + _pragma: qltest_collapse_hierarchy DependentMemberType: _extends: Type @@ -108,12 +112,14 @@ LValueType: ModuleType: _extends: Type + module: ModuleDecl PlaceholderType: _extends: Type ProtocolCompositionType: _extends: Type + members: Type* ExistentialType: _extends: Type @@ -179,6 +185,7 @@ Stmt: TypeRepr: _extends: AstNode + type: Type? # type can be absent on unresolved entities FunctionType: _extends: AnyFunctionType @@ -243,14 +250,12 @@ WeakStorageType: ArchetypeType: _extends: SubstitutableType - name: string interface_type: Type superclass: Type? protocols: ProtocolDecl* GenericTypeParamType: _extends: SubstitutableType - name: string ParenType: _extends: SugarType @@ -270,9 +275,22 @@ EnumCaseDecl: IfConfigDecl: _extends: Decl + _children: + clauses: IfConfigClause* + +IfConfigClause: + _extends: Locatable + _children: + condition: Expr? + elements: AstNode* + is_active: predicate + _dir: decl ImportDecl: _extends: Decl + is_exported: predicate + module: ModuleDecl + declarations: ValueDecl* MissingMemberDecl: _extends: Decl @@ -316,6 +334,7 @@ AppliedPropertyWrapperExpr: _extends: Expr Argument: + _extends: Locatable label: string _children: expr: Expr @@ -388,12 +407,11 @@ EnumIsCaseExpr: _extends: Expr _children: sub_expr: Expr - type_repr: TypeRepr element: EnumElementDecl ErrorExpr: _extends: Expr - _pragma: skip_qltest # unexpected emission + _pragma: qltest_skip # unexpected emission ExplicitCastExpr: _extends: Expr @@ -439,7 +457,7 @@ KeyPathDotExpr: KeyPathExpr: _extends: Expr _children: - parsed_root: Expr? + root: TypeRepr? parsed_path: Expr? LazyInitializerExpr: @@ -468,7 +486,7 @@ ObjCSelectorExpr: _children: sub_expr: Expr method: AbstractFunctionDecl - _pragma: skip_qltest # to be tested in integration tests + _pragma: qltest_skip # to be tested in integration tests OneWayExpr: _extends: Expr @@ -510,7 +528,7 @@ SequenceExpr: _extends: Expr _children: elements: Expr* - _pragma: skip_qltest # we should really never extract these, as these should be resolved to trees of operations + _pragma: qltest_skip # we should really never extract these, as these should be resolved to trees of operations SuperRefExpr: _extends: Expr @@ -542,7 +560,6 @@ TypeExpr: UnresolvedDeclRefExpr: _extends: Expr name: string? - _pragma: skip_qltest # we should really never extract these UnresolvedDotExpr: _extends: Expr @@ -553,15 +570,16 @@ UnresolvedDotExpr: UnresolvedMemberExpr: _extends: Expr name: string - _pragma: skip_qltest # we should really never extract these + _pragma: qltest_skip # we should really never extract these UnresolvedPatternExpr: _extends: Expr - _pragma: skip_qltest # we should really never extract these + _children: + sub_pattern: Pattern UnresolvedSpecializeExpr: _extends: Expr - _pragma: skip_qltest # we should really never extract these + _pragma: qltest_skip # we should really never extract these VarargExpansionExpr: _extends: Expr @@ -698,6 +716,7 @@ BuiltinIntegerLiteralType: BuiltinIntegerType: _extends: AnyBuiltinIntegerType + _pragma: qltest_uncollapse_hierarchy width: int? NestedArchetypeType: @@ -830,11 +849,11 @@ ArrayToPointerExpr: BridgeFromObjCExpr: _extends: ImplicitConversionExpr - _pragma: skip_qltest # to be tested in integration tests + _pragma: qltest_skip # to be tested in integration tests BridgeToObjCExpr: _extends: ImplicitConversionExpr - _pragma: skip_qltest # to be tested in integration tests + _pragma: qltest_skip # to be tested in integration tests ClassMetatypeToObjectExpr: _extends: ImplicitConversionExpr @@ -844,7 +863,7 @@ CollectionUpcastConversionExpr: ConditionalBridgeFromObjCExpr: _extends: ImplicitConversionExpr - _pragma: skip_qltest # to be tested in integration tests + _pragma: qltest_skip # to be tested in integration tests CovariantFunctionConversionExpr: _extends: ImplicitConversionExpr @@ -1066,6 +1085,8 @@ GenericTypeDecl: ModuleDecl: _extends: TypeDecl + is_builtin_module: predicate + is_system_module: predicate ConstructorRefCallExpr: _extends: SelfApplyExpr @@ -1156,87 +1177,3 @@ FloatLiteralExpr: IntegerLiteralExpr: _extends: NumberLiteralExpr string_value: string - -ErrorTypeRepr: - _extends: TypeRepr - -AttributedTypeRepr: - _extends: TypeRepr - -IdentTypeRepr: - _extends: TypeRepr - -ComponentIdentTypeRepr: - _extends: IdentTypeRepr - -SimpleIdentTypeRepr: - _extends: ComponentIdentTypeRepr - -GenericIdentTypeRepr: - _extends: ComponentIdentTypeRepr - -CompoundIdentTypeRepr: - _extends: IdentTypeRepr - -FunctionTypeRepr: - _extends: TypeRepr - -ArrayTypeRepr: - _extends: TypeRepr - -DictionaryTypeRepr: - _extends: TypeRepr - -OptionalTypeRepr: - _extends: TypeRepr - -ImplicitlyUnwrappedOptionalTypeRepr: - _extends: TypeRepr - -TupleTypeRepr: - _extends: TypeRepr - -CompositionTypeRepr: - _extends: TypeRepr - -MetatypeTypeRepr: - _extends: TypeRepr - -ProtocolTypeRepr: - _extends: TypeRepr - -OpaqueReturnTypeRepr: - _extends: TypeRepr - -NamedOpaqueReturnTypeRepr: - _extends: TypeRepr - -ExistentialTypeRepr: - _extends: TypeRepr - -PlaceholderTypeRepr: - _extends: TypeRepr - -SpecifierTypeRepr: - _extends: TypeRepr - -InOutTypeRepr: - _extends: SpecifierTypeRepr - -SharedTypeRepr: - _extends: SpecifierTypeRepr - -OwnedTypeRepr: - _extends: SpecifierTypeRepr - -IsolatedTypeRepr: - _extends: SpecifierTypeRepr - -CompileTimeConstTypeRepr: - _extends: SpecifierTypeRepr - -FixedTypeRepr: - _extends: TypeRepr - -SilBoxTypeRepr: - _extends: TypeRepr diff --git a/swift/codegen/templates/cpp_classes_cpp.mustache b/swift/codegen/templates/cpp_classes_cpp.mustache index fbe403bcc0f..d78c89fc3c7 100644 --- a/swift/codegen/templates/cpp_classes_cpp.mustache +++ b/swift/codegen/templates/cpp_classes_cpp.mustache @@ -24,10 +24,10 @@ void {{name}}::emit({{^final}}TrapLabel<{{name}}Tag> id, {{/final}}std::ostream& {{#is_repeated}} for (auto i = 0u; i < {{field_name}}.size(); ++i) { {{^is_optional}} - out << {{trap_name}}Trap{id, i, {{field_name}}[i]}; + out << {{trap_name}}Trap{id, i, {{field_name}}[i]} << '\n'; {{/is_optional}} {{#is_optional}} - if ({{field_name}}[i]) out << {{trap_name}}Trap{id, i, *{{field_name}}[i]}; + if ({{field_name}}[i]) out << {{trap_name}}Trap{id, i, *{{field_name}}[i]} << '\n'; {{/is_optional}} } {{/is_repeated}} diff --git a/swift/codegen/templates/trap_tags_h.mustache b/swift/codegen/templates/trap_tags_h.mustache index feac64ff92a..c444d28afcb 100644 --- a/swift/codegen/templates/trap_tags_h.mustache +++ b/swift/codegen/templates/trap_tags_h.mustache @@ -7,7 +7,7 @@ namespace codeql { // {{id}} struct {{name}}Tag {{#has_bases}}: {{#bases}}{{^first}}, {{/first}}{{base}}Tag{{/bases}} {{/has_bases}}{ - static constexpr const char* prefix = "{{index}}"; + static constexpr const char* prefix = "{{name}}"; }; {{/tags}} } diff --git a/swift/codegen/test/test_cpp.py b/swift/codegen/test/test_cpp.py index e6cd4f81305..d04877e38c4 100644 --- a/swift/codegen/test/test_cpp.py +++ b/swift/codegen/test/test_cpp.py @@ -65,7 +65,7 @@ def test_trap_has_first_field_marked(): def test_tag_has_first_base_marked(): bases = ["a", "b", "c"] expected = [cpp.TagBase("a", first=True), cpp.TagBase("b"), cpp.TagBase("c")] - t = cpp.Tag("name", bases, 0, "id") + t = cpp.Tag("name", bases, "id") assert t.bases == expected @@ -75,7 +75,7 @@ def test_tag_has_first_base_marked(): (["a", "b"], True) ]) def test_tag_has_bases(bases, expected): - t = cpp.Tag("name", bases, 0, "id") + t = cpp.Tag("name", bases, "id") assert t.has_bases is expected diff --git a/swift/codegen/test/test_cppgen.py b/swift/codegen/test/test_cppgen.py index 160dd6cd2c1..7938cb6decd 100644 --- a/swift/codegen/test/test_cppgen.py +++ b/swift/codegen/test/test_cppgen.py @@ -165,5 +165,18 @@ def test_classes_with_dirs(generate_grouped): } +def test_cpp_skip_pragma(generate): + assert generate([ + schema.Class(name="A", properties=[ + schema.SingleProperty("x", "foo"), + schema.SingleProperty("y", "bar", pragmas=["x", "cpp_skip", "y"]), + ]) + ]) == [ + cpp.Class(name="A", final=True, trap_name="As", fields=[ + cpp.Field("x", "foo"), + ]), + ] + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) diff --git a/swift/codegen/test/test_qlgen.py b/swift/codegen/test/test_qlgen.py index 78f67012077..f861d14f2de 100644 --- a/swift/codegen/test/test_qlgen.py +++ b/swift/codegen/test/test_qlgen.py @@ -480,13 +480,13 @@ def test_test_properties_skipped(opts, generate_tests): write(opts.ql_test_output / "Derived" / "test.swift") assert generate_tests([ schema.Class("Base", derived={"Derived"}, properties=[ - schema.SingleProperty("x", "string", pragmas=["skip_qltest", "foo"]), - schema.RepeatedProperty("y", "int", pragmas=["bar", "skip_qltest"]), + schema.SingleProperty("x", "string", pragmas=["qltest_skip", "foo"]), + schema.RepeatedProperty("y", "int", pragmas=["bar", "qltest_skip"]), ]), schema.Class("Derived", bases={"Base"}, properties=[ - schema.PredicateProperty("a", pragmas=["skip_qltest"]), + schema.PredicateProperty("a", pragmas=["qltest_skip"]), schema.OptionalProperty( - "b", "int", pragmas=["bar", "skip_qltest", "baz"]), + "b", "int", pragmas=["bar", "qltest_skip", "baz"]), ]), ]) == { "Derived/Derived.ql": ql.ClassTester(class_name="Derived"), @@ -496,7 +496,7 @@ def test_test_properties_skipped(opts, generate_tests): def test_test_base_class_skipped(opts, generate_tests): write(opts.ql_test_output / "Derived" / "test.swift") assert generate_tests([ - schema.Class("Base", derived={"Derived"}, pragmas=["skip_qltest", "foo"], properties=[ + schema.Class("Base", derived={"Derived"}, pragmas=["qltest_skip", "foo"], properties=[ schema.SingleProperty("x", "string"), schema.RepeatedProperty("y", "int"), ]), @@ -510,12 +510,54 @@ def test_test_final_class_skipped(opts, generate_tests): write(opts.ql_test_output / "Derived" / "test.swift") assert generate_tests([ schema.Class("Base", derived={"Derived"}), - schema.Class("Derived", bases={"Base"}, pragmas=["skip_qltest", "foo"], properties=[ + schema.Class("Derived", bases={"Base"}, pragmas=["qltest_skip", "foo"], properties=[ schema.SingleProperty("x", "string"), schema.RepeatedProperty("y", "int"), ]), ]) == {} +def test_test_class_hierarchy_collapse(opts, generate_tests): + write(opts.ql_test_output / "Base" / "test.swift") + assert generate_tests([ + schema.Class("Base", derived={"D1", "D2"}, pragmas=["foo", "qltest_collapse_hierarchy"]), + schema.Class("D1", bases={"Base"}, properties=[schema.SingleProperty("x", "string")]), + schema.Class("D2", bases={"Base"}, derived={"D3"}, properties=[schema.SingleProperty("y", "string")]), + schema.Class("D3", bases={"D2"}, properties=[schema.SingleProperty("z", "string")]), + ]) == { + "Base/Base.ql": ql.ClassTester(class_name="Base"), + } + + +def test_test_class_hierarchy_uncollapse(opts, generate_tests): + for d in ("Base", "D3", "D4"): + write(opts.ql_test_output / d / "test.swift") + assert generate_tests([ + schema.Class("Base", derived={"D1", "D2"}, pragmas=["foo", "qltest_collapse_hierarchy"]), + schema.Class("D1", bases={"Base"}, properties=[schema.SingleProperty("x", "string")]), + schema.Class("D2", bases={"Base"}, derived={"D3", "D4"}, pragmas=["qltest_uncollapse_hierarchy", "bar"]), + schema.Class("D3", bases={"D2"}), + schema.Class("D4", bases={"D2"}), + ]) == { + "Base/Base.ql": ql.ClassTester(class_name="Base"), + "D3/D3.ql": ql.ClassTester(class_name="D3"), + "D4/D4.ql": ql.ClassTester(class_name="D4"), + } + + +def test_test_class_hierarchy_uncollapse_at_final(opts, generate_tests): + for d in ("Base", "D3"): + write(opts.ql_test_output / d / "test.swift") + assert generate_tests([ + schema.Class("Base", derived={"D1", "D2"}, pragmas=["foo", "qltest_collapse_hierarchy"]), + schema.Class("D1", bases={"Base"}, properties=[schema.SingleProperty("x", "string")]), + schema.Class("D2", bases={"Base"}, derived={"D3"}), + schema.Class("D3", bases={"D2"}, pragmas=["qltest_uncollapse_hierarchy", "bar"]), + ]) == { + "Base/Base.ql": ql.ClassTester(class_name="Base"), + "D3/D3.ql": ql.ClassTester(class_name="D3"), + } + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) diff --git a/swift/codegen/test/test_trapgen.py b/swift/codegen/test/test_trapgen.py index 376f69c43a3..c8121ce48ba 100644 --- a/swift/codegen/test/test_trapgen.py +++ b/swift/codegen/test/test_trapgen.py @@ -162,10 +162,10 @@ def test_one_union_tags(generate_tags): assert generate_tags([ dbscheme.Union(lhs="@left_hand_side", rhs=["@b", "@a", "@c"]), ]) == [ - cpp.Tag(name="LeftHandSide", bases=[], index=0, id="@left_hand_side"), - cpp.Tag(name="A", bases=["LeftHandSide"], index=1, id="@a"), - cpp.Tag(name="B", bases=["LeftHandSide"], index=2, id="@b"), - cpp.Tag(name="C", bases=["LeftHandSide"], index=3, id="@c"), + cpp.Tag(name="LeftHandSide", bases=[], id="@left_hand_side"), + cpp.Tag(name="A", bases=["LeftHandSide"], id="@a"), + cpp.Tag(name="B", bases=["LeftHandSide"], id="@b"), + cpp.Tag(name="C", bases=["LeftHandSide"], id="@c"), ] @@ -175,12 +175,12 @@ def test_multiple_union_tags(generate_tags): dbscheme.Union(lhs="@a", rhs=["@b", "@c"]), dbscheme.Union(lhs="@e", rhs=["@c", "@f"]), ]) == [ - cpp.Tag(name="D", bases=[], index=0, id="@d"), - cpp.Tag(name="E", bases=[], index=1, id="@e"), - cpp.Tag(name="A", bases=["D"], index=2, id="@a"), - cpp.Tag(name="F", bases=["E"], index=3, id="@f"), - cpp.Tag(name="B", bases=["A"], index=4, id="@b"), - cpp.Tag(name="C", bases=["A", "E"], index=5, id="@c"), + cpp.Tag(name="D", bases=[], id="@d"), + cpp.Tag(name="E", bases=[], id="@e"), + cpp.Tag(name="A", bases=["D"], id="@a"), + cpp.Tag(name="F", bases=["E"], id="@f"), + cpp.Tag(name="B", bases=["A"], id="@b"), + cpp.Tag(name="C", bases=["A", "E"], id="@c"), ] diff --git a/swift/extractor/BUILD.bazel b/swift/extractor/BUILD.bazel index b81778e8fe2..bf5c9e65d52 100644 --- a/swift/extractor/BUILD.bazel +++ b/swift/extractor/BUILD.bazel @@ -2,12 +2,10 @@ load("//swift:rules.bzl", "swift_cc_binary") swift_cc_binary( name = "extractor", - srcs = [ - "SwiftExtractor.cpp", - "SwiftExtractor.h", - "SwiftExtractorConfiguration.h", - "main.cpp", - ], + srcs = glob([ + "*.h", + "*.cpp", + ]), visibility = ["//swift:__pkg__"], deps = [ "//swift/extractor/infra", diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 6c210bdeefe..22f4f01a470 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -1,12 +1,9 @@ #include "SwiftExtractor.h" -#include -#include #include -#include #include -#include #include +#include #include #include @@ -15,10 +12,12 @@ #include #include "swift/extractor/trap/generated/TrapClasses.h" -#include "swift/extractor/trap/TrapOutput.h" +#include "swift/extractor/trap/TrapDomain.h" #include "swift/extractor/visitors/SwiftVisitor.h" +#include "swift/extractor/TargetTrapFile.h" using namespace codeql; +using namespace std::string_literals; static void archiveFile(const SwiftExtractorConfiguration& config, swift::SourceFile& file) { if (std::error_code ec = llvm::sys::fs::create_directories(config.trapDir)) { @@ -51,81 +50,68 @@ static void archiveFile(const SwiftExtractorConfiguration& config, swift::Source } } +static std::string getFilename(swift::ModuleDecl& module, swift::SourceFile* primaryFile) { + if (primaryFile) { + return primaryFile->getFilename().str(); + } + // PCM clang module + if (module.isNonSwiftModule()) { + // Several modules with different names might come from .pcm (clang module) files + // In this case we want to differentiate them + // Moreover, pcm files may come from caches located in different directories, but are + // unambiguously identified by the base file name, so we can discard the absolute directory + std::string filename = "/pcms/"s + llvm::sys::path::filename(module.getModuleFilename()).str(); + filename += "-"; + filename += module.getName().str(); + return filename; + } + return module.getModuleFilename().str(); +} + +static llvm::SmallVector getTopLevelDecls(swift::ModuleDecl& module, + swift::SourceFile* primaryFile = nullptr) { + llvm::SmallVector ret; + ret.push_back(&module); + if (primaryFile) { + primaryFile->getTopLevelDecls(ret); + } else { + module.getTopLevelDecls(ret); + } + return ret; +} + static void extractDeclarations(const SwiftExtractorConfiguration& config, - llvm::ArrayRef topLevelDecls, swift::CompilerInstance& compiler, swift::ModuleDecl& module, swift::SourceFile* primaryFile = nullptr) { + auto filename = getFilename(module, primaryFile); + // The extractor can be called several times from different processes with - // the same input file(s) - // We are using PID to avoid concurrent access - // TODO: find a more robust approach to avoid collisions? - llvm::StringRef filename = primaryFile ? primaryFile->getFilename() : module.getModuleFilename(); - std::string tempTrapName = filename.str() + '.' + std::to_string(getpid()) + ".trap"; - llvm::SmallString tempTrapPath(config.trapDir); - llvm::sys::path::append(tempTrapPath, tempTrapName); - - llvm::StringRef trapParent = llvm::sys::path::parent_path(tempTrapPath); - if (std::error_code ec = llvm::sys::fs::create_directories(trapParent)) { - std::cerr << "Cannot create trap directory '" << trapParent.str() << "': " << ec.message() - << "\n"; + // the same input file(s). Using `TargetFile` the first process will win, and the following + // will just skip the work + auto trapTarget = createTargetTrapFile(config, filename); + if (!trapTarget) { + // another process arrived first, nothing to do for us return; } + TrapDomain trap{*trapTarget}; - std::ofstream trapStream(tempTrapPath.str().str()); - if (!trapStream) { - std::error_code ec; - ec.assign(errno, std::generic_category()); - std::cerr << "Cannot create temp trap file '" << tempTrapPath.str().str() - << "': " << ec.message() << "\n"; - return; - } - trapStream << "// extractor-args: "; - for (auto opt : config.frontendOptions) { - trapStream << std::quoted(opt) << " "; - } - trapStream << "\n\n"; - - TrapOutput trap{trapStream}; - TrapArena arena{}; - - // TODO: move default location emission elsewhere, possibly in a separate global trap file - auto unknownFileLabel = arena.allocateLabel(); + // TODO: remove this and recreate it with IPA when we have that // the following cannot conflict with actual files as those have an absolute path starting with / - trap.assignKey(unknownFileLabel, "unknown"); - trap.emit(FilesTrap{unknownFileLabel}); - auto unknownLocationLabel = arena.allocateLabel(); - trap.assignKey(unknownLocationLabel, "unknown"); - trap.emit(LocationsTrap{unknownLocationLabel, unknownFileLabel}); + File unknownFileEntry{trap.createLabel("unknown")}; + Location unknownLocationEntry{trap.createLabel("unknown")}; + unknownLocationEntry.file = unknownFileEntry.id; + trap.emit(unknownFileEntry); + trap.emit(unknownLocationEntry); - SwiftVisitor visitor(compiler.getSourceMgr(), arena, trap, module, primaryFile); + SwiftVisitor visitor(compiler.getSourceMgr(), trap, module, primaryFile); + auto topLevelDecls = getTopLevelDecls(module, primaryFile); for (auto decl : topLevelDecls) { visitor.extract(decl); } - if (topLevelDecls.empty()) { - // In the case of empty files, the dispatcher is not called, but we still want to 'record' the - // fact that the file was extracted - llvm::SmallString name(filename); - llvm::sys::fs::make_absolute(name); - auto fileLabel = arena.allocateLabel(); - trap.assignKey(fileLabel, name.str().str()); - trap.emit(FilesTrap{fileLabel, name.str().str()}); - } - - // TODO: Pick a better name to avoid collisions - std::string trapName = filename.str() + ".trap"; - llvm::SmallString trapPath(config.trapDir); - llvm::sys::path::append(trapPath, trapName); - - // TODO: The last process wins. Should we do better than that? - if (std::error_code ec = llvm::sys::fs::rename(tempTrapPath, trapPath)) { - std::cerr << "Cannot rename temp trap file '" << tempTrapPath.str().str() << "' -> '" - << trapPath.str().str() << "': " << ec.message() << "\n"; - } } -void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, - swift::CompilerInstance& compiler) { +static std::unordered_set collectInputFilenames(swift::CompilerInstance& compiler) { // The frontend can be called in many different ways. // At each invocation we only extract system and builtin modules and any input source files that // have an output associated with them. @@ -136,26 +122,57 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, sourceFiles.insert(input.getFileName()); } } + return sourceFiles; +} +static std::unordered_set collectModules(swift::CompilerInstance& compiler) { + // getASTContext().getLoadedModules() does not provide all the modules available within the + // program. + // We need to iterate over all the imported modules (recursively) to see the whole "universe." + std::unordered_set allModules; + std::queue worklist; for (auto& [_, module] : compiler.getASTContext().getLoadedModules()) { - // We only extract system and builtin modules here as the other "user" modules can be built - // during the build process and then re-used at a later stage. In this case, we extract the - // user code twice: once during the module build in a form of a source file, and then as - // a pre-built module during building of the dependent source files. - if (module->isSystemModule() || module->isBuiltinModule()) { - llvm::SmallVector decls; - module->getTopLevelDecls(decls); - // TODO: pass ModuleDecl directly when we have module extraction in place? - extractDeclarations(config, decls, compiler, *module); - } else { - for (auto file : module->getFiles()) { - auto sourceFile = llvm::dyn_cast(file); - if (!sourceFile || sourceFiles.count(sourceFile->getFilename().str()) == 0) { - continue; - } - archiveFile(config, *sourceFile); - extractDeclarations(config, sourceFile->getTopLevelDecls(), compiler, *module, sourceFile); + worklist.push(module); + allModules.insert(module); + } + + while (!worklist.empty()) { + auto module = worklist.front(); + worklist.pop(); + llvm::SmallVector importedModules; + // TODO: we may need more than just Exported ones + module->getImportedModules(importedModules, swift::ModuleDecl::ImportFilterKind::Exported); + for (auto& imported : importedModules) { + if (allModules.count(imported.importedModule) == 0) { + worklist.push(imported.importedModule); + allModules.insert(imported.importedModule); } } } + return allModules; +} + +void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, + swift::CompilerInstance& compiler) { + auto inputFiles = collectInputFilenames(compiler); + auto modules = collectModules(compiler); + + for (auto& module : modules) { + bool isFromSourceFile = false; + for (auto file : module->getFiles()) { + auto sourceFile = llvm::dyn_cast(file); + if (!sourceFile) { + continue; + } + isFromSourceFile = true; + if (inputFiles.count(sourceFile->getFilename().str()) == 0) { + continue; + } + archiveFile(config, *sourceFile); + extractDeclarations(config, compiler, *module, sourceFile); + } + if (!isFromSourceFile) { + extractDeclarations(config, compiler, *module); + } + } } diff --git a/swift/extractor/SwiftExtractorConfiguration.h b/swift/extractor/SwiftExtractorConfiguration.h index bf75fdb3b41..cd4ed51cdcd 100644 --- a/swift/extractor/SwiftExtractorConfiguration.h +++ b/swift/extractor/SwiftExtractorConfiguration.h @@ -3,13 +3,37 @@ #include #include +#include "swift/extractor/infra/TargetFile.h" + namespace codeql { struct SwiftExtractorConfiguration { // The location for storing TRAP files to be imported by CodeQL engine. std::string trapDir; // The location for storing extracted source files. std::string sourceArchiveDir; - // The arguments passed to the extractor. Used for debugging. + // A temporary directory that exists during database creation, but is deleted once the DB is + // finalized. + std::string scratchDir; + + // The original arguments passed to the extractor. Used for debugging. std::vector frontendOptions; + // The patched arguments passed to the swift::performFrontend/ Used for debugging. + std::vector patchedFrontendOptions; + + // A temporary directory that contains TRAP files before they are moved into their final + // destination. + std::string getTempTrapDir() const { return scratchDir + "/swift-trap-temp"; } + + // VFS (virtual file system) support. + // A temporary directory that contains VFS files used during extraction. + std::string getVFSDir() const { return scratchDir + "/swift-vfs"; } + + // A temporary directory that contains temp VFS files before they moved into VFSDir. + std::string getTempVFSDir() const { return scratchDir + "/swift-vfs-temp"; } + + // A temporary directory that contains build artifacts generated by the extractor during the + // overall extraction process. + std::string getTempArtifactDir() const { return scratchDir + "/swift-extraction-artifacts"; } }; + } // namespace codeql diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp new file mode 100644 index 00000000000..b09a558d187 --- /dev/null +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -0,0 +1,341 @@ +#include "SwiftOutputRewrite.h" +#include "swift/extractor/SwiftExtractorConfiguration.h" +#include "swift/extractor/TargetTrapFile.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Creates a copy of the output file map and updates remapping table in place +// It does not change the original map file as it is depended upon by the original compiler +// Returns path to the newly created output file map on success, or None in a case of failure +static std::optional rewriteOutputFileMap( + const codeql::SwiftExtractorConfiguration& config, + const std::string& outputFileMapPath, + const std::vector& inputs, + std::unordered_map& remapping) { + auto newMapPath = config.getTempArtifactDir() + '/' + outputFileMapPath; + + // TODO: do not assume absolute path for the second parameter + auto outputMapOrError = swift::OutputFileMap::loadFromPath(outputFileMapPath, ""); + if (!outputMapOrError) { + std::cerr << "Cannot load output map: '" << outputFileMapPath << "'\n"; + return std::nullopt; + } + auto oldOutputMap = outputMapOrError.get(); + swift::OutputFileMap newOutputMap; + std::vector keys; + for (auto& key : inputs) { + auto oldMap = oldOutputMap.getOutputMapForInput(key); + if (!oldMap) { + continue; + } + keys.push_back(key); + auto& newMap = newOutputMap.getOrCreateOutputMapForInput(key); + newMap.copyFrom(*oldMap); + for (auto& entry : newMap) { + auto oldPath = entry.getSecond(); + auto newPath = config.getTempArtifactDir() + '/' + oldPath; + entry.getSecond() = newPath; + remapping[oldPath] = newPath; + } + } + std::error_code ec; + llvm::SmallString filepath(newMapPath); + llvm::StringRef parent = llvm::sys::path::parent_path(filepath); + if (std::error_code ec = llvm::sys::fs::create_directories(parent)) { + std::cerr << "Cannot create relocated output map dir: '" << parent.str() + << "': " << ec.message() << "\n"; + return std::nullopt; + } + + llvm::raw_fd_ostream fd(newMapPath, ec, llvm::sys::fs::OF_None); + newOutputMap.write(fd, keys); + return newMapPath; +} + +// This is an Xcode-specific workaround to produce alias names for an existing .swiftmodule file. +// In the case of Xcode, it calls the Swift compiler and asks it to produce a Swift module. +// Once it's done, Xcode moves the .swiftmodule file in another location, and the location is +// rather arbitrary. Here are examples of such locations: +// Original file produced by the frontend: +// DerivedData//Build/Intermediates.noindex/.build/-/.build/Objects-normal//.swiftmodule +// where: +// Project: name of a project, target, or scheme +// BuildType: Debug, Release, etc. +// Target: macOS, iphoneos, appletvsimulator, etc. +// Arch: arm64, x86_64, etc. +// +// So far we observed that Xcode can move the module into different locations, and it's not +// entirely clear how to deduce the destination from the context available for the extractor. +// 1. First case: +// DerivedData//Build/Products/-/.swiftmodule/.swiftmodule +// DerivedData//Build/Products/-/.swiftmodule/.swiftmodule +// 2. Second case: +// DerivedData//Build/Products/-//.swiftmodule/.swiftmodule +// DerivedData//Build/Products/-//.swiftmodule/.swiftmodule +// 2. Third case: +// DerivedData//Build/Products/-//.framework/Modules/.swiftmodule/.swiftmodule +// DerivedData//Build/Products/-//.framework/Modules/.swiftmodule/.swiftmodule +// The here is a normalized target triple (e.g. arm64-apple-iphoneos15.4 -> +// arm64-apple-iphoneos). +// +// This method constructs those aliases for a module only if it comes from Xcode, which is detected +// by the presence of an `Intermediates.noindex` directory in the module path. +// +// In the case of the Swift Package Manager (`swift build`) this is not needed. +static std::vector computeModuleAliases(llvm::StringRef modulePath, + const std::string& targetTriple) { + if (modulePath.empty()) { + return {}; + } + if (!modulePath.endswith(".swiftmodule")) { + return {}; + } + // Deconstructing the Xcode generated path + // + // clang-format off + // intermediatesDirIndex destinationDir (2) arch(5) + // DerivedData/FooBar/Build/Intermediates.noindex/FooBar.build/Debug-iphonesimulator/FooBar.build/Objects-normal/x86_64/FooBar.swiftmodule + // clang-format on + llvm::SmallVector chunks; + modulePath.split(chunks, '/'); + size_t intermediatesDirIndex = 0; + for (size_t i = 0; i < chunks.size(); i++) { + if (chunks[i] == "Intermediates.noindex") { + intermediatesDirIndex = i; + break; + } + } + // Not built by Xcode, skipping + if (intermediatesDirIndex == 0) { + return {}; + } + size_t destinationDirIndex = intermediatesDirIndex + 2; + size_t archIndex = intermediatesDirIndex + 5; + if (archIndex >= chunks.size()) { + return {}; + } + // e.g. Debug-iphoneos, Release-iphonesimulator, etc. + auto destinationDir = chunks[destinationDirIndex].str(); + auto arch = chunks[archIndex].str(); + auto moduleNameWithExt = chunks.back(); + auto moduleName = moduleNameWithExt.substr(0, moduleNameWithExt.find_last_of('.')); + std::string relocatedModulePath = chunks[0].str(); + for (size_t i = 1; i < intermediatesDirIndex; i++) { + relocatedModulePath += '/' + chunks[i].str(); + } + relocatedModulePath += "/Products/"; + relocatedModulePath += destinationDir + '/'; + + // clang-format off + std::vector moduleLocations = { + // First case + relocatedModulePath + moduleNameWithExt.str() + '/', + // Second case + relocatedModulePath + moduleName.str() + '/' + moduleNameWithExt.str() + '/', + // Third case + relocatedModulePath + moduleName.str() + '/' + moduleName.str() + ".framework/Modules/" + moduleNameWithExt.str() + '/', + }; + // clang-format on + + std::vector archs({arch}); + if (!targetTriple.empty()) { + llvm::Triple triple(targetTriple); + archs.push_back(swift::getTargetSpecificModuleTriple(triple).normalize()); + } + + std::vector aliases; + for (auto& location : moduleLocations) { + for (auto& a : archs) { + aliases.push_back(location + a + ".swiftmodule"); + } + } + + return aliases; +} + +namespace codeql { + +std::unordered_map rewriteOutputsInPlace( + const SwiftExtractorConfiguration& config, + std::vector& CLIArgs) { + std::unordered_map remapping; + + // TODO: handle filelists? + const std::unordered_set pathRewriteOptions({ + "-emit-dependencies-path", + "-emit-module-path", + "-emit-module-doc-path", + "-emit-module-source-info-path", + "-emit-objc-header-path", + "-emit-reference-dependencies-path", + "-index-store-path", + "-module-cache-path", + "-o", + "-pch-output-dir", + "-serialize-diagnostics-path", + }); + + std::unordered_set outputFileMaps( + {"-supplementary-output-file-map", "-output-file-map"}); + + std::vector outputFileMapIndexes; + std::vector maybeInput; + std::string targetTriple; + + std::vector newLocations; + for (size_t i = 0; i < CLIArgs.size(); i++) { + if (pathRewriteOptions.count(CLIArgs[i])) { + auto oldPath = CLIArgs[i + 1]; + auto newPath = config.getTempArtifactDir() + '/' + oldPath; + CLIArgs[++i] = newPath; + newLocations.push_back(newPath); + + remapping[oldPath] = newPath; + } else if (outputFileMaps.count(CLIArgs[i])) { + // collect output map indexes for further rewriting and skip the following argument + // We don't patch the map in place as we need to collect all the input files first + outputFileMapIndexes.push_back(++i); + } else if (CLIArgs[i] == "-target") { + targetTriple = CLIArgs[++i]; + } else if (CLIArgs[i][0] != '-') { + // TODO: add support for input file lists? + // We need to collect input file names to later use them to extract information from the + // output file maps. + maybeInput.push_back(CLIArgs[i]); + } + } + + for (auto index : outputFileMapIndexes) { + auto oldPath = CLIArgs[index]; + auto maybeNewPath = rewriteOutputFileMap(config, oldPath, maybeInput, remapping); + if (maybeNewPath) { + auto newPath = maybeNewPath.value(); + CLIArgs[index] = newPath; + remapping[oldPath] = newPath; + } + } + + // This doesn't really belong here, but we've got Xcode... + for (const auto& [oldPath, newPath] : remapping) { + llvm::StringRef path(oldPath); + auto aliases = computeModuleAliases(path, targetTriple); + for (auto& alias : aliases) { + remapping[alias] = newPath; + } + } + + return remapping; +} + +void ensureDirectoriesForNewPathsExist( + const std::unordered_map& remapping) { + for (auto& [_, newPath] : remapping) { + llvm::SmallString filepath(newPath); + llvm::StringRef parent = llvm::sys::path::parent_path(filepath); + if (std::error_code ec = llvm::sys::fs::create_directories(parent)) { + std::cerr << "Cannot create redirected directory: " << ec.message() << "\n"; + } + } +} + +void storeRemappingForVFS(const SwiftExtractorConfiguration& config, + const std::unordered_map& remapping) { + // Only create remapping for the .swiftmodule files + std::unordered_map modules; + for (const auto& [oldPath, newPath] : remapping) { + if (llvm::StringRef(oldPath).endswith(".swiftmodule")) { + modules.emplace(oldPath, newPath); + } + } + + if (modules.empty()) { + return; + } + + if (std::error_code ec = llvm::sys::fs::create_directories(config.getTempVFSDir())) { + std::cerr << "Cannot create temp VFS directory: " << ec.message() << "\n"; + return; + } + + if (std::error_code ec = llvm::sys::fs::create_directories(config.getVFSDir())) { + std::cerr << "Cannot create VFS directory: " << ec.message() << "\n"; + return; + } + + // Constructing the VFS yaml file in a temp folder so that the other process doesn't read it + // while it is not complete + // TODO: Pick a more robust way to not collide with files from other processes + auto tempVfsPath = config.getTempVFSDir() + '/' + std::to_string(getpid()) + "-vfs.yaml"; + std::error_code ec; + llvm::raw_fd_ostream fd(tempVfsPath, ec, llvm::sys::fs::OF_None); + if (ec) { + std::cerr << "Cannot create temp VFS file: '" << tempVfsPath << "': " << ec.message() << "\n"; + return; + } + // TODO: there must be a better API than this + // LLVM expects the version to be 0 + fd << "{ version: 0,\n"; + // This tells the FS not to fallback to the physical file system in case the remapped file is not + // present + fd << " fallthrough: false,\n"; + fd << " roots: [\n"; + for (auto& [oldPath, newPath] : modules) { + fd << " {\n"; + fd << " type: 'file',\n"; + fd << " name: '" << oldPath << "\',\n"; + fd << " external-contents: '" << newPath << "\'\n"; + fd << " },\n"; + } + fd << " ]\n"; + fd << "}\n"; + + fd.flush(); + auto vfsPath = config.getVFSDir() + '/' + std::to_string(getpid()) + "-vfs.yaml"; + if (std::error_code ec = llvm::sys::fs::rename(tempVfsPath, vfsPath)) { + std::cerr << "Cannot move temp VFS file '" << tempVfsPath << "' -> '" << vfsPath + << "': " << ec.message() << "\n"; + return; + } +} + +std::vector collectVFSFiles(const SwiftExtractorConfiguration& config) { + auto vfsDir = config.getVFSDir() + '/'; + if (!llvm::sys::fs::exists(vfsDir)) { + return {}; + } + std::vector overlays; + std::error_code ec; + llvm::sys::fs::directory_iterator it(vfsDir, ec); + while (!ec && it != llvm::sys::fs::directory_iterator()) { + llvm::StringRef path(it->path()); + if (path.endswith("vfs.yaml")) { + overlays.push_back(path.str()); + } + it.increment(ec); + } + + return overlays; +} + +void lockOutputSwiftModuleTraps(const SwiftExtractorConfiguration& config, + const std::unordered_map& remapping) { + for (const auto& [oldPath, newPath] : remapping) { + if (llvm::StringRef(oldPath).endswith(".swiftmodule")) { + if (auto target = createTargetTrapFile(config, oldPath)) { + *target << "// trap file deliberately empty\n" + "// this swiftmodule was created during the build, so its entities must have" + " been extracted directly from source files"; + } + } + } +} + +} // namespace codeql diff --git a/swift/extractor/SwiftOutputRewrite.h b/swift/extractor/SwiftOutputRewrite.h new file mode 100644 index 00000000000..94f1eeb6aaa --- /dev/null +++ b/swift/extractor/SwiftOutputRewrite.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include + +namespace codeql { + +struct SwiftExtractorConfiguration; + +// Rewrites all the output CLI args to point to a scratch dir instead of the actual locations. +// This is needed to ensure that the artifacts produced by the extractor do not collide with the +// artifacts produced by the actual Swift compiler. +// Returns the map containing remapping oldpath -> newPath. +std::unordered_map rewriteOutputsInPlace( + const SwiftExtractorConfiguration& config, + std::vector& CLIArgs); + +// Create directories for all the redirected new paths as the Swift compiler expects them to exist. +void ensureDirectoriesForNewPathsExist( + const std::unordered_map& remapping); + +// Stores remapped `.swiftmoduile`s in a YAML file for later consumption by the +// llvm::RedirectingFileSystem via Swift's VFSOverlayFiles. +void storeRemappingForVFS(const SwiftExtractorConfiguration& config, + const std::unordered_map& remapping); + +// Returns a list of VFS YAML files produced by all the extractor processes. +// This is separate from storeRemappingForVFS as we also collect files produced by other processes. +std::vector collectVFSFiles(const SwiftExtractorConfiguration& config); + +// Creates empty trap files for output swiftmodule files +void lockOutputSwiftModuleTraps(const SwiftExtractorConfiguration& config, + const std::unordered_map& remapping); +} // namespace codeql diff --git a/swift/extractor/TargetTrapFile.cpp b/swift/extractor/TargetTrapFile.cpp new file mode 100644 index 00000000000..2275575ecfa --- /dev/null +++ b/swift/extractor/TargetTrapFile.cpp @@ -0,0 +1,23 @@ +#include "swift/extractor/TargetTrapFile.h" +#include +namespace codeql { +std::optional createTargetTrapFile(const SwiftExtractorConfiguration& configuration, + std::string_view target) { + std::string trap{target}; + trap += ".trap"; + auto ret = TargetFile::create(trap, configuration.trapDir, configuration.getTempTrapDir()); + if (ret) { + *ret << "/* extractor-args:\n"; + for (const auto& opt : configuration.frontendOptions) { + *ret << " " << std::quoted(opt) << " \\\n"; + } + *ret << "\n*/\n" + "/* swift-frontend-args:\n"; + for (const auto& opt : configuration.patchedFrontendOptions) { + *ret << " " << std::quoted(opt) << " \\\n"; + } + *ret << "\n*/\n"; + } + return ret; +} +} // namespace codeql diff --git a/swift/extractor/TargetTrapFile.h b/swift/extractor/TargetTrapFile.h new file mode 100644 index 00000000000..eb8de4c206f --- /dev/null +++ b/swift/extractor/TargetTrapFile.h @@ -0,0 +1,11 @@ +#pragma once + +#include "swift/extractor/infra/TargetFile.h" +#include "swift/extractor/SwiftExtractorConfiguration.h" + +namespace codeql { + +std::optional createTargetTrapFile(const SwiftExtractorConfiguration& configuration, + std::string_view target); + +} // namespace codeql diff --git a/swift/extractor/infra/BUILD.bazel b/swift/extractor/infra/BUILD.bazel index 33098eb76a4..115fb06b745 100644 --- a/swift/extractor/infra/BUILD.bazel +++ b/swift/extractor/infra/BUILD.bazel @@ -2,9 +2,11 @@ load("//swift:rules.bzl", "swift_cc_library") swift_cc_library( name = "infra", + srcs = glob(["*.cpp"]), hdrs = glob(["*.h"]), visibility = ["//swift:__subpackages__"], deps = [ "//swift/extractor/trap", + "//swift/tools/prebuilt:swift-llvm-support", ], ) diff --git a/swift/extractor/infra/FilePath.h b/swift/extractor/infra/FilePath.h new file mode 100644 index 00000000000..48288b928e4 --- /dev/null +++ b/swift/extractor/infra/FilePath.h @@ -0,0 +1,24 @@ +#pragma once + +#include +namespace codeql { + +// wrapper around `std::string` mainly intended to unambiguously go into an `std::variant` +// TODO probably not needed once we can use `std::filesystem::path` +struct FilePath { + FilePath() = default; + FilePath(const std::string& path) : path{path} {} + FilePath(std::string&& path) : path{std::move(path)} {} + + std::string path; + + bool operator==(const FilePath& other) const { return path == other.path; } +}; +} // namespace codeql + +namespace std { +template <> +struct hash { + size_t operator()(const codeql::FilePath& value) { return hash{}(value.path); } +}; +} // namespace std diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index e7aaa5af612..d564673c976 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -4,11 +4,11 @@ #include #include -#include "swift/extractor/trap/TrapArena.h" #include "swift/extractor/trap/TrapLabelStore.h" -#include "swift/extractor/trap/TrapOutput.h" +#include "swift/extractor/trap/TrapDomain.h" #include "swift/extractor/infra/SwiftTagTraits.h" #include "swift/extractor/trap/generated/TrapClasses.h" +#include "swift/extractor/infra/FilePath.h" namespace codeql { @@ -18,19 +18,41 @@ namespace codeql { // Since SwiftDispatcher sees all the AST nodes, it also attaches a location to every 'locatable' // node (AST nodes that are not types: declarations, statements, expressions, etc.). class SwiftDispatcher { + // types to be supported by assignNewLabel/fetchLabel need to be listed here + using Store = TrapLabelStore; + + template + static constexpr bool IsStorable = std::is_constructible_v; + + template + static constexpr bool IsLocatable = std::is_base_of_v>; + public: // all references and pointers passed as parameters to this constructor are supposed to outlive // the SwiftDispatcher SwiftDispatcher(const swift::SourceManager& sourceManager, - TrapArena& arena, - TrapOutput& trap, + TrapDomain& trap, swift::ModuleDecl& currentModule, swift::SourceFile* currentPrimarySourceFile = nullptr) : sourceManager{sourceManager}, - arena{arena}, trap{trap}, currentModule{currentModule}, - currentPrimarySourceFile{currentPrimarySourceFile} {} + currentPrimarySourceFile{currentPrimarySourceFile} { + if (currentPrimarySourceFile) { + // we make sure the file is in the trap output even if the source is empty + fetchLabel(getFilePath(currentPrimarySourceFile->getFilename())); + } + } template void emit(const Entry& entry) { @@ -64,9 +86,11 @@ class SwiftDispatcher { // This method gives a TRAP label for already emitted AST node. // If the AST node was not emitted yet, then the emission is dispatched to a corresponding // visitor (see `visit(T *)` methods below). - template - TrapLabelOf fetchLabel(E* e) { - assert(e && "trying to fetch a label on nullptr, maybe fetchOptionalLabel is to be used?"); + template >* = nullptr> + TrapLabelOf fetchLabel(const E& e, Args&&... args) { + if constexpr (std::is_constructible_v) { + assert(e && "fetching a label on a null entity, maybe fetchOptionalLabel is to be used?"); + } // this is required so we avoid any recursive loop: a `fetchLabel` during the visit of `e` might // end up calling `fetchLabel` on `e` itself, so we want the visit of `e` to call `fetchLabel` // only after having called `assignNewLabel` on `e`. @@ -76,9 +100,10 @@ class SwiftDispatcher { return *l; } waitingForNewLabel = e; - visit(e); + visit(e, std::forward(args)...); + // TODO when everything is moved to structured C++ classes, this should be moved to createEntry if (auto l = store.get(e)) { - if constexpr (!std::is_base_of_v) { + if constexpr (IsLocatable) { attachLocation(e, *l); } return *l; @@ -95,35 +120,41 @@ class SwiftDispatcher { return fetchLabelFromUnion(node); } + template >* = nullptr> + TrapLabelOf fetchLabel(const E& e) { + return fetchLabel(&e); + } + // Due to the lazy emission approach, we must assign a label to a corresponding AST node before // it actually gets emitted to handle recursive cases such as recursive calls, or recursive type // declarations - template - TrapLabelOf assignNewLabel(E* e, Args&&... args) { + template >* = nullptr> + TrapLabelOf assignNewLabel(const E& e, Args&&... args) { assert(waitingForNewLabel == Store::Handle{e} && "assignNewLabel called on wrong entity"); - auto label = createLabel>(std::forward(args)...); + auto label = trap.createLabel>(std::forward(args)...); store.insert(e, label); waitingForNewLabel = std::monostate{}; return label; } - template >* = nullptr> + template >* = nullptr> TrapLabelOf assignNewLabel(const E& e, Args&&... args) { return assignNewLabel(&e, std::forward(args)...); } - template - TrapLabel createLabel() { - auto ret = arena.allocateLabel(); - trap.assignStar(ret); - return ret; + // convenience methods for structured C++ creation + template + auto createEntry(const E& e, Args&&... args) { + return TrapClassOf{assignNewLabel(e, std::forward(args)...)}; } - template - TrapLabel createLabel(Args&&... args) { - auto ret = arena.allocateLabel(); - trap.assignKey(ret, std::forward(args)...); - return ret; + // used to create a new entry for entities that should not be cached + // an example is swift::Argument, that are created on the fly and thus have no stable pointer + template + auto createUncachedEntry(const E& e, Args&&... args) { + auto label = trap.createLabel>(std::forward(args)...); + attachLocation(&e, label); + return TrapClassOf{label}; } template @@ -137,6 +168,15 @@ class SwiftDispatcher { attachLocation(locatable->getStartLoc(), locatable->getEndLoc(), locatableLabel); } + void attachLocation(const swift::IfConfigClause* clause, TrapLabel locatableLabel) { + attachLocation(clause->Loc, clause->Loc, locatableLabel); + } + + // Emits a Location TRAP entry and attaches it to a `Locatable` trap label for a given `SourceLoc` + void attachLocation(swift::SourceLoc loc, TrapLabel locatableLabel) { + attachLocation(loc, loc, locatableLabel); + } + // Emits a Location TRAP entry for a list of swift entities and attaches it to a `Locatable` trap // label template @@ -152,10 +192,10 @@ class SwiftDispatcher { // return `std::optional(fetchLabel(arg))` if arg converts to true, otherwise std::nullopt // universal reference `Arg&&` is used to catch both temporary and non-const references, not // for perfect forwarding - template - auto fetchOptionalLabel(Arg&& arg) -> std::optional { + template + auto fetchOptionalLabel(Arg&& arg, Args&&... args) -> std::optional { if (arg) { - return fetchLabel(arg); + return fetchLabel(arg, std::forward(args)...); } return std::nullopt; } @@ -173,6 +213,11 @@ class SwiftDispatcher { return ret; } + template + void emitDebugInfo(const Args&... args) { + trap.debug(args...); + } + // In order to not emit duplicated entries for declarations, we restrict emission to only // Decls declared within the current "scope". // Depending on the whether we are extracting a primary source file or not the scope is defined as @@ -186,7 +231,9 @@ class SwiftDispatcher { if (decl.getModuleContext() != ¤tModule) { return false; } - if (!currentPrimarySourceFile) { + // ModuleDecl is a special case: if it passed the previous test, it is the current module + // but it never has a source file, so we short circuit to emit it in any case + if (!currentPrimarySourceFile || decl.getKind() == swift::DeclKind::Module) { return true; } if (auto context = decl.getDeclContext()) { @@ -196,16 +243,6 @@ class SwiftDispatcher { } private: - // types to be supported by assignNewLabel/fetchLabel need to be listed here - using Store = TrapLabelStore; - void attachLocation(swift::SourceLoc start, swift::SourceLoc end, TrapLabel locatableLabel) { @@ -213,16 +250,16 @@ class SwiftDispatcher { // invalid locations seem to come from entities synthesized by the compiler return; } - std::string filepath = getFilepath(start); - auto fileLabel = createLabel(filepath); - // TODO: do not emit duplicate trap entries for Files - trap.emit(FilesTrap{fileLabel, filepath}); - auto [startLine, startColumn] = sourceManager.getLineAndColumnInBuffer(start); - auto [endLine, endColumn] = sourceManager.getLineAndColumnInBuffer(end); - auto locLabel = createLabel('{', fileLabel, "}:", startLine, ':', startColumn, ':', - endLine, ':', endColumn); - trap.emit(LocationsTrap{locLabel, fileLabel, startLine, startColumn, endLine, endColumn}); - trap.emit(LocatableLocationsTrap{locatableLabel, locLabel}); + auto file = getFilePath(sourceManager.getDisplayNameForLoc(start)); + Location entry{{}}; + entry.file = fetchLabel(file); + std::tie(entry.start_line, entry.start_column) = sourceManager.getLineAndColumnInBuffer(start); + std::tie(entry.end_line, entry.end_column) = sourceManager.getLineAndColumnInBuffer(end); + entry.id = trap.createLabel('{', entry.file, "}:", entry.start_line, ':', + entry.start_column, ':', entry.end_line, ':', + entry.end_column); + emit(entry); + emit(LocatableLocationsTrap{locatableLabel, entry.id}); } template @@ -238,40 +275,53 @@ class SwiftDispatcher { template bool fetchLabelFromUnionCase(const llvm::PointerUnion u, TrapLabel& output) { - if (auto e = u.template dyn_cast()) { - output = fetchLabel(e); - return true; + // we rely on the fact that when we extract `ASTNode` instances (which only happens + // on `BraceStmt` elements), we cannot encounter a standalone `TypeRepr` there, so we skip + // this case; extracting `TypeRepr`s here would be problematic as we would not be able to + // provide the corresponding type + if constexpr (!std::is_same_v) { + if (auto e = u.template dyn_cast()) { + output = fetchLabel(e); + return true; + } } return false; } - std::string getFilepath(swift::SourceLoc loc) { + static FilePath getFilePath(llvm::StringRef path) { // TODO: this needs more testing // TODO: check canonicaliztion of names on a case insensitive filesystems // TODO: make symlink resolution conditional on CODEQL_PRESERVE_SYMLINKS=true - auto displayName = sourceManager.getDisplayNameForLoc(loc); llvm::SmallString realPath; - if (std::error_code ec = llvm::sys::fs::real_path(displayName, realPath)) { - std::cerr << "Cannot get real path: '" << displayName.str() << "': " << ec.message() << "\n"; + if (std::error_code ec = llvm::sys::fs::real_path(path, realPath)) { + std::cerr << "Cannot get real path: '" << path.str() << "': " << ec.message() << "\n"; return {}; } return realPath.str().str(); } - // TODO: The following methods are supposed to redirect TRAP emission to correpsonding visitors, - // which are to be introduced in follow-up PRs + // TODO: for const correctness these should consistently be `const` (and maybe const references + // as we don't expect `nullptr` here. However `swift::ASTVisitor` and `swift::TypeVisitor` do not + // accept const pointers virtual void visit(swift::Decl* decl) = 0; + virtual void visit(const swift::IfConfigClause* clause) = 0; virtual void visit(swift::Stmt* stmt) = 0; - virtual void visit(swift::StmtCondition* cond) = 0; + virtual void visit(const swift::StmtCondition* cond) = 0; + virtual void visit(const swift::StmtConditionElement* cond) = 0; virtual void visit(swift::CaseLabelItem* item) = 0; virtual void visit(swift::Expr* expr) = 0; virtual void visit(swift::Pattern* pattern) = 0; - virtual void visit(swift::TypeRepr* type) = 0; + virtual void visit(swift::TypeRepr* typeRepr, swift::Type type) = 0; virtual void visit(swift::TypeBase* type) = 0; + void visit(const FilePath& file) { + auto entry = createEntry(file, file.path); + entry.name = file.path; + emit(entry); + } + const swift::SourceManager& sourceManager; - TrapArena& arena; - TrapOutput& trap; + TrapDomain& trap; Store store; Store::Handle waitingForNewLabel{std::monostate{}}; swift::ModuleDecl& currentModule; diff --git a/swift/extractor/infra/SwiftTagTraits.h b/swift/extractor/infra/SwiftTagTraits.h index 8a2e489683d..a03cf038111 100644 --- a/swift/extractor/infra/SwiftTagTraits.h +++ b/swift/extractor/infra/SwiftTagTraits.h @@ -5,6 +5,7 @@ #include #include "swift/extractor/trap/TrapTagTraits.h" #include "swift/extractor/trap/generated/TrapTags.h" +#include "swift/extractor/infra/FilePath.h" namespace codeql { @@ -14,14 +15,13 @@ using SILBlockStorageTypeTag = SilBlockStorageTypeTag; using SILBoxTypeTag = SilBoxTypeTag; using SILFunctionTypeTag = SilFunctionTypeTag; using SILTokenTypeTag = SilTokenTypeTag; -using SILBoxTypeReprTag = SilBoxTypeReprTag; -#define MAP_TYPE_TO_TAG(TYPE, TAG) \ - template <> \ - struct detail::ToTagFunctor { \ - using type = TAG; \ +#define MAP_TYPE_TO_TAG(TYPE, TAG) \ + template <> \ + struct detail::ToTagFunctor { \ + using type = TAG; \ } -#define MAP_TAG(TYPE) MAP_TYPE_TO_TAG(TYPE, TYPE##Tag) +#define MAP_TAG(TYPE) MAP_TYPE_TO_TAG(swift::TYPE, TYPE##Tag) #define MAP_SUBTAG(TYPE, PARENT) \ MAP_TAG(TYPE); \ static_assert(std::is_base_of_v, \ @@ -36,17 +36,20 @@ using SILBoxTypeReprTag = SilBoxTypeReprTag; MAP_TAG(Stmt); MAP_TAG(StmtCondition); +MAP_TYPE_TO_TAG(swift::StmtConditionElement, ConditionElementTag); MAP_TAG(CaseLabelItem); #define ABSTRACT_STMT(CLASS, PARENT) MAP_SUBTAG(CLASS##Stmt, PARENT) #define STMT(CLASS, PARENT) ABSTRACT_STMT(CLASS, PARENT) #include MAP_TAG(Expr); +MAP_TAG(Argument); #define ABSTRACT_EXPR(CLASS, PARENT) MAP_SUBTAG(CLASS##Expr, PARENT) #define EXPR(CLASS, PARENT) ABSTRACT_EXPR(CLASS, PARENT) #include MAP_TAG(Decl); +MAP_TAG(IfConfigClause); #define ABSTRACT_DECL(CLASS, PARENT) MAP_SUBTAG(CLASS##Decl, PARENT) #define DECL(CLASS, PARENT) ABSTRACT_DECL(CLASS, PARENT) #include @@ -57,11 +60,8 @@ MAP_TAG(Pattern); #include MAP_TAG(TypeRepr); -#define ABSTRACT_TYPEREPR(CLASS, PARENT) MAP_SUBTAG(CLASS##TypeRepr, PARENT) -#define TYPEREPR(CLASS, PARENT) ABSTRACT_TYPEREPR(CLASS, PARENT) -#include -MAP_TYPE_TO_TAG(TypeBase, TypeTag); +MAP_TYPE_TO_TAG(swift::TypeBase, TypeTag); #define ABSTRACT_TYPE(CLASS, PARENT) MAP_SUBTAG(CLASS##Type, PARENT) #define TYPE(CLASS, PARENT) ABSTRACT_TYPE(CLASS, PARENT) #include @@ -69,6 +69,8 @@ MAP_TYPE_TO_TAG(TypeBase, TypeTag); OVERRIDE_TAG(FuncDecl, ConcreteFuncDeclTag); OVERRIDE_TAG(VarDecl, ConcreteVarDeclTag); +MAP_TYPE_TO_TAG(FilePath, FileTag); + #undef MAP_TAG #undef MAP_SUBTAG #undef MAP_TYPE_TO_TAG diff --git a/swift/extractor/infra/TargetFile.cpp b/swift/extractor/infra/TargetFile.cpp new file mode 100644 index 00000000000..d9706205c90 --- /dev/null +++ b/swift/extractor/infra/TargetFile.cpp @@ -0,0 +1,85 @@ +#include "swift/extractor/infra/TargetFile.h" + +#include +#include +#include +#include + +#include +#include + +namespace codeql { +namespace { +[[noreturn]] void error(const char* action, const std::string& arg, std::error_code ec) { + std::cerr << "Unable to " << action << ": " << arg << " (" << ec.message() << ")\n"; + std::abort(); +} + +[[noreturn]] void error(const char* action, const std::string& arg) { + error(action, arg, {errno, std::system_category()}); +} + +void ensureParentDir(const std::string& path) { + auto parent = llvm::sys::path::parent_path(path); + if (auto ec = llvm::sys::fs::create_directories(parent)) { + error("create directory", parent.str(), ec); + } +} + +std::string initPath(std::string_view target, std::string_view dir) { + std::string ret{dir}; + assert(!target.empty() && "target must be a non-empty path"); + if (target[0] != '/') { + ret += '/'; + } + ret.append(target); + ensureParentDir(ret); + return ret; +} +} // namespace + +TargetFile::TargetFile(std::string_view target, + std::string_view targetDir, + std::string_view workingDir) + : workingPath{initPath(target, workingDir)}, targetPath{initPath(target, targetDir)} {} + +bool TargetFile::init() { + errno = 0; + // since C++17 "x" mode opens with O_EXCL (fails if file already exists) + if (auto f = std::fopen(targetPath.c_str(), "wx")) { + std::fclose(f); + out.open(workingPath); + checkOutput("open file for writing"); + return true; + } + if (errno != EEXIST) { + error("open file for writing", targetPath); + } + // else we just lost the race + return false; +} + +std::optional TargetFile::create(std::string_view target, + std::string_view targetDir, + std::string_view workingDir) { + TargetFile ret{target, targetDir, workingDir}; + if (ret.init()) return ret; + return std::nullopt; +} + +void TargetFile::commit() { + if (out.is_open()) { + out.close(); + errno = 0; + if (std::rename(workingPath.c_str(), targetPath.c_str()) != 0) { + error("rename file", targetPath); + } + } +} + +void TargetFile::checkOutput(const char* action) { + if (!out) { + error(action, workingPath); + } +} +} // namespace codeql diff --git a/swift/extractor/infra/TargetFile.h b/swift/extractor/infra/TargetFile.h new file mode 100644 index 00000000000..5f5ca7d823c --- /dev/null +++ b/swift/extractor/infra/TargetFile.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include +#include + +namespace codeql { + +// Only the first process trying to create a `TargetFile` for a given `target` is allowed to do +// so, all others will have `create` return `std::nullopt`. +// The content streamed to the `TargetFile` is written to `workingDir/target`, and is moved onto +// `targetDir/target` on destruction. +class TargetFile { + std::string workingPath; + std::string targetPath; + std::ofstream out; + + public: + static std::optional create(std::string_view target, + std::string_view targetDir, + std::string_view workingDir); + + ~TargetFile() { commit(); } + + TargetFile(TargetFile&& other) = default; + // move assignment deleted as non-trivial and not needed + TargetFile& operator=(TargetFile&& other) = delete; + + template + TargetFile& operator<<(T&& value) { + errno = 0; + out << value; + checkOutput("write to file"); + return *this; + } + + private: + TargetFile(std::string_view target, std::string_view targetDir, std::string_view workingDir); + + bool init(); + void checkOutput(const char* action); + void commit(); +}; + +} // namespace codeql diff --git a/swift/extractor/main.cpp b/swift/extractor/main.cpp index 547225d6cd9..5f9afef4e81 100644 --- a/swift/extractor/main.cpp +++ b/swift/extractor/main.cpp @@ -1,27 +1,32 @@ #include #include #include +#include +#include +#include +#include #include #include #include "SwiftExtractor.h" +#include "SwiftOutputRewrite.h" using namespace std::string_literals; // This is part of the swiftFrontendTool interface, we hook into the // compilation pipeline and extract files after the Swift frontend performed -// semantic analysys +// semantic analysis class Observer : public swift::FrontendObserver { public: explicit Observer(const codeql::SwiftExtractorConfiguration& config) : config{config} {} void parsedArgs(swift::CompilerInvocation& invocation) override { - // Original compiler and the extractor-compiler get into conflicts when - // both produce the same output files. - // TODO: change the final artifact destinations instead of disabling - // the artifact generation completely? - invocation.getFrontendOptions().RequestedAction = swift::FrontendOptions::ActionType::Typecheck; + auto& overlays = invocation.getSearchPathOptions().VFSOverlayFiles; + auto vfsFiles = codeql::collectVFSFiles(config); + for (auto& vfsFile : vfsFiles) { + overlays.push_back(vfsFile); + } } void performedSemanticAnalysis(swift::CompilerInstance& compiler) override { @@ -51,11 +56,25 @@ int main(int argc, char** argv) { codeql::SwiftExtractorConfiguration configuration{}; configuration.trapDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_TRAP_DIR", "."); configuration.sourceArchiveDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_SOURCE_ARCHIVE_DIR", "."); - std::vector args; + configuration.scratchDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_SCRATCH_DIR", "."); + + configuration.frontendOptions.reserve(argc - 1); for (int i = 1; i < argc; i++) { - args.push_back(argv[i]); + configuration.frontendOptions.push_back(argv[i]); } - std::copy(std::begin(args), std::end(args), std::back_inserter(configuration.frontendOptions)); + configuration.patchedFrontendOptions = configuration.frontendOptions; + + auto remapping = + codeql::rewriteOutputsInPlace(configuration, configuration.patchedFrontendOptions); + codeql::ensureDirectoriesForNewPathsExist(remapping); + codeql::storeRemappingForVFS(configuration, remapping); + codeql::lockOutputSwiftModuleTraps(configuration, remapping); + + std::vector args; + for (auto& arg : configuration.patchedFrontendOptions) { + args.push_back(arg.c_str()); + } + Observer observer(configuration); int frontend_rc = swift::performFrontend(args, "swift-extractor", (void*)main, &observer); return frontend_rc; diff --git a/swift/extractor/trap/BUILD.bazel b/swift/extractor/trap/BUILD.bazel index b1860142866..08875c45263 100644 --- a/swift/extractor/trap/BUILD.bazel +++ b/swift/extractor/trap/BUILD.bazel @@ -1,6 +1,6 @@ load("//swift:rules.bzl", "swift_cc_library") -_dirs = ("", "decl/", "expr/", "pattern/", "stmt/", "type/", "typerepr/") +_dirs = ("", "decl/", "expr/", "pattern/", "stmt/", "type/") genrule( name = "cppgen", diff --git a/swift/extractor/trap/TrapArena.h b/swift/extractor/trap/TrapArena.h deleted file mode 100644 index 99d0b4a5d3b..00000000000 --- a/swift/extractor/trap/TrapArena.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "swift/extractor/trap/TrapLabel.h" - -namespace codeql { - -// TrapArena has the responsibilities to allocate distinct trap #-labels -// TODO this is now a small functionality that will be moved to code upcoming from other PRs -class TrapArena { - uint64_t id_{0}; - - public: - template - TrapLabel allocateLabel() { - return TrapLabel::unsafeCreateFromExplicitId(id_++); - } -}; - -} // namespace codeql diff --git a/swift/extractor/trap/TrapOutput.h b/swift/extractor/trap/TrapDomain.h similarity index 56% rename from swift/extractor/trap/TrapOutput.h rename to swift/extractor/trap/TrapDomain.h index b9104b9118a..c84a3910134 100644 --- a/swift/extractor/trap/TrapOutput.h +++ b/swift/extractor/trap/TrapDomain.h @@ -1,19 +1,58 @@ #pragma once #include +#include + #include "swift/extractor/trap/TrapLabel.h" +#include "swift/extractor/infra/TargetFile.h" namespace codeql { -// Sink for trap emissions and label assignments. This abstracts away `ofstream` operations -// like `ofstream`, an explicit bool operator is provided, that return false if something -// went wrong -// TODO better error handling -class TrapOutput { - std::ostream& out_; +// Abstracts a given trap output file, with its own universe of trap labels +class TrapDomain { + TargetFile& out_; public: - explicit TrapOutput(std::ostream& out) : out_{out} {} + explicit TrapDomain(TargetFile& out) : out_{out} {} + + template + void emit(const Entry& e) { + print(e); + } + + template + void debug(const Args&... args) { + print("/* DEBUG:"); + print(args...); + print("*/"); + } + + template + TrapLabel createLabel() { + auto ret = allocateLabel(); + assignStar(ret); + return ret; + } + + template + TrapLabel createLabel(Args&&... args) { + auto ret = allocateLabel(); + assignKey(ret, std::forward(args)...); + return ret; + } + + private: + uint64_t id_{0}; + + template + TrapLabel allocateLabel() { + return TrapLabel::unsafeCreateFromExplicitId(id_++); + } + + template + void print(const Args&... args) { + (out_ << ... << args) << '\n'; + } template void assignStar(TrapLabel label) { @@ -33,23 +72,6 @@ class TrapOutput { (oss << ... << keyParts); assignKey(label, oss.str()); } - - template - void emit(const Entry& e) { - print(e); - } - - template - void debug(const Args&... args) { - out_ << "// DEBUG: "; - (out_ << ... << args) << '\n'; - } - - private: - template - void print(const Args&... args) { - (out_ << ... << args) << '\n'; - } }; } // namespace codeql diff --git a/swift/extractor/trap/TrapLabelStore.h b/swift/extractor/trap/TrapLabelStore.h index 93ca4212185..f9b0edd1753 100644 --- a/swift/extractor/trap/TrapLabelStore.h +++ b/swift/extractor/trap/TrapLabelStore.h @@ -20,10 +20,10 @@ namespace codeql { template class TrapLabelStore { public: - using Handle = std::variant; + using Handle = std::variant; template - std::optional> get(const T* e) { + std::optional> get(const T& e) { if (auto found = store_.find(e); found != store_.end()) { return TrapLabelOf::unsafeCreateFromUntyped(found->second); } @@ -31,7 +31,7 @@ class TrapLabelStore { } template - void insert(const T* e, TrapLabelOf l) { + void insert(const T& e, TrapLabelOf l) { auto [_, inserted] = store_.emplace(e, l); assert(inserted && "already inserted"); } diff --git a/swift/extractor/trap/TrapTagTraits.h b/swift/extractor/trap/TrapTagTraits.h index 9c29ff22330..f0f8c41cc8d 100644 --- a/swift/extractor/trap/TrapTagTraits.h +++ b/swift/extractor/trap/TrapTagTraits.h @@ -26,7 +26,8 @@ struct ToTrapClassFunctor; } // namespace detail template -using TrapTagOf = typename detail::ToTagOverride>::type; +using TrapTagOf = + typename detail::ToTagOverride>>::type; template using TrapLabelOf = TrapLabel>; diff --git a/swift/extractor/visitors/DeclVisitor.cpp b/swift/extractor/visitors/DeclVisitor.cpp index ed47f1e5fb1..fce28e504dd 100644 --- a/swift/extractor/visitors/DeclVisitor.cpp +++ b/swift/extractor/visitors/DeclVisitor.cpp @@ -83,11 +83,13 @@ codeql::PrecedenceGroupDecl DeclVisitor::translatePrecedenceGroupDecl( return entry; } -codeql::ParamDecl DeclVisitor::translateParamDecl(const swift::ParamDecl& decl) { - // TODO: deduplicate - ParamDecl entry{dispatcher_.assignNewLabel(decl)}; - fillVarDecl(decl, entry); - entry.is_inout = decl.isInOut(); +std::optional DeclVisitor::translateParamDecl(const swift::ParamDecl& decl) { + auto entry = createNamedEntry(decl); + if (!entry) { + return std::nullopt; + } + fillVarDecl(decl, *entry); + entry->is_inout = decl.isInOut(); return entry; } @@ -111,11 +113,20 @@ codeql::PatternBindingDecl DeclVisitor::translatePatternBindingDecl( return entry; } -codeql::ConcreteVarDecl DeclVisitor::translateVarDecl(const swift::VarDecl& decl) { - // TODO: deduplicate all non-local variables - ConcreteVarDecl entry{dispatcher_.assignNewLabel(decl)}; - entry.introducer_int = static_cast(decl.getIntroducer()); - fillVarDecl(decl, entry); +std::optional DeclVisitor::translateVarDecl(const swift::VarDecl& decl) { + std::optional entry; + // We do not deduplicate variables from non-swift (PCM, clang modules) modules as the mangler + // crashes sometimes + if (decl.getDeclContext()->isLocalContext() || decl.getModuleContext()->isNonSwiftModule()) { + entry.emplace(dispatcher_.assignNewLabel(decl)); + } else { + entry = createNamedEntry(decl); + if (!entry) { + return std::nullopt; + } + } + entry->introducer_int = static_cast(decl.getIntroducer()); + fillVarDecl(decl, *entry); return entry; } @@ -241,16 +252,15 @@ std::variant DeclVisitor::trans std::optional DeclVisitor::translateSubscriptDecl( const swift::SubscriptDecl& decl) { - auto id = dispatcher_.assignNewLabel(decl, mangledName(decl)); - if (!dispatcher_.shouldEmitDeclBody(decl)) { + auto entry = createNamedEntry(decl); + if (!entry) { return std::nullopt; } - SubscriptDecl entry{id}; - entry.element_type = dispatcher_.fetchLabel(decl.getElementInterfaceType()); + entry->element_type = dispatcher_.fetchLabel(decl.getElementInterfaceType()); if (auto indices = decl.getIndices()) { - entry.params = dispatcher_.fetchRepeatedLabels(*indices); + entry->params = dispatcher_.fetchRepeatedLabels(*indices); } - fillAbstractStorageDecl(decl, entry); + fillAbstractStorageDecl(decl, *entry); return entry; } @@ -262,9 +272,53 @@ codeql::ExtensionDecl DeclVisitor::translateExtensionDecl(const swift::Extension return entry; } +codeql::ImportDecl DeclVisitor::translateImportDecl(const swift::ImportDecl& decl) { + auto entry = dispatcher_.createEntry(decl); + entry.is_exported = decl.isExported(); + entry.module = dispatcher_.fetchLabel(decl.getModule()); + entry.declarations = dispatcher_.fetchRepeatedLabels(decl.getDecls()); + return entry; +} + +std::optional DeclVisitor::translateModuleDecl(const swift::ModuleDecl& decl) { + auto entry = createNamedEntry(decl); + if (!entry) { + return std::nullopt; + } + entry->is_builtin_module = decl.isBuiltinModule(); + entry->is_system_module = decl.isSystemModule(); + fillTypeDecl(decl, *entry); + return entry; +} + std::string DeclVisitor::mangledName(const swift::ValueDecl& decl) { - // prefix adds a couple of special symbols, we don't necessary need them - return mangler.mangleAnyDecl(&decl, /* prefix = */ false); + // ASTMangler::mangleAnyDecl crashes when called on `ModuleDecl` + // TODO find a more unique string working also when different modules are compiled with the same + // name + std::ostringstream ret; + if (decl.getKind() == swift::DeclKind::Module) { + ret << static_cast(decl).getRealName().str().str(); + } else if (decl.getKind() == swift::DeclKind::TypeAlias) { + // In cases like this (when coming from PCM) + // typealias CFXMLTree = CFTree + // typealias CFXMLTreeRef = CFXMLTree + // mangleAnyDecl mangles both CFXMLTree and CFXMLTreeRef into 'So12CFXMLTreeRefa' + // which is not correct and causes inconsistencies. mangleEntity makes these two distinct + // prefix adds a couple of special symbols, we don't necessary need them + ret << mangler.mangleEntity(&decl); + } else { + // prefix adds a couple of special symbols, we don't necessary need them + ret << mangler.mangleAnyDecl(&decl, /* prefix = */ false); + } + // there can be separate declarations (`VarDecl` or `AccessorDecl`) which are effectively the same + // (with equal mangled name) but come from different clang modules. This is the case for example + // for glibc constants like `L_SET` that appear in both `SwiftGlibc` and `CDispatch`. + // For the moment, we sidestep the problem by making them separate entities in the DB + // TODO find a more solid solution + if (decl.getModuleContext()->isNonSwiftModule()) { + ret << '_' << decl.getModuleContext()->getRealName().str().str(); + } + return ret.str(); } void DeclVisitor::fillAbstractFunctionDecl(const swift::AbstractFunctionDecl& decl, @@ -334,4 +388,18 @@ void DeclVisitor::fillAbstractStorageDecl(const swift::AbstractStorageDecl& decl fillValueDecl(decl, entry); } +codeql::IfConfigDecl DeclVisitor::translateIfConfigDecl(const swift::IfConfigDecl& decl) { + auto entry = dispatcher_.createEntry(decl); + entry.clauses = dispatcher_.fetchRepeatedLabels(decl.getClauses()); + return entry; +} + +codeql::IfConfigClause DeclVisitor::translateIfConfigClause(const swift::IfConfigClause& clause) { + auto entry = dispatcher_.createEntry(clause); + entry.condition = dispatcher_.fetchOptionalLabel(clause.Cond); + entry.elements = dispatcher_.fetchRepeatedLabels(clause.Elements); + entry.is_active = clause.isActive; + return entry; +} + } // namespace codeql diff --git a/swift/extractor/visitors/DeclVisitor.h b/swift/extractor/visitors/DeclVisitor.h index 0527513d859..85e819adb5b 100644 --- a/swift/extractor/visitors/DeclVisitor.h +++ b/swift/extractor/visitors/DeclVisitor.h @@ -14,6 +14,11 @@ namespace codeql { class DeclVisitor : public AstVisitorBase { public: using AstVisitorBase::AstVisitorBase; + using AstVisitorBase::visit; + + void visit(const swift::IfConfigClause* clause) { + dispatcher_.emit(translateIfConfigClause(*clause)); + } std::variant translateFuncDecl( const swift::FuncDecl& decl); @@ -25,10 +30,10 @@ class DeclVisitor : public AstVisitorBase { codeql::PostfixOperatorDecl translatePostfixOperatorDecl(const swift::PostfixOperatorDecl& decl); codeql::InfixOperatorDecl translateInfixOperatorDecl(const swift::InfixOperatorDecl& decl); codeql::PrecedenceGroupDecl translatePrecedenceGroupDecl(const swift::PrecedenceGroupDecl& decl); - codeql::ParamDecl translateParamDecl(const swift::ParamDecl& decl); + std::optional translateParamDecl(const swift::ParamDecl& decl); codeql::TopLevelCodeDecl translateTopLevelCodeDecl(const swift::TopLevelCodeDecl& decl); codeql::PatternBindingDecl translatePatternBindingDecl(const swift::PatternBindingDecl& decl); - codeql::ConcreteVarDecl translateVarDecl(const swift::VarDecl& decl); + std::optional translateVarDecl(const swift::VarDecl& decl); std::variant translateStructDecl( const swift::StructDecl& decl); std::variant translateClassDecl( @@ -50,6 +55,10 @@ class DeclVisitor : public AstVisitorBase { const swift::AccessorDecl& decl); std::optional translateSubscriptDecl(const swift::SubscriptDecl& decl); codeql::ExtensionDecl translateExtensionDecl(const swift::ExtensionDecl& decl); + codeql::ImportDecl translateImportDecl(const swift::ImportDecl& decl); + std::optional translateModuleDecl(const swift::ModuleDecl& decl); + codeql::IfConfigDecl translateIfConfigDecl(const swift::IfConfigDecl& decl); + codeql::IfConfigClause translateIfConfigClause(const swift::IfConfigClause& clause); private: std::string mangledName(const swift::ValueDecl& decl); @@ -66,6 +75,15 @@ class DeclVisitor : public AstVisitorBase { void fillAbstractStorageDecl(const swift::AbstractStorageDecl& decl, codeql::AbstractStorageDecl& entry); + template + std::optional> createNamedEntry(const D& decl) { + auto id = dispatcher_.assignNewLabel(decl, mangledName(decl)); + if (dispatcher_.shouldEmitDeclBody(decl)) { + return TrapClassOf{id}; + } + return std::nullopt; + } + private: swift::Mangle::ASTMangler mangler; }; diff --git a/swift/extractor/visitors/ExprVisitor.cpp b/swift/extractor/visitors/ExprVisitor.cpp index e6aabef4cea..a4bc1639811 100644 --- a/swift/extractor/visitors/ExprVisitor.cpp +++ b/swift/extractor/visitors/ExprVisitor.cpp @@ -188,9 +188,8 @@ void ExprVisitor::visitEnumIsCaseExpr(swift::EnumIsCaseExpr* expr) { assert(expr->getCaseTypeRepr() && "EnumIsCaseExpr has CaseTypeRepr"); assert(expr->getEnumElement() && "EnumIsCaseExpr has EnumElement"); auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr()); - auto typeRepr = dispatcher_.fetchLabel(expr->getCaseTypeRepr()); auto enumElement = dispatcher_.fetchLabel(expr->getEnumElement()); - dispatcher_.emit(EnumIsCaseExprsTrap{label, subExpr, typeRepr, enumElement}); + dispatcher_.emit(EnumIsCaseExprsTrap{label, subExpr, enumElement}); } void ExprVisitor::visitMakeTemporarilyEscapableExpr(swift::MakeTemporarilyEscapableExpr* expr) { @@ -288,7 +287,9 @@ void ExprVisitor::visitErasureExpr(swift::ErasureExpr* expr) { codeql::TypeExpr ExprVisitor::translateTypeExpr(const swift::TypeExpr& expr) { TypeExpr entry{dispatcher_.assignNewLabel(expr)}; - entry.type_repr = dispatcher_.fetchOptionalLabel(expr.getTypeRepr()); + if (expr.getTypeRepr() && expr.getInstanceType()) { + entry.type_repr = dispatcher_.fetchLabel(expr.getTypeRepr(), expr.getInstanceType()); + } return entry; } @@ -478,9 +479,14 @@ void ExprVisitor::visitKeyPathExpr(swift::KeyPathExpr* expr) { auto pathLabel = dispatcher_.fetchLabel(path); dispatcher_.emit(KeyPathExprParsedPathsTrap{label, pathLabel}); } - if (auto root = expr->getParsedRoot()) { - auto rootLabel = dispatcher_.fetchLabel(root); - dispatcher_.emit(KeyPathExprParsedRootsTrap{label, rootLabel}); + // TODO maybe move this logic to QL? + if (auto rootTypeRepr = expr->getRootType()) { + auto keyPathType = expr->getType()->getAs(); + assert(keyPathType && "KeyPathExpr must have BoundGenericClassType"); + auto keyPathTypeArgs = keyPathType->getGenericArgs(); + assert(keyPathTypeArgs.size() != 0 && "KeyPathExpr type must have generic args"); + auto rootLabel = dispatcher_.fetchLabel(rootTypeRepr, keyPathTypeArgs[0]); + dispatcher_.emit(KeyPathExprRootsTrap{label, rootLabel}); } } } @@ -611,11 +617,11 @@ void ExprVisitor::fillAbstractClosureExpr(const swift::AbstractClosureExpr& expr } TrapLabel ExprVisitor::emitArgument(const swift::Argument& arg) { - auto argLabel = dispatcher_.createLabel(); - assert(arg.getExpr() && "Argument has getExpr"); - dispatcher_.emit( - ArgumentsTrap{argLabel, arg.getLabel().str().str(), dispatcher_.fetchLabel(arg.getExpr())}); - return argLabel; + auto entry = dispatcher_.createUncachedEntry(arg); + entry.label = arg.getLabel().str().str(); + entry.expr = dispatcher_.fetchLabel(arg.getExpr()); + dispatcher_.emit(entry); + return entry.id; } void ExprVisitor::emitImplicitConversionExpr(swift::ImplicitConversionExpr* expr, @@ -668,4 +674,10 @@ void ExprVisitor::emitLookupExpr(const swift::LookupExpr* expr, TrapLabel { codeql::BridgeFromObjCExpr translateBridgeFromObjCExpr(const swift::BridgeFromObjCExpr& expr); codeql::DotSelfExpr translateDotSelfExpr(const swift::DotSelfExpr& expr); codeql::ErrorExpr translateErrorExpr(const swift::ErrorExpr& expr); + // The following function requires a non-const parameter because: + // * `swift::UnresolvedPatternExpr::getSubPattern` has a `const`-qualified overload returning + // `const swift::Pattern*` + // * `swift::ASTVisitor` only visits non-const pointers + // either we accept this, or we fix constness, e.g. by providing `visit` on `const` pointers + // in `VisitorBase`, or by doing a `const_cast` in `SwifDispatcher::fetchLabel` + codeql::UnresolvedPatternExpr translateUnresolvedPatternExpr(swift::UnresolvedPatternExpr& expr); private: void fillAbstractClosureExpr(const swift::AbstractClosureExpr& expr, diff --git a/swift/extractor/visitors/PatternVisitor.cpp b/swift/extractor/visitors/PatternVisitor.cpp index 43421fcbede..4ef90aa56a4 100644 --- a/swift/extractor/visitors/PatternVisitor.cpp +++ b/swift/extractor/visitors/PatternVisitor.cpp @@ -18,8 +18,8 @@ void PatternVisitor::visitTypedPattern(swift::TypedPattern* pattern) { assert(pattern->getSubPattern() && "expect TypedPattern to have a SubPattern"); dispatcher_.emit(TypedPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())}); if (auto typeRepr = pattern->getTypeRepr()) { - dispatcher_.emit( - TypedPatternTypeReprsTrap{label, dispatcher_.fetchLabel(pattern->getTypeRepr())}); + dispatcher_.emit(TypedPatternTypeReprsTrap{ + label, dispatcher_.fetchLabel(pattern->getTypeRepr(), pattern->getType())}); } } @@ -63,7 +63,8 @@ void PatternVisitor::visitIsPattern(swift::IsPattern* pattern) { dispatcher_.emit(IsPatternsTrap{label}); if (auto typeRepr = pattern->getCastTypeRepr()) { - dispatcher_.emit(IsPatternCastTypeReprsTrap{label, dispatcher_.fetchLabel(typeRepr)}); + dispatcher_.emit(IsPatternCastTypeReprsTrap{ + label, dispatcher_.fetchLabel(typeRepr, pattern->getCastType())}); } if (auto subPattern = pattern->getSubPattern()) { dispatcher_.emit(IsPatternSubPatternsTrap{label, dispatcher_.fetchLabel(subPattern)}); diff --git a/swift/extractor/visitors/StmtVisitor.cpp b/swift/extractor/visitors/StmtVisitor.cpp index 21f93828ed7..bc8a8a30933 100644 --- a/swift/extractor/visitors/StmtVisitor.cpp +++ b/swift/extractor/visitors/StmtVisitor.cpp @@ -7,26 +7,22 @@ void StmtVisitor::visitLabeledStmt(swift::LabeledStmt* stmt) { emitLabeledStmt(stmt, label); } -void StmtVisitor::visitStmtCondition(swift::StmtCondition* cond) { - auto label = dispatcher_.assignNewLabel(cond); - dispatcher_.emit(StmtConditionsTrap{label}); - unsigned index = 0; - for (const auto& cond : *cond) { - auto condLabel = dispatcher_.createLabel(); - dispatcher_.attachLocation(cond, condLabel); - dispatcher_.emit(ConditionElementsTrap{condLabel}); - dispatcher_.emit(StmtConditionElementsTrap{label, index++, condLabel}); - if (auto boolean = cond.getBooleanOrNull()) { - auto elementLabel = dispatcher_.fetchLabel(boolean); - dispatcher_.emit(ConditionElementBooleansTrap{condLabel, elementLabel}); - } else if (auto pattern = cond.getPatternOrNull()) { - auto patternLabel = dispatcher_.fetchLabel(pattern); - auto initilizerLabel = dispatcher_.fetchLabel(cond.getInitializer()); - dispatcher_.emit(ConditionElementPatternsTrap{condLabel, patternLabel}); - dispatcher_.emit(ConditionElementInitializersTrap{condLabel, initilizerLabel}); - } - /// TODO: Implement availability +codeql::StmtCondition StmtVisitor::translateStmtCondition(const swift::StmtCondition& cond) { + auto entry = dispatcher_.createEntry(cond); + entry.elements = dispatcher_.fetchRepeatedLabels(cond); + return entry; +} + +codeql::ConditionElement StmtVisitor::translateStmtConditionElement( + const swift::StmtConditionElement& element) { + auto entry = dispatcher_.createEntry(element); + if (auto boolean = element.getBooleanOrNull()) { + entry.boolean = dispatcher_.fetchLabel(boolean); + } else if (auto pattern = element.getPatternOrNull()) { + entry.pattern = dispatcher_.fetchLabel(pattern); + entry.initializer = dispatcher_.fetchLabel(element.getInitializer()); } + return entry; } void StmtVisitor::visitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt) { diff --git a/swift/extractor/visitors/StmtVisitor.h b/swift/extractor/visitors/StmtVisitor.h index 78273366d9e..e929a364399 100644 --- a/swift/extractor/visitors/StmtVisitor.h +++ b/swift/extractor/visitors/StmtVisitor.h @@ -10,7 +10,9 @@ class StmtVisitor : public AstVisitorBase { using AstVisitorBase::AstVisitorBase; void visitLabeledStmt(swift::LabeledStmt* stmt); - void visitStmtCondition(swift::StmtCondition* cond); + codeql::StmtCondition translateStmtCondition(const swift::StmtCondition& cond); + codeql::ConditionElement translateStmtConditionElement( + const swift::StmtConditionElement& element); void visitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt); void visitCaseLabelItem(swift::CaseLabelItem* labelItem); void visitBraceStmt(swift::BraceStmt* stmt); diff --git a/swift/extractor/visitors/SwiftVisitor.h b/swift/extractor/visitors/SwiftVisitor.h index 6380390af82..965aa7975f3 100644 --- a/swift/extractor/visitors/SwiftVisitor.h +++ b/swift/extractor/visitors/SwiftVisitor.h @@ -5,7 +5,6 @@ #include "swift/extractor/visitors/ExprVisitor.h" #include "swift/extractor/visitors/StmtVisitor.h" #include "swift/extractor/visitors/TypeVisitor.h" -#include "swift/extractor/visitors/TypeReprVisitor.h" #include "swift/extractor/visitors/PatternVisitor.h" namespace codeql { @@ -15,24 +14,31 @@ class SwiftVisitor : private SwiftDispatcher { using SwiftDispatcher::SwiftDispatcher; template - void extract(T* entity) { + void extract(const T& entity) { fetchLabel(entity); } private: void visit(swift::Decl* decl) override { declVisitor.visit(decl); } + void visit(const swift::IfConfigClause* clause) override { declVisitor.visit(clause); } void visit(swift::Stmt* stmt) override { stmtVisitor.visit(stmt); } - void visit(swift::StmtCondition* cond) override { stmtVisitor.visitStmtCondition(cond); } + void visit(const swift::StmtCondition* cond) override { + emit(stmtVisitor.translateStmtCondition(*cond)); + } + void visit(const swift::StmtConditionElement* element) override { + emit(stmtVisitor.translateStmtConditionElement(*element)); + } void visit(swift::CaseLabelItem* item) override { stmtVisitor.visitCaseLabelItem(item); } void visit(swift::Expr* expr) override { exprVisitor.visit(expr); } void visit(swift::Pattern* pattern) override { patternVisitor.visit(pattern); } - void visit(swift::TypeRepr* type) override { typeReprVisitor.visit(type); } void visit(swift::TypeBase* type) override { typeVisitor.visit(type); } + void visit(swift::TypeRepr* typeRepr, swift::Type type) override { + emit(typeVisitor.translateTypeRepr(*typeRepr, type)); + } DeclVisitor declVisitor{*this}; ExprVisitor exprVisitor{*this}; StmtVisitor stmtVisitor{*this}; - TypeReprVisitor typeReprVisitor{*this}; TypeVisitor typeVisitor{*this}; PatternVisitor patternVisitor{*this}; }; diff --git a/swift/extractor/visitors/TypeReprVisitor.cpp b/swift/extractor/visitors/TypeReprVisitor.cpp deleted file mode 100644 index a3daa7938bb..00000000000 --- a/swift/extractor/visitors/TypeReprVisitor.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "swift/extractor/visitors/TypeReprVisitor.h" - -namespace codeql {} // namespace codeql diff --git a/swift/extractor/visitors/TypeReprVisitor.h b/swift/extractor/visitors/TypeReprVisitor.h deleted file mode 100644 index dba2198cc6c..00000000000 --- a/swift/extractor/visitors/TypeReprVisitor.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "swift/extractor/visitors/VisitorBase.h" -#include "swift/extractor/trap/generated/typerepr/TrapClasses.h" - -namespace codeql { - -class TypeReprVisitor : public AstVisitorBase { - public: - using AstVisitorBase::AstVisitorBase; -}; - -} // namespace codeql diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index 897cc58625e..d1c499a9a96 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -1,4 +1,5 @@ #include "swift/extractor/visitors/TypeVisitor.h" + namespace codeql { void TypeVisitor::visit(swift::TypeBase* type) { TypeVisitorBase::visit(type); @@ -8,6 +9,12 @@ void TypeVisitor::visit(swift::TypeBase* type) { dispatcher_.emit(TypesTrap{label, type->getString(), canonicalLabel}); } +codeql::TypeRepr TypeVisitor::translateTypeRepr(const swift::TypeRepr& typeRepr, swift::Type type) { + auto entry = dispatcher_.createEntry(typeRepr); + entry.type = dispatcher_.fetchOptionalLabel(type); + return entry; +} + void TypeVisitor::visitProtocolType(swift::ProtocolType* type) { auto label = dispatcher_.assignNewLabel(type); dispatcher_.emit(ProtocolTypesTrap{label}); @@ -122,13 +129,13 @@ void TypeVisitor::visitParenType(swift::ParenType* type) { } codeql::OptionalType TypeVisitor::translateOptionalType(const swift::OptionalType& type) { - codeql::OptionalType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createTypeEntry(type); fillUnarySyntaxSugarType(type, entry); return entry; } codeql::ArraySliceType TypeVisitor::translateArraySliceType(const swift::ArraySliceType& type) { - codeql::ArraySliceType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createTypeEntry(type); fillUnarySyntaxSugarType(type, entry); return entry; } @@ -152,7 +159,7 @@ void TypeVisitor::visitGenericFunctionType(swift::GenericFunctionType* type) { void TypeVisitor::visitGenericTypeParamType(swift::GenericTypeParamType* type) { auto label = dispatcher_.assignNewLabel(type); - dispatcher_.emit(GenericTypeParamTypesTrap{label, type->getName().str().str()}); + dispatcher_.emit(GenericTypeParamTypesTrap{label}); } void TypeVisitor::visitLValueType(swift::LValueType* type) { @@ -163,7 +170,7 @@ void TypeVisitor::visitLValueType(swift::LValueType* type) { codeql::PrimaryArchetypeType TypeVisitor::translatePrimaryArchetypeType( const swift::PrimaryArchetypeType& type) { - PrimaryArchetypeType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createTypeEntry(type); fillArchetypeType(type, entry); return entry; } @@ -183,7 +190,6 @@ void TypeVisitor::fillUnarySyntaxSugarType(const swift::UnarySyntaxSugarType& ty codeql::UnarySyntaxSugarType& entry) { assert(type.getBaseType() && "expect UnarySyntaxSugarType to have BaseType"); entry.base_type = dispatcher_.fetchLabel(type.getBaseType()); - fillType(type, entry); } void TypeVisitor::emitAnyFunctionType(const swift::AnyFunctionType* type, @@ -230,7 +236,7 @@ void TypeVisitor::emitAnyGenericType(swift::AnyGenericType* type, codeql::NestedArchetypeType TypeVisitor::translateNestedArchetypeType( const swift::NestedArchetypeType& type) { - codeql::NestedArchetypeType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createTypeEntry(type); entry.parent = dispatcher_.fetchLabel(type.getParent()); entry.associated_type_declaration = dispatcher_.fetchLabel(type.getAssocType()); fillArchetypeType(type, entry); @@ -238,43 +244,38 @@ codeql::NestedArchetypeType TypeVisitor::translateNestedArchetypeType( } void TypeVisitor::fillType(const swift::TypeBase& type, codeql::Type& entry) { - entry.diagnostics_name = type.getString(); + entry.name = type.getString(); entry.canonical_type = dispatcher_.fetchLabel(type.getCanonicalType()); } void TypeVisitor::fillArchetypeType(const swift::ArchetypeType& type, ArchetypeType& entry) { entry.interface_type = dispatcher_.fetchLabel(type.getInterfaceType()); - entry.name = type.getName().str().str(); entry.protocols = dispatcher_.fetchRepeatedLabels(type.getConformsTo()); entry.superclass = dispatcher_.fetchOptionalLabel(type.getSuperclass()); - fillType(type, entry); } codeql::ExistentialType TypeVisitor::translateExistentialType(const swift::ExistentialType& type) { - codeql::ExistentialType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createTypeEntry(type); entry.constraint = dispatcher_.fetchLabel(type.getConstraintType()); - fillType(type, entry); return entry; } codeql::DynamicSelfType TypeVisitor::translateDynamicSelfType(const swift::DynamicSelfType& type) { - codeql::DynamicSelfType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createTypeEntry(type); entry.static_self_type = dispatcher_.fetchLabel(type.getSelfType()); - fillType(type, entry); return entry; } codeql::VariadicSequenceType TypeVisitor::translateVariadicSequenceType( const swift::VariadicSequenceType& type) { - codeql::VariadicSequenceType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createTypeEntry(type); fillUnarySyntaxSugarType(type, entry); return entry; } codeql::InOutType TypeVisitor::translateInOutType(const swift::InOutType& type) { - codeql::InOutType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createTypeEntry(type); entry.object_type = dispatcher_.fetchLabel(type.getObjectType()); - fillType(type, entry); return entry; } @@ -304,4 +305,90 @@ void TypeVisitor::fillReferenceStorageType(const swift::ReferenceStorageType& ty fillType(type, entry); } +codeql::ProtocolCompositionType TypeVisitor::translateProtocolCompositionType( + const swift::ProtocolCompositionType& type) { + auto entry = createTypeEntry(type); + entry.members = dispatcher_.fetchRepeatedLabels(type.getMembers()); + return entry; +} + +codeql::BuiltinIntegerLiteralType TypeVisitor::translateBuiltinIntegerLiteralType( + const swift::BuiltinIntegerLiteralType& type) { + return createTypeEntry(type); +} + +codeql::BuiltinIntegerType TypeVisitor::translateBuiltinIntegerType( + const swift::BuiltinIntegerType& type) { + auto entry = createTypeEntry(type); + if (type.isFixedWidth()) { + entry.width = type.getFixedWidth(); + } + return entry; +} + +codeql::BuiltinBridgeObjectType TypeVisitor::translateBuiltinBridgeObjectType( + const swift::BuiltinBridgeObjectType& type) { + return createTypeEntry(type); +} + +codeql::BuiltinDefaultActorStorageType TypeVisitor::translateBuiltinDefaultActorStorageType( + const swift::BuiltinDefaultActorStorageType& type) { + return createTypeEntry(type); +} + +codeql::BuiltinExecutorType TypeVisitor::translateBuiltinExecutorType( + const swift::BuiltinExecutorType& type) { + return createTypeEntry(type); +} + +codeql::BuiltinFloatType TypeVisitor::translateBuiltinFloatType( + const swift::BuiltinFloatType& type) { + return createTypeEntry(type); +} + +codeql::BuiltinJobType TypeVisitor::translateBuiltinJobType(const swift::BuiltinJobType& type) { + return createTypeEntry(type); +} + +codeql::BuiltinNativeObjectType TypeVisitor::translateBuiltinNativeObjectType( + const swift::BuiltinNativeObjectType& type) { + return createTypeEntry(type); +} + +codeql::BuiltinRawPointerType TypeVisitor::translateBuiltinRawPointerType( + const swift::BuiltinRawPointerType& type) { + return createTypeEntry(type); +} + +codeql::BuiltinRawUnsafeContinuationType TypeVisitor::translateBuiltinRawUnsafeContinuationType( + const swift::BuiltinRawUnsafeContinuationType& type) { + return createTypeEntry(type); +} + +codeql::BuiltinUnsafeValueBufferType TypeVisitor::translateBuiltinUnsafeValueBufferType( + const swift::BuiltinUnsafeValueBufferType& type) { + return createTypeEntry(type); +} + +codeql::BuiltinVectorType TypeVisitor::translateBuiltinVectorType( + const swift::BuiltinVectorType& type) { + return createTypeEntry(type); +} + +codeql::OpenedArchetypeType TypeVisitor::translateOpenedArchetypeType( + const swift::OpenedArchetypeType& type) { + auto entry = createTypeEntry(type); + fillArchetypeType(type, entry); + return entry; +} + +codeql::ModuleType TypeVisitor::translateModuleType(const swift::ModuleType& type) { + auto key = type.getModule()->getRealName().str().str(); + if (type.getModule()->isNonSwiftModule()) { + key += "|clang"; + } + auto entry = createTypeEntry(type, key); + entry.module = dispatcher_.fetchLabel(type.getModule()); + return entry; +} } // namespace codeql diff --git a/swift/extractor/visitors/TypeVisitor.h b/swift/extractor/visitors/TypeVisitor.h index fa8c0d0ed09..21cbd96d24d 100644 --- a/swift/extractor/visitors/TypeVisitor.h +++ b/swift/extractor/visitors/TypeVisitor.h @@ -9,6 +9,8 @@ class TypeVisitor : public TypeVisitorBase { using TypeVisitorBase::TypeVisitorBase; void visit(swift::TypeBase* type); + codeql::TypeRepr translateTypeRepr(const swift::TypeRepr& typeRepr, swift::Type type); + void visitProtocolType(swift::ProtocolType* type); void visitEnumType(swift::EnumType* type); void visitStructType(swift::StructType* type); @@ -47,6 +49,29 @@ class TypeVisitor : public TypeVisitorBase { const swift::UnmanagedStorageType& type); codeql::WeakStorageType translateWeakStorageType(const swift::WeakStorageType& type); codeql::UnownedStorageType translateUnownedStorageType(const swift::UnownedStorageType& type); + codeql::ProtocolCompositionType translateProtocolCompositionType( + const swift::ProtocolCompositionType& type); + codeql::BuiltinIntegerLiteralType translateBuiltinIntegerLiteralType( + const swift::BuiltinIntegerLiteralType& type); + codeql::BuiltinIntegerType translateBuiltinIntegerType(const swift::BuiltinIntegerType& type); + codeql::BuiltinBridgeObjectType translateBuiltinBridgeObjectType( + const swift::BuiltinBridgeObjectType& type); + codeql::BuiltinDefaultActorStorageType translateBuiltinDefaultActorStorageType( + const swift::BuiltinDefaultActorStorageType& type); + codeql::BuiltinExecutorType translateBuiltinExecutorType(const swift::BuiltinExecutorType& type); + codeql::BuiltinFloatType translateBuiltinFloatType(const swift::BuiltinFloatType& type); + codeql::BuiltinJobType translateBuiltinJobType(const swift::BuiltinJobType& type); + codeql::BuiltinNativeObjectType translateBuiltinNativeObjectType( + const swift::BuiltinNativeObjectType& type); + codeql::BuiltinRawPointerType translateBuiltinRawPointerType( + const swift::BuiltinRawPointerType& type); + codeql::BuiltinRawUnsafeContinuationType translateBuiltinRawUnsafeContinuationType( + const swift::BuiltinRawUnsafeContinuationType& type); + codeql::BuiltinUnsafeValueBufferType translateBuiltinUnsafeValueBufferType( + const swift::BuiltinUnsafeValueBufferType& type); + codeql::BuiltinVectorType translateBuiltinVectorType(const swift::BuiltinVectorType& type); + codeql::OpenedArchetypeType translateOpenedArchetypeType(const swift::OpenedArchetypeType& type); + codeql::ModuleType translateModuleType(const swift::ModuleType& type); private: void fillType(const swift::TypeBase& type, codeql::Type& entry); @@ -58,6 +83,13 @@ class TypeVisitor : public TypeVisitorBase { void emitAnyFunctionType(const swift::AnyFunctionType* type, TrapLabel label); void emitBoundGenericType(swift::BoundGenericType* type, TrapLabel label); void emitAnyGenericType(swift::AnyGenericType* type, TrapLabel label); + + template + auto createTypeEntry(const T& type, const Args&... args) { + auto entry = dispatcher_.createEntry(type, args...); + fillType(type, entry); + return entry; + } }; } // namespace codeql diff --git a/swift/extractor/visitors/VisitorBase.h b/swift/extractor/visitors/VisitorBase.h index 8402e8924af..b835492d00d 100644 --- a/swift/extractor/visitors/VisitorBase.h +++ b/swift/extractor/visitors/VisitorBase.h @@ -29,7 +29,7 @@ class VisitorBase { public: \ void visit##CLASS##KIND(swift::CLASS##KIND* e) { \ using TranslateResult = std::invoke_result_t; \ + CrtpSubclass, swift::CLASS##KIND&>; \ constexpr bool hasTranslateImplementation = !std::is_same_v; \ if constexpr (hasTranslateImplementation) { \ dispatcher_.emit(static_cast(this)->translate##CLASS##KIND(*e)); \ diff --git a/swift/integration-tests/.gitignore b/swift/integration-tests/.gitignore index 8e66c817556..9ea4244ad91 100644 --- a/swift/integration-tests/.gitignore +++ b/swift/integration-tests/.gitignore @@ -6,3 +6,4 @@ xcuserdata/ DerivedData/ .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata *.actual +db diff --git a/swift/integration-tests/create_database_utils.py b/swift/integration-tests/create_database_utils.py new file mode 100644 index 00000000000..38822fd70b4 --- /dev/null +++ b/swift/integration-tests/create_database_utils.py @@ -0,0 +1,26 @@ +""" +recreation of internal `create_database_utils.py` to run the tests locally, with minimal +and swift-specialized functionality +""" +import subprocess +import pathlib +import sys + + +def run_codeql_database_create(cmds, lang, keep_trap=True): + assert lang == 'swift' + codeql_root = pathlib.Path(__file__).parents[2] + cmd = [ + "codeql", "database", "create", + "-s", ".", "-l", "swift", "--internal-use-lua-tracing", f"--search-path={codeql_root}", "--no-cleanup", + ] + if keep_trap: + cmd.append("--keep-trap") + for c in cmds: + cmd += ["-c", c] + cmd.append("db") + res = subprocess.run(cmd) + if res.returncode: + print("FAILED", file=sys.stderr) + print(" ", *cmd, file=sys.stderr) + sys.exit(res.returncode) diff --git a/swift/integration-tests/cross-references/Functions.expected b/swift/integration-tests/cross-references/Functions.expected deleted file mode 100644 index 76335112240..00000000000 --- a/swift/integration-tests/cross-references/Functions.expected +++ /dev/null @@ -1,4 +0,0 @@ -| Sources/cross-references/lib.swift:1:1:1:11 | f | -| Sources/cross-references/lib.swift:17:8:19:1 | ~ | -| Sources/cross-references/lib.swift:22:9:24:1 | ~ | -| Sources/cross-references/lib.swift:27:1:29:1 | ~ | diff --git a/swift/integration-tests/frontend-invocations/D.swift b/swift/integration-tests/osx-only/frontend-invocations/A.swift similarity index 100% rename from swift/integration-tests/frontend-invocations/D.swift rename to swift/integration-tests/osx-only/frontend-invocations/A.swift diff --git a/swift/integration-tests/frontend-invocations/E.swift b/swift/integration-tests/osx-only/frontend-invocations/B.swift similarity index 100% rename from swift/integration-tests/frontend-invocations/E.swift rename to swift/integration-tests/osx-only/frontend-invocations/B.swift diff --git a/swift/integration-tests/frontend-invocations/Esup.swift b/swift/integration-tests/osx-only/frontend-invocations/C.swift similarity index 100% rename from swift/integration-tests/frontend-invocations/Esup.swift rename to swift/integration-tests/osx-only/frontend-invocations/C.swift diff --git a/swift/ql/test/extractor-tests/generated/File/hello.swift b/swift/integration-tests/osx-only/frontend-invocations/D.swift similarity index 100% rename from swift/ql/test/extractor-tests/generated/File/hello.swift rename to swift/integration-tests/osx-only/frontend-invocations/D.swift diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.expected b/swift/integration-tests/osx-only/frontend-invocations/E.swift similarity index 100% rename from swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.expected rename to swift/integration-tests/osx-only/frontend-invocations/E.swift diff --git a/swift/integration-tests/osx-only/frontend-invocations/Esup.swift b/swift/integration-tests/osx-only/frontend-invocations/Esup.swift new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/integration-tests/frontend-invocations/Files.expected b/swift/integration-tests/osx-only/frontend-invocations/Files.expected similarity index 100% rename from swift/integration-tests/frontend-invocations/Files.expected rename to swift/integration-tests/osx-only/frontend-invocations/Files.expected diff --git a/swift/integration-tests/frontend-invocations/Files.ql b/swift/integration-tests/osx-only/frontend-invocations/Files.ql similarity index 100% rename from swift/integration-tests/frontend-invocations/Files.ql rename to swift/integration-tests/osx-only/frontend-invocations/Files.ql diff --git a/swift/integration-tests/frontend-invocations/Makefile b/swift/integration-tests/osx-only/frontend-invocations/Makefile similarity index 100% rename from swift/integration-tests/frontend-invocations/Makefile rename to swift/integration-tests/osx-only/frontend-invocations/Makefile diff --git a/swift/integration-tests/frontend-invocations/test.py b/swift/integration-tests/osx-only/frontend-invocations/test.py similarity index 100% rename from swift/integration-tests/frontend-invocations/test.py rename to swift/integration-tests/osx-only/frontend-invocations/test.py diff --git a/swift/integration-tests/cross-references/Classes.expected b/swift/integration-tests/posix-only/cross-references/Classes.expected similarity index 100% rename from swift/integration-tests/cross-references/Classes.expected rename to swift/integration-tests/posix-only/cross-references/Classes.expected diff --git a/swift/integration-tests/cross-references/Classes.ql b/swift/integration-tests/posix-only/cross-references/Classes.ql similarity index 100% rename from swift/integration-tests/cross-references/Classes.ql rename to swift/integration-tests/posix-only/cross-references/Classes.ql diff --git a/swift/integration-tests/cross-references/Constructors.expected b/swift/integration-tests/posix-only/cross-references/Constructors.expected similarity index 100% rename from swift/integration-tests/cross-references/Constructors.expected rename to swift/integration-tests/posix-only/cross-references/Constructors.expected diff --git a/swift/integration-tests/cross-references/Constructors.ql b/swift/integration-tests/posix-only/cross-references/Constructors.ql similarity index 100% rename from swift/integration-tests/cross-references/Constructors.ql rename to swift/integration-tests/posix-only/cross-references/Constructors.ql diff --git a/swift/integration-tests/cross-references/Destructors.expected b/swift/integration-tests/posix-only/cross-references/Destructors.expected similarity index 100% rename from swift/integration-tests/cross-references/Destructors.expected rename to swift/integration-tests/posix-only/cross-references/Destructors.expected diff --git a/swift/integration-tests/cross-references/Destructors.ql b/swift/integration-tests/posix-only/cross-references/Destructors.ql similarity index 100% rename from swift/integration-tests/cross-references/Destructors.ql rename to swift/integration-tests/posix-only/cross-references/Destructors.ql diff --git a/swift/integration-tests/cross-references/Enums.expected b/swift/integration-tests/posix-only/cross-references/Enums.expected similarity index 100% rename from swift/integration-tests/cross-references/Enums.expected rename to swift/integration-tests/posix-only/cross-references/Enums.expected diff --git a/swift/integration-tests/cross-references/Enums.ql b/swift/integration-tests/posix-only/cross-references/Enums.ql similarity index 100% rename from swift/integration-tests/cross-references/Enums.ql rename to swift/integration-tests/posix-only/cross-references/Enums.ql diff --git a/swift/integration-tests/posix-only/cross-references/Functions.expected b/swift/integration-tests/posix-only/cross-references/Functions.expected new file mode 100644 index 00000000000..2ecf78a6be4 --- /dev/null +++ b/swift/integration-tests/posix-only/cross-references/Functions.expected @@ -0,0 +1,4 @@ +| Sources/cross-references/lib.swift:1:1:1:11 | f() | +| Sources/cross-references/lib.swift:17:8:19:1 | ~(_:) | +| Sources/cross-references/lib.swift:22:9:24:1 | ~(_:) | +| Sources/cross-references/lib.swift:27:1:29:1 | ~(_:_:) | diff --git a/swift/integration-tests/cross-references/Functions.ql b/swift/integration-tests/posix-only/cross-references/Functions.ql similarity index 100% rename from swift/integration-tests/cross-references/Functions.ql rename to swift/integration-tests/posix-only/cross-references/Functions.ql diff --git a/swift/integration-tests/cross-references/Operators.expected b/swift/integration-tests/posix-only/cross-references/Operators.expected similarity index 100% rename from swift/integration-tests/cross-references/Operators.expected rename to swift/integration-tests/posix-only/cross-references/Operators.expected diff --git a/swift/integration-tests/cross-references/Operators.ql b/swift/integration-tests/posix-only/cross-references/Operators.ql similarity index 100% rename from swift/integration-tests/cross-references/Operators.ql rename to swift/integration-tests/posix-only/cross-references/Operators.ql diff --git a/swift/integration-tests/cross-references/Package.swift b/swift/integration-tests/posix-only/cross-references/Package.swift similarity index 100% rename from swift/integration-tests/cross-references/Package.swift rename to swift/integration-tests/posix-only/cross-references/Package.swift diff --git a/swift/integration-tests/cross-references/Protocols.expected b/swift/integration-tests/posix-only/cross-references/Protocols.expected similarity index 100% rename from swift/integration-tests/cross-references/Protocols.expected rename to swift/integration-tests/posix-only/cross-references/Protocols.expected diff --git a/swift/integration-tests/cross-references/Protocols.ql b/swift/integration-tests/posix-only/cross-references/Protocols.ql similarity index 100% rename from swift/integration-tests/cross-references/Protocols.ql rename to swift/integration-tests/posix-only/cross-references/Protocols.ql diff --git a/swift/integration-tests/cross-references/Sources/cross-references/lib.swift b/swift/integration-tests/posix-only/cross-references/Sources/cross-references/lib.swift similarity index 99% rename from swift/integration-tests/cross-references/Sources/cross-references/lib.swift rename to swift/integration-tests/posix-only/cross-references/Sources/cross-references/lib.swift index 39acad28b14..1155935d326 100644 --- a/swift/integration-tests/cross-references/Sources/cross-references/lib.swift +++ b/swift/integration-tests/posix-only/cross-references/Sources/cross-references/lib.swift @@ -27,4 +27,3 @@ infix operator ~ func ~(lhs: Int, rhs: Int) -> Int { return lhs } - diff --git a/swift/integration-tests/cross-references/Sources/cross-references/main.swift b/swift/integration-tests/posix-only/cross-references/Sources/cross-references/main.swift similarity index 98% rename from swift/integration-tests/cross-references/Sources/cross-references/main.swift rename to swift/integration-tests/posix-only/cross-references/Sources/cross-references/main.swift index b4143493c41..474d885af58 100644 --- a/swift/integration-tests/cross-references/Sources/cross-references/main.swift +++ b/swift/integration-tests/posix-only/cross-references/Sources/cross-references/main.swift @@ -15,4 +15,3 @@ struct s : P {} 42~ 15 ~ 42 - diff --git a/swift/integration-tests/cross-references/Structs.expected b/swift/integration-tests/posix-only/cross-references/Structs.expected similarity index 100% rename from swift/integration-tests/cross-references/Structs.expected rename to swift/integration-tests/posix-only/cross-references/Structs.expected diff --git a/swift/integration-tests/cross-references/Structs.ql b/swift/integration-tests/posix-only/cross-references/Structs.ql similarity index 100% rename from swift/integration-tests/cross-references/Structs.ql rename to swift/integration-tests/posix-only/cross-references/Structs.ql diff --git a/swift/integration-tests/cross-references/VarDecls.expected b/swift/integration-tests/posix-only/cross-references/VarDecls.expected similarity index 83% rename from swift/integration-tests/cross-references/VarDecls.expected rename to swift/integration-tests/posix-only/cross-references/VarDecls.expected index 104271d5384..6fab086e7dd 100644 --- a/swift/integration-tests/cross-references/VarDecls.expected +++ b/swift/integration-tests/posix-only/cross-references/VarDecls.expected @@ -1,5 +1,4 @@ | Sources/cross-references/lib.swift:10:5:10:5 | X | -| Sources/cross-references/lib.swift:10:5:10:5 | X | | Sources/cross-references/lib.swift:17:16:17:19 | v | | Sources/cross-references/lib.swift:22:16:22:19 | v | | Sources/cross-references/lib.swift:27:8:27:13 | lhs | diff --git a/swift/integration-tests/cross-references/VarDecls.ql b/swift/integration-tests/posix-only/cross-references/VarDecls.ql similarity index 100% rename from swift/integration-tests/cross-references/VarDecls.ql rename to swift/integration-tests/posix-only/cross-references/VarDecls.ql diff --git a/swift/integration-tests/cross-references/test.py b/swift/integration-tests/posix-only/cross-references/test.py similarity index 100% rename from swift/integration-tests/cross-references/test.py rename to swift/integration-tests/posix-only/cross-references/test.py diff --git a/swift/integration-tests/hello-world/Package.swift b/swift/integration-tests/posix-only/hello-world/Package.swift similarity index 100% rename from swift/integration-tests/hello-world/Package.swift rename to swift/integration-tests/posix-only/hello-world/Package.swift diff --git a/swift/integration-tests/hello-world/Sources/hello-world/hello_world.swift b/swift/integration-tests/posix-only/hello-world/Sources/hello-world/hello_world.swift similarity index 100% rename from swift/integration-tests/hello-world/Sources/hello-world/hello_world.swift rename to swift/integration-tests/posix-only/hello-world/Sources/hello-world/hello_world.swift diff --git a/swift/integration-tests/hello-world/test.expected b/swift/integration-tests/posix-only/hello-world/test.expected similarity index 100% rename from swift/integration-tests/hello-world/test.expected rename to swift/integration-tests/posix-only/hello-world/test.expected diff --git a/swift/integration-tests/hello-world/test.py b/swift/integration-tests/posix-only/hello-world/test.py similarity index 100% rename from swift/integration-tests/hello-world/test.py rename to swift/integration-tests/posix-only/hello-world/test.py diff --git a/swift/integration-tests/hello-world/test.ql b/swift/integration-tests/posix-only/hello-world/test.ql similarity index 100% rename from swift/integration-tests/hello-world/test.ql rename to swift/integration-tests/posix-only/hello-world/test.ql diff --git a/swift/integration-tests/posix-only/partial-modules/A/Package.swift b/swift/integration-tests/posix-only/partial-modules/A/Package.swift new file mode 100644 index 00000000000..41bf0b6d70d --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/A/Package.swift @@ -0,0 +1,18 @@ +// swift-tools-version: 5.5 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "A", + products: [ + .library( + name: "A", + targets: ["A"]), + ], + targets: [ + .target( + name: "A", + dependencies: []), + ] +) diff --git a/swift/integration-tests/posix-only/partial-modules/A/Sources/A/A.swift b/swift/integration-tests/posix-only/partial-modules/A/Sources/A/A.swift new file mode 100644 index 00000000000..b8554b24b6c --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/A/Sources/A/A.swift @@ -0,0 +1,5 @@ +public struct A { + public private(set) var text = Atext + + public init() {} +} diff --git a/swift/integration-tests/posix-only/partial-modules/A/Sources/A/Asup.swift b/swift/integration-tests/posix-only/partial-modules/A/Sources/A/Asup.swift new file mode 100644 index 00000000000..a2af1709c3c --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/A/Sources/A/Asup.swift @@ -0,0 +1 @@ +let Atext = "Hello, A" diff --git a/swift/integration-tests/posix-only/partial-modules/B/Package.swift b/swift/integration-tests/posix-only/partial-modules/B/Package.swift new file mode 100644 index 00000000000..dffa5b10771 --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/B/Package.swift @@ -0,0 +1,18 @@ +// swift-tools-version: 5.5 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "B", + products: [ + .library( + name: "B", + targets: ["B"]), + ], + targets: [ + .target( + name: "B", + dependencies: []), + ] +) diff --git a/swift/integration-tests/posix-only/partial-modules/B/Sources/B/B.swift b/swift/integration-tests/posix-only/partial-modules/B/Sources/B/B.swift new file mode 100644 index 00000000000..1954601508c --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/B/Sources/B/B.swift @@ -0,0 +1,5 @@ +public struct B { + public private(set) var text = Btext + + public init() {} +} diff --git a/swift/integration-tests/posix-only/partial-modules/B/Sources/B/Bsup.swift b/swift/integration-tests/posix-only/partial-modules/B/Sources/B/Bsup.swift new file mode 100644 index 00000000000..80634b1065d --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/B/Sources/B/Bsup.swift @@ -0,0 +1 @@ +let Btext = "Hello, B" diff --git a/swift/integration-tests/posix-only/partial-modules/Modules.expected b/swift/integration-tests/posix-only/partial-modules/Modules.expected new file mode 100644 index 00000000000..3cdcff9b980 --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/Modules.expected @@ -0,0 +1,5 @@ +| file://:0:0:0:0 | A | +| file://:0:0:0:0 | B | +| file://:0:0:0:0 | PackageDescription | +| file://:0:0:0:0 | main | +| file://:0:0:0:0 | partial_modules | diff --git a/swift/integration-tests/posix-only/partial-modules/Modules.ql b/swift/integration-tests/posix-only/partial-modules/Modules.ql new file mode 100644 index 00000000000..d456e261a3c --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/Modules.ql @@ -0,0 +1,5 @@ +import swift + +from ModuleDecl decl +where not decl.isBuiltinModule() and not decl.isSystemModule() +select decl diff --git a/swift/integration-tests/posix-only/partial-modules/Package.swift b/swift/integration-tests/posix-only/partial-modules/Package.swift new file mode 100644 index 00000000000..362476ab0c4 --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/Package.swift @@ -0,0 +1,23 @@ +// swift-tools-version: 5.5 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "partial-modules", + products: [ + .library( + name: "partial-modules", + targets: ["partial-modules"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + .package(path: "./A"), + .package(path: "./B"), + ], + targets: [ + .target( + name: "partial-modules", + dependencies: ["A", "B"]), + ] +) diff --git a/swift/integration-tests/posix-only/partial-modules/Sources/partial-modules/partial_modules.swift b/swift/integration-tests/posix-only/partial-modules/Sources/partial-modules/partial_modules.swift new file mode 100644 index 00000000000..ee70ae483c8 --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/Sources/partial-modules/partial_modules.swift @@ -0,0 +1,11 @@ +import A +import B + +public struct partial_modules { + public init() { + let a = A() + let b = B() + print(a.text) + print(b.text) + } +} diff --git a/swift/integration-tests/posix-only/partial-modules/Unknown.expected b/swift/integration-tests/posix-only/partial-modules/Unknown.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/integration-tests/posix-only/partial-modules/Unknown.ql b/swift/integration-tests/posix-only/partial-modules/Unknown.ql new file mode 100644 index 00000000000..222ef6339a7 --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/Unknown.ql @@ -0,0 +1,4 @@ +import swift + +from UnresolvedDotExpr e +select e diff --git a/swift/integration-tests/posix-only/partial-modules/test.py b/swift/integration-tests/posix-only/partial-modules/test.py new file mode 100644 index 00000000000..ae89d5da5d7 --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/test.py @@ -0,0 +1,7 @@ +from create_database_utils import * + +run_codeql_database_create([ + 'env', + 'swift package clean', + 'swift build' +], lang='swift', keep_trap=True) diff --git a/swift/integration-tests/runner.py b/swift/integration-tests/runner.py new file mode 100755 index 00000000000..77a62bfb81b --- /dev/null +++ b/swift/integration-tests/runner.py @@ -0,0 +1,82 @@ +#!/bin/env python3 +""" +recreation of internal `integration-tests-runner.py` to run the tests locally, with minimal +and swift-specialized functionality. + +This runner requires: +* a codeql CLI binary in PATH +* `bazel run //swift:create_extractor_pack` to have been run +""" + +import pathlib +import os +import sys +import subprocess +import argparse +import shutil +import platform + +this_dir = pathlib.Path(__file__).parent + + +def options(): + p = argparse.ArgumentParser() + p.add_argument("--test-dir", "-d", type=pathlib.Path, action="append") + #FIXME: the following should be the default + p.add_argument("--check-databases", action="store_true") + p.add_argument("--learn", action="store_true") + p.add_argument("--threads", "-j", type=int, default=0) + return p.parse_args() + + +def execute_test(path): + shutil.rmtree(path.parent / "db", ignore_errors=True) + return subprocess.run([sys.executable, "-u", path.name], cwd=path.parent).returncode == 0 + +def skipped(test): + return platform.system() != "Darwin" and "osx-only" in test.parts + + +def main(opts): + test_dirs = opts.test_dir or [this_dir] + tests = [t for d in test_dirs for t in d.rglob("test.py") if not skipped(t)] + + if not tests: + print("No tests found", file=sys.stderr) + return False + + os.environ["PYTHONPATH"] = str(this_dir) + failed_db_creation = [] + succesful_db_creation = [] + for t in tests: + (succesful_db_creation if execute_test(t) else failed_db_creation).append(t) + + if succesful_db_creation: + codeql_root = this_dir.parents[1] + cmd = [ + "codeql", "test", "run", + f"--search-path={codeql_root}", + "--keep-databases", + "--dataset=db/db-swift", + f"--threads={opts.threads}", + ] + if opts.check_databases: + cmd.append("--check-databases") + else: + cmd.append("--no-check-databases") + if opts.learn: + cmd.append("--learn") + cmd.extend(str(t.parent) for t in succesful_db_creation) + ql_test_success = subprocess.run(cmd).returncode == 0 + + if failed_db_creation: + print("Database creation failed:", file=sys.stderr) + for t in failed_db_creation: + print(" ", t.parent, file=sys.stderr) + return False + + return ql_test_success + + +if __name__ == "__main__": + sys.exit(0 if main(options()) else 1) diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll index b69acbec115..c3eda3a98f5 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll @@ -59,7 +59,7 @@ module CfgScope { private class KeyPathScope extends Range_ instanceof KeyPathExpr { AstControlFlowTree tree; - KeyPathScope() { tree.getAst() = this.getParsedRoot().getFullyConverted() } + KeyPathScope() { tree.getAst() = this } final override predicate entry(ControlFlowElement first) { first(tree, first) } @@ -836,9 +836,6 @@ module Patterns { // Note: `getSubPattern` only has a result if the `is` pattern is of the form `pattern as type`. i = 0 and result.asAstNode() = ast.getSubPattern().getFullyUnresolved() - or - i = 1 and - result.asAstNode() = ast.getCastTypeRepr() } } @@ -946,6 +943,37 @@ module Decls { } } + /** + * The control-flow of a type declaration. This is necessary to skip past local type + * declarations that occur inside bodies like in: + * ```swift + * func foo() -> Int { + * let x = 42 + * class C {} + * return x + * } + * ``` + */ + private class TypeDeclTree extends AstLeafTree { + override TypeDecl ast; + } + + /** + * The control-flow of a function declaration. This is necessary to skip past local function + * declarations that occur inside bodies like in: + * ```swift + * func foo() -> Int { + * let x = 42 + * func bar() { ... } + * return x + * } + * ``` + */ + private class AbstractFunctionDeclTree extends AstLeafTree { + override AbstractFunctionDecl ast; + } + + /** The control-flow of a function declaration body. */ class FuncDeclTree extends StandardPreOrderTree, TFuncDeclElement { AbstractFunctionDecl ast; @@ -1573,8 +1601,14 @@ module Exprs { final override ControlFlowElement getChildElement(int i) { result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0 - or - result.asAstNode() = ast.getTypeRepr().getFullyUnresolved() and i = 1 + } + } + + private class IsTree extends AstStandardPostOrderTree { + override IsExpr ast; + + final override ControlFlowElement getChildElement(int i) { + result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0 } } diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll index 47fcd24883c..7d0dd10c084 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll @@ -881,7 +881,12 @@ import Cached * graph is restricted to nodes from `RelevantNode`. */ module TestOutput { - abstract class RelevantNode extends Node { } + abstract class RelevantNode extends Node { + /** + * Gets a string used to resolve ties in node and edge ordering. + */ + string getOrderDisambuigation() { result = "" } + } query predicate nodes(RelevantNode n, string attr, string val) { attr = "semmle.order" and @@ -894,7 +899,8 @@ module TestOutput { p order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString(), + p.getOrderDisambuigation() ) ).toString() } @@ -916,7 +922,8 @@ module TestOutput { s order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString(), + s.getOrderDisambuigation() ) ).toString() } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 7b9e78d2c4b..a076f7a2e45 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/swift/ql/lib/codeql/swift/elements.qll b/swift/ql/lib/codeql/swift/elements.qll index c10706d7c7a..1a5da053693 100644 --- a/swift/ql/lib/codeql/swift/elements.qll +++ b/swift/ql/lib/codeql/swift/elements.qll @@ -24,6 +24,7 @@ import codeql.swift.elements.decl.FuncDecl import codeql.swift.elements.decl.GenericContext import codeql.swift.elements.decl.GenericTypeDecl import codeql.swift.elements.decl.GenericTypeParamDecl +import codeql.swift.elements.decl.IfConfigClause import codeql.swift.elements.decl.IfConfigDecl import codeql.swift.elements.decl.ImportDecl import codeql.swift.elements.decl.InfixOperatorDecl @@ -271,6 +272,7 @@ import codeql.swift.elements.type.SyntaxSugarType import codeql.swift.elements.type.TupleType import codeql.swift.elements.type.Type import codeql.swift.elements.type.TypeAliasType +import codeql.swift.elements.type.TypeRepr import codeql.swift.elements.type.TypeVariableType import codeql.swift.elements.type.UnarySyntaxSugarType import codeql.swift.elements.type.UnboundGenericType @@ -279,32 +281,3 @@ import codeql.swift.elements.type.UnownedStorageType import codeql.swift.elements.type.UnresolvedType import codeql.swift.elements.type.VariadicSequenceType import codeql.swift.elements.type.WeakStorageType -import codeql.swift.elements.typerepr.ArrayTypeRepr -import codeql.swift.elements.typerepr.AttributedTypeRepr -import codeql.swift.elements.typerepr.CompileTimeConstTypeRepr -import codeql.swift.elements.typerepr.ComponentIdentTypeRepr -import codeql.swift.elements.typerepr.CompositionTypeRepr -import codeql.swift.elements.typerepr.CompoundIdentTypeRepr -import codeql.swift.elements.typerepr.DictionaryTypeRepr -import codeql.swift.elements.typerepr.ErrorTypeRepr -import codeql.swift.elements.typerepr.ExistentialTypeRepr -import codeql.swift.elements.typerepr.FixedTypeRepr -import codeql.swift.elements.typerepr.FunctionTypeRepr -import codeql.swift.elements.typerepr.GenericIdentTypeRepr -import codeql.swift.elements.typerepr.IdentTypeRepr -import codeql.swift.elements.typerepr.ImplicitlyUnwrappedOptionalTypeRepr -import codeql.swift.elements.typerepr.InOutTypeRepr -import codeql.swift.elements.typerepr.IsolatedTypeRepr -import codeql.swift.elements.typerepr.MetatypeTypeRepr -import codeql.swift.elements.typerepr.NamedOpaqueReturnTypeRepr -import codeql.swift.elements.typerepr.OpaqueReturnTypeRepr -import codeql.swift.elements.typerepr.OptionalTypeRepr -import codeql.swift.elements.typerepr.OwnedTypeRepr -import codeql.swift.elements.typerepr.PlaceholderTypeRepr -import codeql.swift.elements.typerepr.ProtocolTypeRepr -import codeql.swift.elements.typerepr.SharedTypeRepr -import codeql.swift.elements.typerepr.SilBoxTypeRepr -import codeql.swift.elements.typerepr.SimpleIdentTypeRepr -import codeql.swift.elements.typerepr.SpecifierTypeRepr -import codeql.swift.elements.typerepr.TupleTypeRepr -import codeql.swift.elements.typerepr.TypeRepr diff --git a/swift/ql/lib/codeql/swift/elements/Locatable.qll b/swift/ql/lib/codeql/swift/elements/Locatable.qll index 19b5cc4818e..f07641af07b 100644 --- a/swift/ql/lib/codeql/swift/elements/Locatable.qll +++ b/swift/ql/lib/codeql/swift/elements/Locatable.qll @@ -1,4 +1,5 @@ private import codeql.swift.generated.Locatable +private import codeql.swift.elements.File class Locatable extends LocatableBase { pragma[nomagic] @@ -7,4 +8,9 @@ class Locatable extends LocatableBase { or not exists(LocatableBase.super.getLocation()) and result instanceof UnknownLocation } + + /** + * Gets the primary file where this element occurs. + */ + File getFile() { result = getLocation().getFile() } } diff --git a/swift/ql/lib/codeql/swift/elements/decl/IfConfigClause.qll b/swift/ql/lib/codeql/swift/elements/decl/IfConfigClause.qll new file mode 100644 index 00000000000..6ab22e67989 --- /dev/null +++ b/swift/ql/lib/codeql/swift/elements/decl/IfConfigClause.qll @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py, remove this comment if you wish to edit this file +private import codeql.swift.generated.decl.IfConfigClause + +class IfConfigClause extends IfConfigClauseBase { } diff --git a/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll b/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll new file mode 100644 index 00000000000..27e7e42e4fa --- /dev/null +++ b/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll @@ -0,0 +1,112 @@ +private import codeql.swift.elements.expr.Expr +private import codeql.swift.elements.expr.BinaryExpr +private import codeql.swift.elements.expr.PrefixUnaryExpr +private import codeql.swift.elements.expr.DotSyntaxCallExpr + +/** + * An arithmetic operation, such as: + * ``` + * a + b + * ``` + */ +class ArithmeticOperation extends Expr { + ArithmeticOperation() { + this instanceof BinaryArithmeticOperation or + this instanceof UnaryArithmeticOperation + } + + /** + * Gets an operand of this arithmetic operation. + */ + Expr getAnOperand() { + result = this.(BinaryArithmeticOperation).getAnOperand() + or + result = this.(UnaryArithmeticOperation).getOperand() + } +} + +/** + * A binary arithmetic operation, such as: + * ``` + * a + b + * ``` + */ +class BinaryArithmeticOperation extends BinaryExpr { + BinaryArithmeticOperation() { + this instanceof AddExpr or + this instanceof SubExpr or + this instanceof MulExpr or + this instanceof DivExpr or + this instanceof RemExpr + } +} + +/** + * An add expression. + * ``` + * a + b + * ``` + */ +class AddExpr extends BinaryExpr { + AddExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "+(_:_:)" } +} + +/** + * A subtract expression. + * ``` + * a - b + * ``` + */ +class SubExpr extends BinaryExpr { + SubExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "-(_:_:)" } +} + +/** + * A multiply expression. + * ``` + * a * b + * ``` + */ +class MulExpr extends BinaryExpr { + MulExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "*(_:_:)" } +} + +/** + * A divide expression. + * ``` + * a / b + * ``` + */ +class DivExpr extends BinaryExpr { + DivExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "/(_:_:)" } +} + +/** + * A remainder expression. + * ``` + * a % b + * ``` + */ +class RemExpr extends BinaryExpr { + RemExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "%(_:_:)" } +} + +/** + * A unary arithmetic operation, such as: + * ``` + * -a + * ``` + */ +class UnaryArithmeticOperation extends PrefixUnaryExpr { + UnaryArithmeticOperation() { this instanceof UnaryMinusExpr } +} + +/** + * A unary minus expression. + * ``` + * -a + * ``` + */ +class UnaryMinusExpr extends PrefixUnaryExpr { + UnaryMinusExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "-(_:)" } +} diff --git a/swift/ql/lib/codeql/swift/elements/expr/LogicalOperation.qll b/swift/ql/lib/codeql/swift/elements/expr/LogicalOperation.qll index 928e25cccfd..5a550923199 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/LogicalOperation.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/LogicalOperation.qll @@ -6,31 +6,19 @@ private import codeql.swift.elements.expr.DeclRefExpr private import codeql.swift.elements.decl.ConcreteFuncDecl private predicate unaryHasName(PrefixUnaryExpr e, string name) { - e.getFunction() - .(DotSyntaxCallExpr) - .getFunction() - .(DeclRefExpr) - .getDecl() - .(ConcreteFuncDecl) - .getName() = name + e.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = name } private predicate binaryHasName(BinaryExpr e, string name) { - e.getFunction() - .(DotSyntaxCallExpr) - .getFunction() - .(DeclRefExpr) - .getDecl() - .(ConcreteFuncDecl) - .getName() = name + e.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = name } class LogicalAndExpr extends BinaryExpr { - LogicalAndExpr() { binaryHasName(this, "&&") } + LogicalAndExpr() { binaryHasName(this, "&&(_:_:)") } } class LogicalOrExpr extends BinaryExpr { - LogicalOrExpr() { binaryHasName(this, "||") } + LogicalOrExpr() { binaryHasName(this, "||(_:_:)") } } class BinaryLogicalOperation extends BinaryExpr { @@ -41,7 +29,7 @@ class BinaryLogicalOperation extends BinaryExpr { } class NotExpr extends PrefixUnaryExpr { - NotExpr() { unaryHasName(this, "!") } + NotExpr() { unaryHasName(this, "!(_:)") } } class UnaryLogicalOperation extends PrefixUnaryExpr { diff --git a/swift/ql/lib/codeql/swift/elements/expr/UnresolvedDeclRefExpr.qll b/swift/ql/lib/codeql/swift/elements/expr/UnresolvedDeclRefExpr.qll index 281e1db01a7..3cbe55fe9a6 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/UnresolvedDeclRefExpr.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/UnresolvedDeclRefExpr.qll @@ -1,4 +1,9 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file private import codeql.swift.generated.expr.UnresolvedDeclRefExpr -class UnresolvedDeclRefExpr extends UnresolvedDeclRefExprBase { } +class UnresolvedDeclRefExpr extends UnresolvedDeclRefExprBase { + override string toString() { + result = getName() + " (unresolved)" + or + not hasName() and result = "(unresolved)" + } +} diff --git a/swift/ql/lib/codeql/swift/elements/type/AnyGenericType.qll b/swift/ql/lib/codeql/swift/elements/type/AnyGenericType.qll index dbdf4a9b27b..1dac1499152 100644 --- a/swift/ql/lib/codeql/swift/elements/type/AnyGenericType.qll +++ b/swift/ql/lib/codeql/swift/elements/type/AnyGenericType.qll @@ -1,6 +1,4 @@ +// generated by codegen/codegen.py, remove this comment if you wish to edit this file private import codeql.swift.generated.type.AnyGenericType -private import codeql.swift.elements.decl.GenericTypeDecl -class AnyGenericType extends AnyGenericTypeBase { - string getName() { result = this.getDeclaration().(GenericTypeDecl).getName() } -} +class AnyGenericType extends AnyGenericTypeBase { } diff --git a/swift/ql/lib/codeql/swift/elements/type/ExistentialType.qll b/swift/ql/lib/codeql/swift/elements/type/ExistentialType.qll index 2f3241dcc44..6730daf49cf 100644 --- a/swift/ql/lib/codeql/swift/elements/type/ExistentialType.qll +++ b/swift/ql/lib/codeql/swift/elements/type/ExistentialType.qll @@ -1,6 +1,4 @@ +// generated by codegen/codegen.py, remove this comment if you wish to edit this file private import codeql.swift.generated.type.ExistentialType -private import codeql.swift.elements.type.ProtocolType -class ExistentialType extends ExistentialTypeBase { - override ProtocolType getConstraint() { result = super.getConstraint() } -} +class ExistentialType extends ExistentialTypeBase { } diff --git a/swift/ql/lib/codeql/swift/elements/type/Type.qll b/swift/ql/lib/codeql/swift/elements/type/Type.qll index 18d37ff8b40..1b357e65560 100644 --- a/swift/ql/lib/codeql/swift/elements/type/Type.qll +++ b/swift/ql/lib/codeql/swift/elements/type/Type.qll @@ -1,7 +1,5 @@ private import codeql.swift.generated.type.Type class Type extends TypeBase { - override string toString() { result = this.getDiagnosticsName() } - - string getName() { result = this.getDiagnosticsName() } + override string toString() { result = this.getName() } } diff --git a/swift/ql/lib/codeql/swift/elements/type/TypeRepr.qll b/swift/ql/lib/codeql/swift/elements/type/TypeRepr.qll new file mode 100644 index 00000000000..8462ceb1b6b --- /dev/null +++ b/swift/ql/lib/codeql/swift/elements/type/TypeRepr.qll @@ -0,0 +1,5 @@ +private import codeql.swift.generated.type.TypeRepr + +class TypeRepr extends TypeReprBase { + override string toString() { result = getType().toString() } +} diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/ComponentIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/ComponentIdentTypeRepr.qll deleted file mode 100644 index 0b5640208f4..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/ComponentIdentTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.ComponentIdentTypeRepr - -class ComponentIdentTypeRepr extends ComponentIdentTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/CompositionTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/CompositionTypeRepr.qll deleted file mode 100644 index 4f79f493e7e..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/CompositionTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.CompositionTypeRepr - -class CompositionTypeRepr extends CompositionTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/ErrorTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/ErrorTypeRepr.qll deleted file mode 100644 index bc3a125e0ac..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/ErrorTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.ErrorTypeRepr - -class ErrorTypeRepr extends ErrorTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/ExistentialTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/ExistentialTypeRepr.qll deleted file mode 100644 index 7762a02bb64..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/ExistentialTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.ExistentialTypeRepr - -class ExistentialTypeRepr extends ExistentialTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/FixedTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/FixedTypeRepr.qll deleted file mode 100644 index 8c1687c8853..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/FixedTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.FixedTypeRepr - -class FixedTypeRepr extends FixedTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/IdentTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/IdentTypeRepr.qll deleted file mode 100644 index 5fa70e354e4..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/IdentTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.IdentTypeRepr - -class IdentTypeRepr extends IdentTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/NamedOpaqueReturnTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/NamedOpaqueReturnTypeRepr.qll deleted file mode 100644 index 115b02b9858..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/NamedOpaqueReturnTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.NamedOpaqueReturnTypeRepr - -class NamedOpaqueReturnTypeRepr extends NamedOpaqueReturnTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/OpaqueReturnTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/OpaqueReturnTypeRepr.qll deleted file mode 100644 index cd0586d67f4..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/OpaqueReturnTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.OpaqueReturnTypeRepr - -class OpaqueReturnTypeRepr extends OpaqueReturnTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/PlaceholderTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/PlaceholderTypeRepr.qll deleted file mode 100644 index 423ced1a5d8..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/PlaceholderTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.PlaceholderTypeRepr - -class PlaceholderTypeRepr extends PlaceholderTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/SimpleIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/SimpleIdentTypeRepr.qll deleted file mode 100644 index 070146f5ace..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/SimpleIdentTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.SimpleIdentTypeRepr - -class SimpleIdentTypeRepr extends SimpleIdentTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/SpecifierTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/SpecifierTypeRepr.qll deleted file mode 100644 index 40d1d648881..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/SpecifierTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.SpecifierTypeRepr - -class SpecifierTypeRepr extends SpecifierTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/TypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/TypeRepr.qll deleted file mode 100644 index 4a4ea87833e..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/TypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.TypeRepr - -class TypeRepr extends TypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll b/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll index aaf3dec16bd..5b8b979d16f 100644 --- a/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll +++ b/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll @@ -28,6 +28,12 @@ Element getAnImmediateChild(Element e) { or enum_element_decl_params(e, _, x) or + if_config_clause_conditions(e, x) + or + if_config_clause_elements(e, _, x) + or + if_config_decl_clauses(e, _, x) + or pattern_binding_decl_inits(e, _, x) or pattern_binding_decl_patterns(e, _, x) @@ -64,11 +70,9 @@ Element getAnImmediateChild(Element e) { or dynamic_type_exprs(e, x) or - enum_is_case_exprs(e, x, _, _) + enum_is_case_exprs(e, x, _) or - enum_is_case_exprs(e, _, x, _) - or - enum_is_case_exprs(e, _, _, x) + enum_is_case_exprs(e, _, x) or explicit_cast_exprs(e, x) or @@ -96,7 +100,7 @@ Element getAnImmediateChild(Element e) { or key_path_application_exprs(e, _, x) or - key_path_expr_parsed_roots(e, x) + key_path_expr_roots(e, x) or key_path_expr_parsed_paths(e, x) or @@ -144,6 +148,8 @@ Element getAnImmediateChild(Element e) { or unresolved_dot_exprs(e, x, _) or + unresolved_pattern_exprs(e, x) + or vararg_expansion_exprs(e, x) or binding_patterns(e, x) diff --git a/swift/ql/lib/codeql/swift/generated/decl/IfConfigClause.qll b/swift/ql/lib/codeql/swift/generated/decl/IfConfigClause.qll new file mode 100644 index 00000000000..89a1cb277ed --- /dev/null +++ b/swift/ql/lib/codeql/swift/generated/decl/IfConfigClause.qll @@ -0,0 +1,30 @@ +// generated by codegen/codegen.py +import codeql.swift.elements.AstNode +import codeql.swift.elements.expr.Expr +import codeql.swift.elements.Locatable + +class IfConfigClauseBase extends @if_config_clause, Locatable { + override string getAPrimaryQlClass() { result = "IfConfigClause" } + + Expr getCondition() { + exists(Expr x | + if_config_clause_conditions(this, x) and + result = x.resolve() + ) + } + + predicate hasCondition() { exists(getCondition()) } + + AstNode getElement(int index) { + exists(AstNode x | + if_config_clause_elements(this, index, x) and + result = x.resolve() + ) + } + + AstNode getAnElement() { result = getElement(_) } + + int getNumberOfElements() { result = count(getAnElement()) } + + predicate isActive() { if_config_clause_is_active(this) } +} diff --git a/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll index 578051e9f8b..5d13959a227 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll @@ -1,6 +1,18 @@ // generated by codegen/codegen.py import codeql.swift.elements.decl.Decl +import codeql.swift.elements.decl.IfConfigClause class IfConfigDeclBase extends @if_config_decl, Decl { override string getAPrimaryQlClass() { result = "IfConfigDecl" } + + IfConfigClause getClause(int index) { + exists(IfConfigClause x | + if_config_decl_clauses(this, index, x) and + result = x.resolve() + ) + } + + IfConfigClause getAClause() { result = getClause(_) } + + int getNumberOfClauses() { result = count(getAClause()) } } diff --git a/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll index fdd89db170a..8f5638ad069 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll @@ -1,6 +1,28 @@ // generated by codegen/codegen.py import codeql.swift.elements.decl.Decl +import codeql.swift.elements.decl.ModuleDecl +import codeql.swift.elements.decl.ValueDecl class ImportDeclBase extends @import_decl, Decl { override string getAPrimaryQlClass() { result = "ImportDecl" } + + predicate isExported() { import_decl_is_exported(this) } + + ModuleDecl getModule() { + exists(ModuleDecl x | + import_decls(this, x) and + result = x.resolve() + ) + } + + ValueDecl getDeclaration(int index) { + exists(ValueDecl x | + import_decl_declarations(this, index, x) and + result = x.resolve() + ) + } + + ValueDecl getADeclaration() { result = getDeclaration(_) } + + int getNumberOfDeclarations() { result = count(getADeclaration()) } } diff --git a/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll index aad5d00c0c6..3a1931b2d52 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll @@ -3,4 +3,8 @@ import codeql.swift.elements.decl.TypeDecl class ModuleDeclBase extends @module_decl, TypeDecl { override string getAPrimaryQlClass() { result = "ModuleDecl" } + + predicate isBuiltinModule() { module_decl_is_builtin_module(this) } + + predicate isSystemModule() { module_decl_is_system_module(this) } } diff --git a/swift/ql/lib/codeql/swift/generated/expr/Argument.qll b/swift/ql/lib/codeql/swift/generated/expr/Argument.qll index 9f16b90e3fe..7e8d6ea0ed3 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/Argument.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/Argument.qll @@ -1,8 +1,8 @@ // generated by codegen/codegen.py -import codeql.swift.elements.Element import codeql.swift.elements.expr.Expr +import codeql.swift.elements.Locatable -class ArgumentBase extends @argument, Element { +class ArgumentBase extends @argument, Locatable { override string getAPrimaryQlClass() { result = "Argument" } string getLabel() { arguments(this, result, _) } diff --git a/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll index e02b97813a4..1dfdb7d0d2c 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll @@ -1,28 +1,20 @@ // generated by codegen/codegen.py import codeql.swift.elements.decl.EnumElementDecl import codeql.swift.elements.expr.Expr -import codeql.swift.elements.typerepr.TypeRepr class EnumIsCaseExprBase extends @enum_is_case_expr, Expr { override string getAPrimaryQlClass() { result = "EnumIsCaseExpr" } Expr getSubExpr() { exists(Expr x | - enum_is_case_exprs(this, x, _, _) and - result = x.resolve() - ) - } - - TypeRepr getTypeRepr() { - exists(TypeRepr x | - enum_is_case_exprs(this, _, x, _) and + enum_is_case_exprs(this, x, _) and result = x.resolve() ) } EnumElementDecl getElement() { exists(EnumElementDecl x | - enum_is_case_exprs(this, _, _, x) and + enum_is_case_exprs(this, _, x) and result = x.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll index 7ac3d4614f0..faeeb4fde9b 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll @@ -1,17 +1,18 @@ // generated by codegen/codegen.py import codeql.swift.elements.expr.Expr +import codeql.swift.elements.type.TypeRepr class KeyPathExprBase extends @key_path_expr, Expr { override string getAPrimaryQlClass() { result = "KeyPathExpr" } - Expr getParsedRoot() { - exists(Expr x | - key_path_expr_parsed_roots(this, x) and + TypeRepr getRoot() { + exists(TypeRepr x | + key_path_expr_roots(this, x) and result = x.resolve() ) } - predicate hasParsedRoot() { exists(getParsedRoot()) } + predicate hasRoot() { exists(getRoot()) } Expr getParsedPath() { exists(Expr x | diff --git a/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll index 8b9e238b3ca..3c5816624d1 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll @@ -1,6 +1,6 @@ // generated by codegen/codegen.py import codeql.swift.elements.expr.Expr -import codeql.swift.elements.typerepr.TypeRepr +import codeql.swift.elements.type.TypeRepr class TypeExprBase extends @type_expr, Expr { override string getAPrimaryQlClass() { result = "TypeExpr" } diff --git a/swift/ql/lib/codeql/swift/generated/expr/UnresolvedPatternExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/UnresolvedPatternExpr.qll index 8d03b2079aa..ae62f2df23b 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/UnresolvedPatternExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/UnresolvedPatternExpr.qll @@ -1,6 +1,14 @@ // generated by codegen/codegen.py import codeql.swift.elements.expr.Expr +import codeql.swift.elements.pattern.Pattern class UnresolvedPatternExprBase extends @unresolved_pattern_expr, Expr { override string getAPrimaryQlClass() { result = "UnresolvedPatternExpr" } + + Pattern getSubPattern() { + exists(Pattern x | + unresolved_pattern_exprs(this, x) and + result = x.resolve() + ) + } } diff --git a/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll b/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll index 8caf5493b36..b83c0af7d65 100644 --- a/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll +++ b/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll @@ -1,6 +1,6 @@ // generated by codegen/codegen.py import codeql.swift.elements.pattern.Pattern -import codeql.swift.elements.typerepr.TypeRepr +import codeql.swift.elements.type.TypeRepr class IsPatternBase extends @is_pattern, Pattern { override string getAPrimaryQlClass() { result = "IsPattern" } diff --git a/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll b/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll index 9a16c9cfe02..aebb2a6527c 100644 --- a/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll +++ b/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll @@ -1,6 +1,6 @@ // generated by codegen/codegen.py import codeql.swift.elements.pattern.Pattern -import codeql.swift.elements.typerepr.TypeRepr +import codeql.swift.elements.type.TypeRepr class TypedPatternBase extends @typed_pattern, Pattern { override string getAPrimaryQlClass() { result = "TypedPattern" } diff --git a/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll b/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll index a3184728112..ef257500f64 100644 --- a/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll @@ -4,11 +4,9 @@ import codeql.swift.elements.type.SubstitutableType import codeql.swift.elements.type.Type class ArchetypeTypeBase extends @archetype_type, SubstitutableType { - string getName() { archetype_types(this, result, _) } - Type getInterfaceType() { exists(Type x | - archetype_types(this, _, x) and + archetype_types(this, x) and result = x.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/type/GenericTypeParamType.qll b/swift/ql/lib/codeql/swift/generated/type/GenericTypeParamType.qll index c0b13904806..9f286d86cc7 100644 --- a/swift/ql/lib/codeql/swift/generated/type/GenericTypeParamType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/GenericTypeParamType.qll @@ -3,6 +3,4 @@ import codeql.swift.elements.type.SubstitutableType class GenericTypeParamTypeBase extends @generic_type_param_type, SubstitutableType { override string getAPrimaryQlClass() { result = "GenericTypeParamType" } - - string getName() { generic_type_param_types(this, result) } } diff --git a/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll b/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll index 91da39854d7..866598ad431 100644 --- a/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll @@ -1,6 +1,14 @@ // generated by codegen/codegen.py +import codeql.swift.elements.decl.ModuleDecl import codeql.swift.elements.type.Type class ModuleTypeBase extends @module_type, Type { override string getAPrimaryQlClass() { result = "ModuleType" } + + ModuleDecl getModule() { + exists(ModuleDecl x | + module_types(this, x) and + result = x.resolve() + ) + } } diff --git a/swift/ql/lib/codeql/swift/generated/type/ProtocolCompositionType.qll b/swift/ql/lib/codeql/swift/generated/type/ProtocolCompositionType.qll index 863f8c8ca8b..594338def93 100644 --- a/swift/ql/lib/codeql/swift/generated/type/ProtocolCompositionType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/ProtocolCompositionType.qll @@ -3,4 +3,15 @@ import codeql.swift.elements.type.Type class ProtocolCompositionTypeBase extends @protocol_composition_type, Type { override string getAPrimaryQlClass() { result = "ProtocolCompositionType" } + + Type getMember(int index) { + exists(Type x | + protocol_composition_type_members(this, index, x) and + result = x.resolve() + ) + } + + Type getAMember() { result = getMember(_) } + + int getNumberOfMembers() { result = count(getAMember()) } } diff --git a/swift/ql/lib/codeql/swift/generated/type/Type.qll b/swift/ql/lib/codeql/swift/generated/type/Type.qll index cfe4b638da3..ee55d9ce9d6 100644 --- a/swift/ql/lib/codeql/swift/generated/type/Type.qll +++ b/swift/ql/lib/codeql/swift/generated/type/Type.qll @@ -3,7 +3,7 @@ import codeql.swift.elements.Element import codeql.swift.elements.type.Type class TypeBase extends @type, Element { - string getDiagnosticsName() { types(this, result, _) } + string getName() { types(this, result, _) } Type getCanonicalType() { exists(Type x | diff --git a/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll b/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll new file mode 100644 index 00000000000..5cc1cc04147 --- /dev/null +++ b/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll @@ -0,0 +1,16 @@ +// generated by codegen/codegen.py +import codeql.swift.elements.AstNode +import codeql.swift.elements.type.Type + +class TypeReprBase extends @type_repr, AstNode { + override string getAPrimaryQlClass() { result = "TypeRepr" } + + Type getType() { + exists(Type x | + type_repr_types(this, x) and + result = x.resolve() + ) + } + + predicate hasType() { exists(getType()) } +} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ArrayTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ArrayTypeRepr.qll deleted file mode 100644 index 486a98a541e..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ArrayTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class ArrayTypeReprBase extends @array_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "ArrayTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/AttributedTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/AttributedTypeRepr.qll deleted file mode 100644 index 96d78c7c933..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/AttributedTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class AttributedTypeReprBase extends @attributed_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "AttributedTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/CompileTimeConstTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/CompileTimeConstTypeRepr.qll deleted file mode 100644 index eecb67b9218..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/CompileTimeConstTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.SpecifierTypeRepr - -class CompileTimeConstTypeReprBase extends @compile_time_const_type_repr, SpecifierTypeRepr { - override string getAPrimaryQlClass() { result = "CompileTimeConstTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ComponentIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ComponentIdentTypeRepr.qll deleted file mode 100644 index d0323ad681d..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ComponentIdentTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.IdentTypeRepr - -class ComponentIdentTypeReprBase extends @component_ident_type_repr, IdentTypeRepr { } diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/CompositionTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/CompositionTypeRepr.qll deleted file mode 100644 index b0789100618..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/CompositionTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class CompositionTypeReprBase extends @composition_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "CompositionTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/CompoundIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/CompoundIdentTypeRepr.qll deleted file mode 100644 index 7c1c3548272..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/CompoundIdentTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.IdentTypeRepr - -class CompoundIdentTypeReprBase extends @compound_ident_type_repr, IdentTypeRepr { - override string getAPrimaryQlClass() { result = "CompoundIdentTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/DictionaryTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/DictionaryTypeRepr.qll deleted file mode 100644 index 692b9352e20..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/DictionaryTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class DictionaryTypeReprBase extends @dictionary_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "DictionaryTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ErrorTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ErrorTypeRepr.qll deleted file mode 100644 index 511f7e25569..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ErrorTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class ErrorTypeReprBase extends @error_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "ErrorTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ExistentialTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ExistentialTypeRepr.qll deleted file mode 100644 index 43aefeed5a9..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ExistentialTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class ExistentialTypeReprBase extends @existential_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "ExistentialTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/FixedTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/FixedTypeRepr.qll deleted file mode 100644 index 2a6e59a90a8..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/FixedTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class FixedTypeReprBase extends @fixed_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "FixedTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/FunctionTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/FunctionTypeRepr.qll deleted file mode 100644 index da781a90d4b..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/FunctionTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class FunctionTypeReprBase extends @function_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "FunctionTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/GenericIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/GenericIdentTypeRepr.qll deleted file mode 100644 index 101985aca56..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/GenericIdentTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.ComponentIdentTypeRepr - -class GenericIdentTypeReprBase extends @generic_ident_type_repr, ComponentIdentTypeRepr { - override string getAPrimaryQlClass() { result = "GenericIdentTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/IdentTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/IdentTypeRepr.qll deleted file mode 100644 index d71eca38b92..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/IdentTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class IdentTypeReprBase extends @ident_type_repr, TypeRepr { } diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr.qll deleted file mode 100644 index e0759e0fa3c..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr.qll +++ /dev/null @@ -1,7 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class ImplicitlyUnwrappedOptionalTypeReprBase extends @implicitly_unwrapped_optional_type_repr, - TypeRepr { - override string getAPrimaryQlClass() { result = "ImplicitlyUnwrappedOptionalTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/InOutTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/InOutTypeRepr.qll deleted file mode 100644 index a7adf859579..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/InOutTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.SpecifierTypeRepr - -class InOutTypeReprBase extends @in_out_type_repr, SpecifierTypeRepr { - override string getAPrimaryQlClass() { result = "InOutTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/IsolatedTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/IsolatedTypeRepr.qll deleted file mode 100644 index 63dcdd9e379..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/IsolatedTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.SpecifierTypeRepr - -class IsolatedTypeReprBase extends @isolated_type_repr, SpecifierTypeRepr { - override string getAPrimaryQlClass() { result = "IsolatedTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/MetatypeTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/MetatypeTypeRepr.qll deleted file mode 100644 index e0477db158b..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/MetatypeTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class MetatypeTypeReprBase extends @metatype_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "MetatypeTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/NamedOpaqueReturnTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/NamedOpaqueReturnTypeRepr.qll deleted file mode 100644 index af885d21ab4..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/NamedOpaqueReturnTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class NamedOpaqueReturnTypeReprBase extends @named_opaque_return_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "NamedOpaqueReturnTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/OpaqueReturnTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/OpaqueReturnTypeRepr.qll deleted file mode 100644 index 7ecb38e22c6..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/OpaqueReturnTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class OpaqueReturnTypeReprBase extends @opaque_return_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "OpaqueReturnTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/OptionalTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/OptionalTypeRepr.qll deleted file mode 100644 index 62a24285ef5..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/OptionalTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class OptionalTypeReprBase extends @optional_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "OptionalTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/OwnedTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/OwnedTypeRepr.qll deleted file mode 100644 index b24ca1aa597..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/OwnedTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.SpecifierTypeRepr - -class OwnedTypeReprBase extends @owned_type_repr, SpecifierTypeRepr { - override string getAPrimaryQlClass() { result = "OwnedTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/PlaceholderTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/PlaceholderTypeRepr.qll deleted file mode 100644 index 5bb446c9c73..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/PlaceholderTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class PlaceholderTypeReprBase extends @placeholder_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "PlaceholderTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ProtocolTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ProtocolTypeRepr.qll deleted file mode 100644 index 1b2e7fb2652..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ProtocolTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class ProtocolTypeReprBase extends @protocol_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "ProtocolTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/SharedTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/SharedTypeRepr.qll deleted file mode 100644 index ca9254217c9..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/SharedTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.SpecifierTypeRepr - -class SharedTypeReprBase extends @shared_type_repr, SpecifierTypeRepr { - override string getAPrimaryQlClass() { result = "SharedTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/SilBoxTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/SilBoxTypeRepr.qll deleted file mode 100644 index 47d4585511b..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/SilBoxTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class SilBoxTypeReprBase extends @sil_box_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "SilBoxTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/SimpleIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/SimpleIdentTypeRepr.qll deleted file mode 100644 index 328b8bc7e69..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/SimpleIdentTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.ComponentIdentTypeRepr - -class SimpleIdentTypeReprBase extends @simple_ident_type_repr, ComponentIdentTypeRepr { - override string getAPrimaryQlClass() { result = "SimpleIdentTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/SpecifierTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/SpecifierTypeRepr.qll deleted file mode 100644 index 469aa3413d1..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/SpecifierTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class SpecifierTypeReprBase extends @specifier_type_repr, TypeRepr { } diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/TupleTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/TupleTypeRepr.qll deleted file mode 100644 index 79e65037aa9..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/TupleTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class TupleTypeReprBase extends @tuple_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "TupleTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/TypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/TypeRepr.qll deleted file mode 100644 index 497ac46fa64..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/TypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.AstNode - -class TypeReprBase extends @type_repr, AstNode { } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index f306d471380..7c102d30524 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -13,8 +13,7 @@ sourceLocationPrefix( // from codegen/schema.yml @element = - @argument -| @callable + @callable | @file | @generic_context | @iterable_decl_context @@ -34,8 +33,10 @@ files( ); @locatable = - @ast_node + @argument +| @ast_node | @condition_element +| @if_config_clause ; #keyset[id] @@ -82,7 +83,7 @@ locations( #keyset[id] types( //dir=type int id: @type ref, - string diagnostics_name: string ref, + string name: string ref, int canonical_type: @type ref ); @@ -263,7 +264,8 @@ l_value_types( //dir=type ); module_types( //dir=type - unique int id: @module_type + unique int id: @module_type, + int module: @module_decl ref ); placeholder_types( //dir=type @@ -274,6 +276,13 @@ protocol_composition_types( //dir=type unique int id: @protocol_composition_type ); +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type ref +); + existential_types( //dir=type unique int id: @existential_type, int constraint: @type ref @@ -464,27 +473,15 @@ expr_types( //dir=expr | @yield_stmt ; -@type_repr = - @array_type_repr -| @attributed_type_repr -| @composition_type_repr -| @dictionary_type_repr -| @error_type_repr -| @existential_type_repr -| @fixed_type_repr -| @function_type_repr -| @ident_type_repr -| @implicitly_unwrapped_optional_type_repr -| @metatype_type_repr -| @named_opaque_return_type_repr -| @opaque_return_type_repr -| @optional_type_repr -| @placeholder_type_repr -| @protocol_type_repr -| @sil_box_type_repr -| @specifier_type_repr -| @tuple_type_repr -; +type_reprs( //dir=type + unique int id: @type_repr +); + +#keyset[id] +type_repr_types( //dir=type + int id: @type_repr ref, + int type_: @type ref +); function_types( //dir=type unique int id: @function_type @@ -586,7 +583,6 @@ weak_storage_types( //dir=type #keyset[id] archetype_types( //dir=type int id: @archetype_type ref, - string name: string ref, int interface_type: @type ref ); @@ -604,8 +600,7 @@ archetype_type_protocols( //dir=type ); generic_type_param_types( //dir=type - unique int id: @generic_type_param_type, - string name: string ref + unique int id: @generic_type_param_type ); paren_types( //dir=type @@ -638,8 +633,50 @@ if_config_decls( //dir=decl unique int id: @if_config_decl ); +#keyset[id, index] +if_config_decl_clauses( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int clause: @if_config_clause ref +); + +if_config_clauses( //dir=decl + unique int id: @if_config_clause +); + +#keyset[id] +if_config_clause_conditions( //dir=decl + int id: @if_config_clause ref, + int condition: @expr ref +); + +#keyset[id, index] +if_config_clause_elements( //dir=decl + int id: @if_config_clause ref, + int index: int ref, + int element: @ast_node ref +); + +#keyset[id] +if_config_clause_is_active( //dir=decl + int id: @if_config_clause ref +); + import_decls( //dir=decl - unique int id: @import_decl + unique int id: @import_decl, + int module: @module_decl ref +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl ref ); missing_member_decls( //dir=decl @@ -847,7 +884,6 @@ editor_placeholder_exprs( //dir=expr enum_is_case_exprs( //dir=expr unique int id: @enum_is_case_expr, int sub_expr: @expr ref, - int type_repr: @type_repr ref, int element: @enum_element_decl ref ); @@ -951,9 +987,9 @@ key_path_exprs( //dir=expr ); #keyset[id] -key_path_expr_parsed_roots( //dir=expr +key_path_expr_roots( //dir=expr int id: @key_path_expr ref, - int parsed_root: @expr ref + int root: @type_repr ref ); #keyset[id] @@ -1123,7 +1159,8 @@ unresolved_member_exprs( //dir=expr ); unresolved_pattern_exprs( //dir=expr - unique int id: @unresolved_pattern_expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern ref ); unresolved_specialize_exprs( //dir=expr @@ -2013,6 +2050,16 @@ module_decls( //dir=decl unique int id: @module_decl ); +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + constructor_ref_call_exprs( //dir=expr unique int id: @constructor_ref_call_expr ); @@ -2149,121 +2196,3 @@ integer_literal_exprs( //dir=expr unique int id: @integer_literal_expr, string string_value: string ref ); - -error_type_reprs( //dir=typerepr - unique int id: @error_type_repr -); - -attributed_type_reprs( //dir=typerepr - unique int id: @attributed_type_repr -); - -@ident_type_repr = - @component_ident_type_repr -| @compound_ident_type_repr -; - -@component_ident_type_repr = - @generic_ident_type_repr -| @simple_ident_type_repr -; - -simple_ident_type_reprs( //dir=typerepr - unique int id: @simple_ident_type_repr -); - -generic_ident_type_reprs( //dir=typerepr - unique int id: @generic_ident_type_repr -); - -compound_ident_type_reprs( //dir=typerepr - unique int id: @compound_ident_type_repr -); - -function_type_reprs( //dir=typerepr - unique int id: @function_type_repr -); - -array_type_reprs( //dir=typerepr - unique int id: @array_type_repr -); - -dictionary_type_reprs( //dir=typerepr - unique int id: @dictionary_type_repr -); - -optional_type_reprs( //dir=typerepr - unique int id: @optional_type_repr -); - -implicitly_unwrapped_optional_type_reprs( //dir=typerepr - unique int id: @implicitly_unwrapped_optional_type_repr -); - -tuple_type_reprs( //dir=typerepr - unique int id: @tuple_type_repr -); - -composition_type_reprs( //dir=typerepr - unique int id: @composition_type_repr -); - -metatype_type_reprs( //dir=typerepr - unique int id: @metatype_type_repr -); - -protocol_type_reprs( //dir=typerepr - unique int id: @protocol_type_repr -); - -opaque_return_type_reprs( //dir=typerepr - unique int id: @opaque_return_type_repr -); - -named_opaque_return_type_reprs( //dir=typerepr - unique int id: @named_opaque_return_type_repr -); - -existential_type_reprs( //dir=typerepr - unique int id: @existential_type_repr -); - -placeholder_type_reprs( //dir=typerepr - unique int id: @placeholder_type_repr -); - -@specifier_type_repr = - @compile_time_const_type_repr -| @in_out_type_repr -| @isolated_type_repr -| @owned_type_repr -| @shared_type_repr -; - -in_out_type_reprs( //dir=typerepr - unique int id: @in_out_type_repr -); - -shared_type_reprs( //dir=typerepr - unique int id: @shared_type_repr -); - -owned_type_reprs( //dir=typerepr - unique int id: @owned_type_repr -); - -isolated_type_reprs( //dir=typerepr - unique int id: @isolated_type_repr -); - -compile_time_const_type_reprs( //dir=typerepr - unique int id: @compile_time_const_type_repr -); - -fixed_type_reprs( //dir=typerepr - unique int id: @fixed_type_repr -); - -sil_box_type_reprs( //dir=typerepr - unique int id: @sil_box_type_repr -); diff --git a/swift/ql/lib/swift.qll b/swift/ql/lib/swift.qll index a0b0f019400..d9281ba1093 100644 --- a/swift/ql/lib/swift.qll +++ b/swift/ql/lib/swift.qll @@ -1,5 +1,6 @@ /** Top-level import for the Swift language pack */ import codeql.swift.elements +import codeql.swift.elements.expr.ArithmeticOperation import codeql.swift.elements.expr.LogicalOperation import codeql.swift.elements.decl.MethodDecl diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 9dd758e7d33..4e78d56f7d2 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -1,10 +1,10 @@ /** * @name String length conflation * @description Using a length value from an `NSString` in a `String`, or a count from a `String` in an `NSString`, may cause unexpected behavior. - * @kind problem + * @kind path-problem * @problem.severity error * @security-severity 7.8 - * @precision TODO + * @precision high * @id swift/string-length-conflation * @tags security * external/cwe/cwe-135 @@ -14,71 +14,114 @@ import swift import codeql.swift.dataflow.DataFlow import DataFlow::PathGraph +/** + * A configuration for tracking string lengths originating from source that is + * a `String` or an `NSString` object, to a sink of a different kind that + * expects an incompatible measure of length. + */ class StringLengthConflationConfiguration extends DataFlow::Configuration { StringLengthConflationConfiguration() { this = "StringLengthConflationConfiguration" } override predicate isSource(DataFlow::Node node, string flowstate) { - // result of a call to to `String.count` + // result of a call to `String.count` exists(MemberRefExpr member | member.getBaseExpr().getType().getName() = "String" and member.getMember().(VarDecl).getName() = "count" and node.asExpr() = member and flowstate = "String" ) + or + // result of a call to `NSString.length` + exists(MemberRefExpr member | + member.getBaseExpr().getType().getName() = ["NSString", "NSMutableString"] and + member.getMember().(VarDecl).getName() = "length" and + node.asExpr() = member and + flowstate = "NSString" + ) } override predicate isSink(DataFlow::Node node, string flowstate) { - // arguments to method calls... exists( - string className, string methodName, string paramName, ClassDecl c, AbstractFunctionDecl f, - CallExpr call, int arg + AbstractFunctionDecl funcDecl, CallExpr call, string funcName, string paramName, int arg | ( - // `NSRange.init` - className = "NSRange" and - methodName = "init(location:length:)" and - paramName = ["location", "length"] + // arguments to method calls... + exists(string className, ClassDecl c | + ( + // `NSRange.init` + className = "NSRange" and + funcName = "init(location:length:)" and + paramName = ["location", "length"] + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "character(at:)" and + paramName = "at" + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "substring(from:)" and + paramName = "from" + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "substring(to:)" and + paramName = "to" + or + // `NSMutableString.insert` + className = "NSMutableString" and + funcName = "insert(_:at:)" and + paramName = "at" + ) and + c.getName() = className and + c.getAMember() = funcDecl and + call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and + flowstate = "String" // `String` length flowing into `NSString` + ) or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - methodName = "character(at:)" and - paramName = "at" + // arguments to function calls... + // `NSMakeRange` + funcName = "NSMakeRange(_:_:)" and + paramName = ["loc", "len"] and + call.getStaticTarget() = funcDecl and + flowstate = "String" // `String` length flowing into `NSString` or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - methodName = "substring(from:)" and - paramName = "from" - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - methodName = "substring(to:)" and - paramName = "to" - or - // `NSMutableString.insert` - className = "NSMutableString" and - methodName = "insert(_:at:)" and - paramName = "at" + // arguments to method calls... + ( + // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` + funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and + paramName = "k" + or + // `String.prefix`, `String.suffix` + funcName = ["prefix(_:)", "suffix(_:)"] and + paramName = "maxLength" + or + // `String.Index.init` + funcName = "init(encodedOffset:)" and + paramName = "offset" + or + // `String.index` + funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and + paramName = "n" + or + // `String.formIndex` + funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and + paramName = "distance" + ) and + call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and + flowstate = "NSString" // `NSString` length flowing into `String` ) and - c.getName() = className and - c.getAMember() = f and // TODO: will this even work if its defined in a parent class? - call.getFunction().(ApplyExpr).getStaticTarget() = f and - f.getName() = methodName and - f.getParam(arg).getName() = paramName and - call.getArgument(arg).getExpr() = node.asExpr() and - flowstate = "String" // `String` length flowing into `NSString` - ) - or - // arguments to function calls... - exists(string funcName, string paramName, CallExpr call, int arg | - // `NSMakeRange` - funcName = "NSMakeRange(_:_:)" and - paramName = ["loc", "len"] and - call.getStaticTarget().getName() = funcName and - call.getStaticTarget().getParam(arg).getName() = paramName and - call.getArgument(arg).getExpr() = node.asExpr() and - flowstate = "String" // `String` length flowing into `NSString` + // match up `funcName`, `paramName`, `arg`, `node`. + funcDecl.getName() = funcName and + funcDecl.getParam(pragma[only_bind_into](arg)).getName() = paramName and + call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() ) } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + // allow flow through `+`, `-`, `*` etc. + node2.asExpr().(ArithmeticOperation).getAnOperand() = node1.asExpr() + } } from diff --git a/swift/ql/src/queries/placeholder.ql b/swift/ql/src/queries/placeholder.ql deleted file mode 100644 index 24a95c4899c..00000000000 --- a/swift/ql/src/queries/placeholder.ql +++ /dev/null @@ -1,9 +0,0 @@ -/** - * @kind problem - * @id swift/placeholder - */ - -import swift - -from IntegerLiteralExpr lit -select lit, "A literal" diff --git a/swift/ql/test/TestUtils.qll b/swift/ql/test/TestUtils.qll index 9bfff38db4f..265513b4f4a 100644 --- a/swift/ql/test/TestUtils.qll +++ b/swift/ql/test/TestUtils.qll @@ -4,18 +4,29 @@ cached predicate toBeTested(Element e) { e instanceof File or + exists(ModuleDecl m | + not m.isBuiltinModule() and + not m.isSystemModule() and + (m = e or m.getInterfaceType() = e) + ) + or exists(Locatable loc | loc.getLocation().getFile().getName().matches("%swift/ql/test%") and ( e = loc or - e = loc.(ValueDecl).getInterfaceType() - or - e = loc.(NominalTypeDecl).getType() - or - e = loc.(VarDecl).getType() - or - e = loc.(Expr).getType() + exists(Type t | + (e = t or e = t.(ExistentialType).getConstraint() or e = t.getCanonicalType()) and + ( + t = loc.(ValueDecl).getInterfaceType() + or + t = loc.(NominalTypeDecl).getType() + or + t = loc.(VarDecl).getType() + or + t = loc.(Expr).getType() + ) + ) ) ) } diff --git a/swift/ql/test/extractor-tests/expressions/all.expected b/swift/ql/test/extractor-tests/expressions/all.expected index 20951358f73..b34ca7349cd 100644 --- a/swift/ql/test/extractor-tests/expressions/all.expected +++ b/swift/ql/test/extractor-tests/expressions/all.expected @@ -123,8 +123,6 @@ | expressions.swift:54:1:54:1 | _ | DiscardAssignmentExpr | | expressions.swift:54:1:54:8 | ... = ... | AssignExpr | | expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr | -| expressions.swift:54:6:54:6 | (no string representation) | TypeExpr | -| expressions.swift:54:6:54:8 | ... .x | UnresolvedDotExpr | | expressions.swift:58:16:58:16 | 1234 | IntegerLiteralExpr | | expressions.swift:59:1:59:1 | unsafeFunction(pointer:) | DeclRefExpr | | expressions.swift:59:1:59:34 | call to unsafeFunction(pointer:) | CallExpr | @@ -242,5 +240,3 @@ | expressions.swift:154:22:154:56 | \\...[...] | KeyPathApplicationExpr | | expressions.swift:154:33:154:33 | keyPathB | DeclRefExpr | | expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr | -| expressions.swift:154:53:154:53 | (no string representation) | TypeExpr | -| expressions.swift:154:53:154:55 | ... .x | UnresolvedDotExpr | diff --git a/swift/ql/test/extractor-tests/generated/File/File.expected b/swift/ql/test/extractor-tests/generated/File/File.expected index d2ef49d491d..73437ea7a92 100644 --- a/swift/ql/test/extractor-tests/generated/File/File.expected +++ b/swift/ql/test/extractor-tests/generated/File/File.expected @@ -1,2 +1,3 @@ +| empty.swift:0:0:0:0 | empty.swift | getName: | empty.swift | | file://:0:0:0:0 | | getName: | | -| hello.swift:0:0:0:0 | hello.swift | getName: | hello.swift | +| non_empty.swift:0:0:0:0 | non_empty.swift | getName: | non_empty.swift | diff --git a/swift/ql/test/extractor-tests/generated/File/empty.swift b/swift/ql/test/extractor-tests/generated/File/empty.swift new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/File/non_empty.swift b/swift/ql/test/extractor-tests/generated/File/non_empty.swift new file mode 100644 index 00000000000..11b15b1a458 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/File/non_empty.swift @@ -0,0 +1 @@ +print("hello") diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.expected new file mode 100644 index 00000000000..f50475445e5 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.expected @@ -0,0 +1,7 @@ +| var_decls.swift:4:7:4:7 | i | getInterfaceType: | Int | getName: | i | getType: | Int | getIntroducerInt: | 1 | +| var_decls.swift:7:5:7:5 | numbers | getInterfaceType: | [Int] | getName: | numbers | getType: | [Int] | getIntroducerInt: | 1 | +| var_decls.swift:10:12:10:12 | numbers | getInterfaceType: | [Int] | getName: | numbers | getType: | [Int] | getIntroducerInt: | 0 | +| var_decls.swift:15:7:15:7 | wrappedValue | getInterfaceType: | T | getName: | wrappedValue | getType: | T | getIntroducerInt: | 1 | +| var_decls.swift:20:7:20:7 | wrappedValue | getInterfaceType: | Int | getName: | wrappedValue | getType: | Int | getIntroducerInt: | 1 | +| var_decls.swift:24:15:24:15 | _wrapped | getInterfaceType: | X | getName: | _wrapped | getType: | X | getIntroducerInt: | 1 | +| var_decls.swift:24:15:24:15 | wrapped | getInterfaceType: | Int | getName: | wrapped | getType: | Int | getIntroducerInt: | 1 | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.ql new file mode 100644 index 00000000000..55ae04af6ac --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.ql @@ -0,0 +1,14 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteVarDecl x, Type getInterfaceType, string getName, Type getType, int getIntroducerInt +where + toBeTested(x) and + not x.isUnknown() and + getInterfaceType = x.getInterfaceType() and + getName = x.getName() and + getType = x.getType() and + getIntroducerInt = x.getIntroducerInt() +select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType, + "getIntroducerInt:", getIntroducerInt diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected new file mode 100644 index 00000000000..cfbce6fe5ef --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected @@ -0,0 +1,13 @@ +| var_decls.swift:10:12:10:12 | numbers | 0 | var_decls.swift:10:12:10:12 | get | +| var_decls.swift:15:7:15:7 | wrappedValue | 0 | var_decls.swift:15:7:15:7 | get | +| var_decls.swift:15:7:15:7 | wrappedValue | 1 | var_decls.swift:15:7:15:7 | set | +| var_decls.swift:15:7:15:7 | wrappedValue | 2 | var_decls.swift:15:7:15:7 | (unnamed function decl) | +| var_decls.swift:20:7:20:7 | wrappedValue | 0 | var_decls.swift:20:7:20:7 | get | +| var_decls.swift:20:7:20:7 | wrappedValue | 1 | var_decls.swift:20:7:20:7 | set | +| var_decls.swift:20:7:20:7 | wrappedValue | 2 | var_decls.swift:20:7:20:7 | (unnamed function decl) | +| var_decls.swift:24:15:24:15 | _wrapped | 0 | var_decls.swift:24:15:24:15 | get | +| var_decls.swift:24:15:24:15 | _wrapped | 1 | var_decls.swift:24:15:24:15 | set | +| var_decls.swift:24:15:24:15 | _wrapped | 2 | var_decls.swift:24:15:24:15 | (unnamed function decl) | +| var_decls.swift:24:15:24:15 | wrapped | 0 | var_decls.swift:24:15:24:15 | get | +| var_decls.swift:24:15:24:15 | wrapped | 1 | var_decls.swift:24:15:24:15 | set | +| var_decls.swift:24:15:24:15 | wrapped | 2 | var_decls.swift:24:15:24:15 | (unnamed function decl) | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.ql new file mode 100644 index 00000000000..b25caf7bf97 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteVarDecl x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getAccessorDecl(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.expected new file mode 100644 index 00000000000..67bff5661b0 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.expected @@ -0,0 +1 @@ +| var_decls.swift:24:15:24:15 | wrapped | X | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.ql new file mode 100644 index 00000000000..569c25f0602 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteVarDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getAttachedPropertyWrapperType() diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.expected new file mode 100644 index 00000000000..786b16fcab1 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.expected @@ -0,0 +1,3 @@ +| var_decls.swift:4:7:4:7 | i | var_decls.swift:4:11:4:11 | 0 | +| var_decls.swift:7:5:7:5 | numbers | var_decls.swift:7:15:7:18 | [...] | +| var_decls.swift:10:12:10:12 | numbers | var_decls.swift:10:22:10:35 | [...] | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.ql new file mode 100644 index 00000000000..eddfa346732 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteVarDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getParentInitializer() diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.expected new file mode 100644 index 00000000000..8e15539394a --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.expected @@ -0,0 +1,7 @@ +| var_decls.swift:4:7:4:7 | i | var_decls.swift:4:7:4:7 | i | +| var_decls.swift:7:5:7:5 | numbers | var_decls.swift:7:5:7:5 | numbers | +| var_decls.swift:10:12:10:12 | numbers | var_decls.swift:10:12:10:12 | numbers | +| var_decls.swift:15:7:15:7 | wrappedValue | var_decls.swift:15:7:15:21 | ... as ... | +| var_decls.swift:20:7:20:7 | wrappedValue | var_decls.swift:20:7:20:21 | ... as ... | +| var_decls.swift:24:15:24:15 | _wrapped | var_decls.swift:24:15:24:15 | ... as ... | +| var_decls.swift:24:15:24:15 | wrapped | var_decls.swift:24:15:24:25 | ... as ... | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.ql new file mode 100644 index 00000000000..2aedb61e2ae --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteVarDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getParentPattern() diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/var_decls.swift b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/var_decls.swift new file mode 100644 index 00000000000..37c145a5a42 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/var_decls.swift @@ -0,0 +1,25 @@ +func loop() { + for i in 1...5 { + } + var i = 0 +} + +var numbers = [42] + +struct S { +static let numbers = [42, 404, 101] +} + +@propertyWrapper +struct X { + var wrappedValue: T +} + +@propertyWrapper +struct Y { + var wrappedValue: Int +} + +struct Wrapped { + @X @Y var wrapped : Int +} diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.expected b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.expected new file mode 100644 index 00000000000..d4230ce830c --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.expected @@ -0,0 +1,6 @@ +| if_config.swift:1:1:1:1 | IfConfigClause | isActive: | no | +| if_config.swift:4:1:4:1 | IfConfigClause | isActive: | no | +| if_config.swift:7:1:7:1 | IfConfigClause | isActive: | yes | +| if_config_active.swift:3:1:3:1 | IfConfigClause | isActive: | yes | +| if_config_active.swift:6:1:6:1 | IfConfigClause | isActive: | no | +| if_config_active.swift:9:1:9:1 | IfConfigClause | isActive: | no | diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.ql b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.ql new file mode 100644 index 00000000000..832025712f0 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.ql @@ -0,0 +1,10 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from IfConfigClause x, string isActive +where + toBeTested(x) and + not x.isUnknown() and + if x.isActive() then isActive = "yes" else isActive = "no" +select x, "isActive:", isActive diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.expected b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.expected new file mode 100644 index 00000000000..f4955665acd --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.expected @@ -0,0 +1,4 @@ +| if_config.swift:1:1:1:1 | IfConfigClause | if_config.swift:1:5:1:5 | FOO (unresolved) | +| if_config.swift:4:1:4:1 | IfConfigClause | if_config.swift:4:9:4:19 | call to ... | +| if_config_active.swift:3:1:3:1 | IfConfigClause | if_config_active.swift:3:5:3:5 | FOO (unresolved) | +| if_config_active.swift:6:1:6:1 | IfConfigClause | if_config_active.swift:6:9:6:17 | call to ... | diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.ql b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.ql new file mode 100644 index 00000000000..174c1a4994d --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from IfConfigClause x +where toBeTested(x) and not x.isUnknown() +select x, x.getCondition() diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.expected b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.expected new file mode 100644 index 00000000000..11dd2b54127 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.expected @@ -0,0 +1,18 @@ +| if_config.swift:1:1:1:1 | IfConfigClause | 0 | if_config.swift:2:1:2:16 | { ... } | +| if_config.swift:1:1:1:1 | IfConfigClause | 1 | if_config.swift:2:5:2:5 | foo | +| if_config.swift:1:1:1:1 | IfConfigClause | 2 | if_config.swift:3:1:3:12 | { ... } | +| if_config.swift:4:1:4:1 | IfConfigClause | 0 | if_config.swift:5:1:5:16 | { ... } | +| if_config.swift:4:1:4:1 | IfConfigClause | 1 | if_config.swift:5:5:5:5 | bar | +| if_config.swift:4:1:4:1 | IfConfigClause | 2 | if_config.swift:6:1:6:12 | { ... } | +| if_config.swift:7:1:7:1 | IfConfigClause | 0 | if_config.swift:8:1:8:16 | { ... } | +| if_config.swift:7:1:7:1 | IfConfigClause | 1 | if_config.swift:8:5:8:5 | baz | +| if_config.swift:7:1:7:1 | IfConfigClause | 2 | if_config.swift:9:1:9:12 | { ... } | +| if_config_active.swift:3:1:3:1 | IfConfigClause | 0 | if_config_active.swift:4:1:4:16 | { ... } | +| if_config_active.swift:3:1:3:1 | IfConfigClause | 1 | if_config_active.swift:4:5:4:5 | foo | +| if_config_active.swift:3:1:3:1 | IfConfigClause | 2 | if_config_active.swift:5:1:5:12 | { ... } | +| if_config_active.swift:6:1:6:1 | IfConfigClause | 0 | if_config_active.swift:7:1:7:16 | { ... } | +| if_config_active.swift:6:1:6:1 | IfConfigClause | 1 | if_config_active.swift:7:5:7:5 | bar | +| if_config_active.swift:6:1:6:1 | IfConfigClause | 2 | if_config_active.swift:8:1:8:12 | { ... } | +| if_config_active.swift:9:1:9:1 | IfConfigClause | 0 | if_config_active.swift:10:1:10:16 | { ... } | +| if_config_active.swift:9:1:9:1 | IfConfigClause | 1 | if_config_active.swift:10:5:10:5 | baz | +| if_config_active.swift:9:1:9:1 | IfConfigClause | 2 | if_config_active.swift:11:1:11:12 | { ... } | diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.ql b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.ql new file mode 100644 index 00000000000..02c0eec17c9 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from IfConfigClause x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getElement(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config.swift b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config.swift new file mode 100644 index 00000000000..87cbc8ecd42 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config.swift @@ -0,0 +1,10 @@ +#if FOO +var foo: Int = 1 +print("foo") +#elseif os(watchOS) +var bar: Int = 2 +print("bar") +#else +var baz: Int = 3 +print("baz") +#endif diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config_active.swift b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config_active.swift new file mode 100644 index 00000000000..89849731bfe --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config_active.swift @@ -0,0 +1,12 @@ +//codeql-extractor-options: -D FOO + +#if FOO +var foo: Int = 1 +print("foo") +#elseif os(macOS) +var bar: Int = 2 +print("bar") +#else +var baz: Int = 3 +print("baz") +#endif diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.expected b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.expected new file mode 100644 index 00000000000..3fed7a7fcc1 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.expected @@ -0,0 +1 @@ +| if_config.swift:1:1:10:1 | #if ... | diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.ql b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.ql new file mode 100644 index 00000000000..a43d57b1d93 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from IfConfigDecl x +where toBeTested(x) and not x.isUnknown() +select x diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.expected b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.expected new file mode 100644 index 00000000000..d90ba458397 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.expected @@ -0,0 +1,3 @@ +| if_config.swift:1:1:10:1 | #if ... | 0 | if_config.swift:1:1:1:1 | IfConfigClause | +| if_config.swift:1:1:10:1 | #if ... | 1 | if_config.swift:4:1:4:1 | IfConfigClause | +| if_config.swift:1:1:10:1 | #if ... | 2 | if_config.swift:7:1:7:1 | IfConfigClause | diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.ql b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.ql new file mode 100644 index 00000000000..5ffaf75e476 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from IfConfigDecl x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getClause(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/if_config.swift b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/if_config.swift new file mode 100644 index 00000000000..6f492013933 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/if_config.swift @@ -0,0 +1,10 @@ +#if FOO +var foo: Int = 1 +print("foo") +#elseif BAR +var bar: Int = 2 +print("bar") +#else +var baz: Int = 3 +print("baz") +#endif diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.expected new file mode 100644 index 00000000000..3e9fd295744 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.expected @@ -0,0 +1,5 @@ +| import.swift:1:1:1:8 | import ... | isExported: | no | getModule: | file://:0:0:0:0 | Swift | +| import.swift:2:1:2:24 | import ... | isExported: | no | getModule: | file://:0:0:0:0 | Swift | +| import.swift:3:12:3:32 | import ... | isExported: | yes | getModule: | file://:0:0:0:0 | Swift | +| import.swift:4:1:4:19 | import ... | isExported: | no | getModule: | file://:0:0:0:0 | Swift | +| import.swift:5:1:5:23 | import ... | isExported: | no | getModule: | file://:0:0:0:0 | Swift | diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.ql new file mode 100644 index 00000000000..34978aae118 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ImportDecl x, string isExported, ModuleDecl getModule +where + toBeTested(x) and + not x.isUnknown() and + (if x.isExported() then isExported = "yes" else isExported = "no") and + getModule = x.getModule() +select x, "isExported:", isExported, "getModule:", getModule diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.expected b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.expected new file mode 100644 index 00000000000..b877b113bc6 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.expected @@ -0,0 +1,5 @@ +| import.swift:2:1:2:24 | import ... | 0 | file://:0:0:0:0 | Int | +| import.swift:3:12:3:32 | import ... | 0 | file://:0:0:0:0 | Double | +| import.swift:4:1:4:19 | import ... | 0 | file://:0:0:0:0 | print(_:separator:terminator:) | +| import.swift:4:1:4:19 | import ... | 1 | file://:0:0:0:0 | print(_:separator:terminator:to:) | +| import.swift:5:1:5:23 | import ... | 0 | file://:0:0:0:0 | Hashable | diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.ql b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.ql new file mode 100644 index 00000000000..852fe518ed2 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ImportDecl x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getDeclaration(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/import.swift b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/import.swift new file mode 100644 index 00000000000..bcb562996ae --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/import.swift @@ -0,0 +1,5 @@ +import Swift +import typealias Swift.Int +@_exported import struct Swift.Double +import func Swift.print // imports all overloads +import protocol Swift.Hashable diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected new file mode 100644 index 00000000000..cfae187857a --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected @@ -0,0 +1,2 @@ +| file://:0:0:0:0 | Foo | getInterfaceType: | module | getName: | Foo | isBuiltinModule: | no | isSystemModule: | no | +| file://:0:0:0:0 | default_module_name | getInterfaceType: | module | getName: | default_module_name | isBuiltinModule: | no | isSystemModule: | no | diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.ql new file mode 100644 index 00000000000..73e912a8245 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.ql @@ -0,0 +1,15 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from + ModuleDecl x, Type getInterfaceType, string getName, string isBuiltinModule, string isSystemModule +where + toBeTested(x) and + not x.isUnknown() and + getInterfaceType = x.getInterfaceType() and + getName = x.getName() and + (if x.isBuiltinModule() then isBuiltinModule = "yes" else isBuiltinModule = "no") and + if x.isSystemModule() then isSystemModule = "yes" else isSystemModule = "no" +select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "isBuiltinModule:", + isBuiltinModule, "isSystemModule:", isSystemModule diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.expected b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.ql b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.ql new file mode 100644 index 00000000000..0c0cec75d86 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ModuleDecl x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getBaseType(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/default_module_name.swift b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/default_module_name.swift new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/modules.swift b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/modules.swift new file mode 100644 index 00000000000..bb12ed63ddd --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/modules.swift @@ -0,0 +1 @@ +//codeql-extractor-options: -module-name Foo diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.expected new file mode 100644 index 00000000000..8f559769407 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.expected @@ -0,0 +1,15 @@ +| param_decls.swift:1:10:1:13 | _ | getInterfaceType: | Int | getName: | _ | getType: | Int | isInout: | no | +| param_decls.swift:1:18:1:29 | y | getInterfaceType: | Double | getName: | y | getType: | Double | isInout: | yes | +| param_decls.swift:2:10:2:13 | _ | getInterfaceType: | Int | getName: | _ | getType: | Int | isInout: | no | +| param_decls.swift:2:18:2:29 | y | getInterfaceType: | Double | getName: | y | getType: | Double | isInout: | yes | +| param_decls.swift:5:5:5:5 | self | getInterfaceType: | S | getName: | self | getType: | S | isInout: | yes | +| param_decls.swift:5:15:5:15 | x | getInterfaceType: | Int | getName: | x | getType: | Int | isInout: | no | +| param_decls.swift:5:15:5:15 | x | getInterfaceType: | Int | getName: | x | getType: | Int | isInout: | no | +| param_decls.swift:5:15:5:18 | x | getInterfaceType: | Int | getName: | x | getType: | Int | isInout: | no | +| param_decls.swift:5:23:5:23 | y | getInterfaceType: | Int | getName: | y | getType: | Int | isInout: | no | +| param_decls.swift:5:23:5:23 | y | getInterfaceType: | Int | getName: | y | getType: | Int | isInout: | no | +| param_decls.swift:5:23:5:26 | y | getInterfaceType: | Int | getName: | y | getType: | Int | isInout: | no | +| param_decls.swift:7:9:7:9 | newValue | getInterfaceType: | Int? | getName: | newValue | getType: | Int? | isInout: | no | +| param_decls.swift:12:13:12:22 | s | getInterfaceType: | String | getName: | s | getType: | String | isInout: | yes | +| param_decls.swift:13:13:13:22 | s | getInterfaceType: | String | getName: | s | getType: | String | isInout: | yes | +| param_decls.swift:14:26:14:26 | $0 | getInterfaceType: | Int | getName: | $0 | getType: | Int | isInout: | no | diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.ql new file mode 100644 index 00000000000..acf3614b7b0 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.ql @@ -0,0 +1,14 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ParamDecl x, Type getInterfaceType, string getName, Type getType, string isInout +where + toBeTested(x) and + not x.isUnknown() and + getInterfaceType = x.getInterfaceType() and + getName = x.getName() and + getType = x.getType() and + if x.isInout() then isInout = "yes" else isInout = "no" +select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType, + "isInout:", isInout diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.ql new file mode 100644 index 00000000000..a751e0006cc --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ParamDecl x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getAccessorDecl(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.expected b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.ql b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.ql new file mode 100644 index 00000000000..0e71fb1cf26 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ParamDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getAttachedPropertyWrapperType() diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.expected b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.ql b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.ql new file mode 100644 index 00000000000..39f7e9e1b6e --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ParamDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getParentInitializer() diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.expected b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.ql b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.ql new file mode 100644 index 00000000000..17b5a06c1d5 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ParamDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getParentPattern() diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/param_decls.swift b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/param_decls.swift new file mode 100644 index 00000000000..72b47ed2c60 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/param_decls.swift @@ -0,0 +1,15 @@ +func foo(_: Int, x y: inout Double) {} +func bar(_: Int, x y: inout Double) {} + +struct S { + subscript(x: Int, y: Int) -> Int? { + get { nil } + set {} + } +} + +func closures() { + let x = {(s: inout String) -> String in s} + let y = {(s: inout String) -> String in ""} + let z : (Int) -> Int = { $0 + 1 } +} diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.expected b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.expected new file mode 100644 index 00000000000..d9f729ea4ac --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.expected @@ -0,0 +1,2 @@ +| dot_syntax_call.swift:6:1:6:3 | call to foo(_:_:) | getFunction: | dot_syntax_call.swift:6:3:6:3 | foo(_:_:) | getBaseExpr: | dot_syntax_call.swift:6:1:6:1 | X.Type | +| dot_syntax_call.swift:7:1:7:3 | call to bar() | getFunction: | dot_syntax_call.swift:7:3:7:3 | bar() | getBaseExpr: | dot_syntax_call.swift:7:1:7:1 | X.Type | diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.ql b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.ql new file mode 100644 index 00000000000..d4fce9de8bc --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from DotSyntaxCallExpr x, Expr getFunction, Expr getBaseExpr +where + toBeTested(x) and + not x.isUnknown() and + getFunction = x.getFunction() and + getBaseExpr = x.getBaseExpr() +select x, "getFunction:", getFunction, "getBaseExpr:", getBaseExpr diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected new file mode 100644 index 00000000000..85102771b48 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected @@ -0,0 +1,2 @@ +| dot_syntax_call.swift:6:1:6:3 | call to foo(_:_:) | 0 | dot_syntax_call.swift:6:1:6:1 | : X.Type | +| dot_syntax_call.swift:7:1:7:3 | call to bar() | 0 | dot_syntax_call.swift:7:1:7:1 | : X.Type | diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.ql b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.ql new file mode 100644 index 00000000000..384f99edb51 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from DotSyntaxCallExpr x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getArgument(index) diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.expected new file mode 100644 index 00000000000..f59178625cf --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.expected @@ -0,0 +1,2 @@ +| dot_syntax_call.swift:6:1:6:3 | call to foo(_:_:) | (Int, Int) -> () | +| dot_syntax_call.swift:7:1:7:3 | call to bar() | () -> () | diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.ql b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.ql similarity index 85% rename from swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.ql rename to swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.ql index f91cc957ef7..b7711a5d67c 100644 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.ql +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.ql @@ -2,6 +2,6 @@ import codeql.swift.elements import TestUtils -from UnresolvedDotExpr x +from DotSyntaxCallExpr x where toBeTested(x) and not x.isUnknown() select x, x.getType() diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/dot_syntax_call.swift b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/dot_syntax_call.swift new file mode 100644 index 00000000000..f8b97e23898 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/dot_syntax_call.swift @@ -0,0 +1,7 @@ +class X { + static func foo(_: Int, _:Int) {} + class func bar() {} +} + +X.foo(1, 2) +X.bar() diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected new file mode 100644 index 00000000000..6076a256058 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected @@ -0,0 +1,10 @@ +| enum_is_case.swift:4:1:4:17 | ... is some | getSubExpr: | enum_is_case.swift:4:1:4:17 | OptionalEvaluationExpr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:5:1:5:32 | ... is some | getSubExpr: | enum_is_case.swift:5:1:5:32 | OptionalEvaluationExpr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:6:1:6:1 | ... is some | getSubExpr: | enum_is_case.swift:6:1:6:1 | 42 | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:7:1:7:1 | ... is some | getSubExpr: | enum_is_case.swift:7:1:7:1 | 42 | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:9:1:9:19 | ... is some | getSubExpr: | enum_is_case.swift:9:1:9:19 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:19:1:19:18 | ... is some | getSubExpr: | enum_is_case.swift:19:1:19:18 | OptionalEvaluationExpr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:21:1:21:5 | ... is some | getSubExpr: | enum_is_case.swift:21:1:21:5 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:22:1:22:10 | ... is some | getSubExpr: | enum_is_case.swift:22:1:22:10 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:23:1:23:10 | ... is some | getSubExpr: | enum_is_case.swift:23:1:23:10 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:24:1:24:8 | ... is some | getSubExpr: | enum_is_case.swift:24:1:24:8 | call to ... | getElement: | file://:0:0:0:0 | some | diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql new file mode 100644 index 00000000000..9c3340d4ff5 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from EnumIsCaseExpr x, Expr getSubExpr, EnumElementDecl getElement +where + toBeTested(x) and + not x.isUnknown() and + getSubExpr = x.getSubExpr() and + getElement = x.getElement() +select x, "getSubExpr:", getSubExpr, "getElement:", getElement diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected new file mode 100644 index 00000000000..f1a8bd34fda --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected @@ -0,0 +1,10 @@ +| enum_is_case.swift:4:1:4:17 | ... is some | Bool | +| enum_is_case.swift:5:1:5:32 | ... is some | Bool | +| enum_is_case.swift:6:1:6:1 | ... is some | Bool | +| enum_is_case.swift:7:1:7:1 | ... is some | Bool | +| enum_is_case.swift:9:1:9:19 | ... is some | Bool | +| enum_is_case.swift:19:1:19:18 | ... is some | Bool | +| enum_is_case.swift:21:1:21:5 | ... is some | Bool | +| enum_is_case.swift:22:1:22:10 | ... is some | Bool | +| enum_is_case.swift:23:1:23:10 | ... is some | Bool | +| enum_is_case.swift:24:1:24:8 | ... is some | Bool | diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.ql b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.ql new file mode 100644 index 00000000000..b8d841b545c --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from EnumIsCaseExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getType() diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift new file mode 100644 index 00000000000..f33edd6c0c7 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift @@ -0,0 +1,24 @@ +// EnumIsCaseExpr despite its generic nature is actually only generated when an `is` expression passes through an +// intrinsic Optional check, or an array, dictionary or set downcast + +Optional.some(42) is Int +Optional.some(Optional.some(42)) is Int +42 is Int? +42 is Int?? + +[Optional.some(42)] is [Int] +[42] is [Int?] + +class X : Hashable { + static func == (lhs: X, rhs: X) -> Bool { return true } + func hash(into hasher: inout Hasher) {} +} + +class Y: X {} + +Optional.some(Y()) is X + +[X()] is [Y] +["x": X()] is [String: Y] +["x": X()] is [String: Y] +Set() is Set diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.expected new file mode 100644 index 00000000000..ecf2a57ba5d --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.expected @@ -0,0 +1,10 @@ +| unresolved_decl_ref.swift:4:5:4:5 | FOO (unresolved) | +| unresolved_decl_ref.swift:4:9:4:9 | && (unresolved) | +| unresolved_decl_ref.swift:4:12:4:12 | os (unresolved) | +| unresolved_decl_ref.swift:4:15:4:15 | Windows (unresolved) | +| unresolved_decl_ref.swift:5:1:5:1 | print (unresolved) | +| unresolved_decl_ref.swift:6:9:6:9 | BAR (unresolved) | +| unresolved_decl_ref.swift:6:13:6:13 | \|\| (unresolved) | +| unresolved_decl_ref.swift:6:16:6:16 | arch (unresolved) | +| unresolved_decl_ref.swift:6:21:6:21 | i386 (unresolved) | +| unresolved_decl_ref.swift:9:1:9:1 | print (unresolved) | diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.ql new file mode 100644 index 00000000000..507d2fcf87d --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedDeclRefExpr x +where toBeTested(x) and not x.isUnknown() +select x diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.expected new file mode 100644 index 00000000000..1ea60aabedc --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.expected @@ -0,0 +1,10 @@ +| unresolved_decl_ref.swift:4:5:4:5 | FOO (unresolved) | FOO | +| unresolved_decl_ref.swift:4:9:4:9 | && (unresolved) | && | +| unresolved_decl_ref.swift:4:12:4:12 | os (unresolved) | os | +| unresolved_decl_ref.swift:4:15:4:15 | Windows (unresolved) | Windows | +| unresolved_decl_ref.swift:5:1:5:1 | print (unresolved) | print | +| unresolved_decl_ref.swift:6:9:6:9 | BAR (unresolved) | BAR | +| unresolved_decl_ref.swift:6:13:6:13 | \|\| (unresolved) | \|\| | +| unresolved_decl_ref.swift:6:16:6:16 | arch (unresolved) | arch | +| unresolved_decl_ref.swift:6:21:6:21 | i386 (unresolved) | i386 | +| unresolved_decl_ref.swift:9:1:9:1 | print (unresolved) | print | diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.ql new file mode 100644 index 00000000000..1424e3443d9 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedDeclRefExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getName() diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.ql new file mode 100644 index 00000000000..27953cceeb1 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedDeclRefExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getType() diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/unresolved_decl_ref.swift b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/unresolved_decl_ref.swift new file mode 100644 index 00000000000..94dee19d618 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/unresolved_decl_ref.swift @@ -0,0 +1,10 @@ +//codeql-extractor-options: -D BAR + +// conditions and inactive branches in conditional compilation blocks are not resolved +#if FOO && os(Windows) +print(1) +#elseif BAR || arch(i386) +print(2) +#else +print(3) +#endif diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/MISSING_SOURCE.txt similarity index 100% rename from swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/MISSING_SOURCE.txt rename to swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/MISSING_SOURCE.txt diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.expected deleted file mode 100644 index 2bb615eb361..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.expected +++ /dev/null @@ -1,3 +0,0 @@ -| unresolved_dot_expr.swift:5:6:5:8 | ... .x | getBase: | unresolved_dot_expr.swift:5:6:5:6 | (no string representation) | getName: | x | -| unresolved_dot_expr.swift:11:6:11:8 | ... .a | getBase: | unresolved_dot_expr.swift:11:6:11:6 | (no string representation) | getName: | a | -| unresolved_dot_expr.swift:11:6:11:10 | ... .x | getBase: | unresolved_dot_expr.swift:11:6:11:8 | ... .a | getName: | x | diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql deleted file mode 100644 index 29327a3f86c..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql +++ /dev/null @@ -1,11 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from UnresolvedDotExpr x, Expr getBase, string getName -where - toBeTested(x) and - not x.isUnknown() and - getBase = x.getBase() and - getName = x.getName() -select x, "getBase:", getBase, "getName:", getName diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/unresolved_dot_expr.swift b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/unresolved_dot_expr.swift deleted file mode 100644 index 3003e6efe82..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/unresolved_dot_expr.swift +++ /dev/null @@ -1,11 +0,0 @@ -struct A { - var x: Int = 42 -} - -_ = \A.x - -struct B { - var a: A -} - -_ = \B.a.x diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.expected new file mode 100644 index 00000000000..3f348092bdb --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.expected @@ -0,0 +1 @@ +| unresolved_pattern_expr.swift:2:19:2:19 | UnresolvedPatternExpr | getSubPattern: | unresolved_pattern_expr.swift:2:19:2:19 | x | diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.ql new file mode 100644 index 00000000000..9a5f8e54490 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.ql @@ -0,0 +1,10 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedPatternExpr x, Pattern getSubPattern +where + toBeTested(x) and + not x.isUnknown() and + getSubPattern = x.getSubPattern() +select x, "getSubPattern:", getSubPattern diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.ql new file mode 100644 index 00000000000..af57d0129a1 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedPatternExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getType() diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/unresolved_pattern_expr.swift b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/unresolved_pattern_expr.swift new file mode 100644 index 00000000000..2ca1bbb7c24 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/unresolved_pattern_expr.swift @@ -0,0 +1,5 @@ +#if FOO +if case let .some(x) = 42 { + print(x) +} +#endif diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinBridgeObjectType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinBridgeObjectType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinBridgeObjectType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinDefaultActorStorageType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinDefaultActorStorageType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinDefaultActorStorageType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinExecutorType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinExecutorType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinExecutorType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinFloatType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinFloatType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinFloatType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerLiteralType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerLiteralType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerLiteralType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected new file mode 100644 index 00000000000..410b13be428 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected @@ -0,0 +1,5 @@ +| Builtin.Int8 | getName: | Builtin.Int8 | getCanonicalType: | Builtin.Int8 | +| Builtin.Int16 | getName: | Builtin.Int16 | getCanonicalType: | Builtin.Int16 | +| Builtin.Int32 | getName: | Builtin.Int32 | getCanonicalType: | Builtin.Int32 | +| Builtin.Int64 | getName: | Builtin.Int64 | getCanonicalType: | Builtin.Int64 | +| Builtin.Word | getName: | Builtin.Word | getCanonicalType: | Builtin.Word | diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql new file mode 100644 index 00000000000..05131e5b9fd --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from BuiltinIntegerType x, string getName, Type getCanonicalType +where + toBeTested(x) and + not x.isUnknown() and + getName = x.getName() and + getCanonicalType = x.getCanonicalType() +select x, "getName:", getName, "getCanonicalType:", getCanonicalType diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.expected b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.expected new file mode 100644 index 00000000000..350ab9ee53a --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.expected @@ -0,0 +1,4 @@ +| Builtin.Int8 | 8 | +| Builtin.Int16 | 16 | +| Builtin.Int32 | 32 | +| Builtin.Int64 | 64 | diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.ql b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.ql new file mode 100644 index 00000000000..ebe05b7b0cb --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from BuiltinIntegerType x +where toBeTested(x) and not x.isUnknown() +select x, x.getWidth() diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/builtin_integer_types.swift b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/builtin_integer_types.swift new file mode 100644 index 00000000000..66c832a5ebc --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/builtin_integer_types.swift @@ -0,0 +1,8 @@ +//codeql-extractor-options: -parse-stdlib +func foo( + _: Builtin.Int8, + _: Builtin.Int16, + _: Builtin.Int32, + _: Builtin.Int64, + _: Builtin.Word +) {} diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinJobType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinJobType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinJobType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinNativeObjectType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinNativeObjectType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinNativeObjectType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinRawPointerType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinRawPointerType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinRawPointerType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinRawUnsafeContinuationType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinRawUnsafeContinuationType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinRawUnsafeContinuationType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected new file mode 100644 index 00000000000..5df760136c3 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected @@ -0,0 +1,11 @@ +| Builtin.BridgeObject | getName: | Builtin.BridgeObject | getCanonicalType: | Builtin.BridgeObject | +| Builtin.DefaultActorStorage | getName: | Builtin.DefaultActorStorage | getCanonicalType: | Builtin.DefaultActorStorage | +| Builtin.Executor | getName: | Builtin.Executor | getCanonicalType: | Builtin.Executor | +| Builtin.FPIEEE32 | getName: | Builtin.FPIEEE32 | getCanonicalType: | Builtin.FPIEEE32 | +| Builtin.FPIEEE64 | getName: | Builtin.FPIEEE64 | getCanonicalType: | Builtin.FPIEEE64 | +| Builtin.IntLiteral | getName: | Builtin.IntLiteral | getCanonicalType: | Builtin.IntLiteral | +| Builtin.Job | getName: | Builtin.Job | getCanonicalType: | Builtin.Job | +| Builtin.NativeObject | getName: | Builtin.NativeObject | getCanonicalType: | Builtin.NativeObject | +| Builtin.RawPointer | getName: | Builtin.RawPointer | getCanonicalType: | Builtin.RawPointer | +| Builtin.RawUnsafeContinuation | getName: | Builtin.RawUnsafeContinuation | getCanonicalType: | Builtin.RawUnsafeContinuation | +| Builtin.UnsafeValueBuffer | getName: | Builtin.UnsafeValueBuffer | getCanonicalType: | Builtin.UnsafeValueBuffer | diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql new file mode 100644 index 00000000000..d6b019a4a6d --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from BuiltinType x, string getName, Type getCanonicalType +where + toBeTested(x) and + not x.isUnknown() and + getName = x.getName() and + getCanonicalType = x.getCanonicalType() +select x, "getName:", getName, "getCanonicalType:", getCanonicalType diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinType/builtin_types.swift b/swift/ql/test/extractor-tests/generated/type/BuiltinType/builtin_types.swift new file mode 100644 index 00000000000..671a1b8eca7 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinType/builtin_types.swift @@ -0,0 +1,14 @@ +//codeql-extractor-options: -parse-stdlib +func foo( + _: Builtin.IntLiteral, + _: Builtin.FPIEEE32, + _: Builtin.FPIEEE64, + _: Builtin.BridgeObject, + _: Builtin.DefaultActorStorage, + _: Builtin.Executor, + _: Builtin.Job, + _: Builtin.NativeObject, + _: Builtin.RawPointer, + _: Builtin.RawUnsafeContinuation, + _: Builtin.UnsafeValueBuffer +) {} diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinUnsafeValueBufferType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinUnsafeValueBufferType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinUnsafeValueBufferType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinVectorType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinVectorType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinVectorType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.expected b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.expected index 833a3098c1f..6e36cc0e55f 100644 --- a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.expected +++ b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.expected @@ -1 +1 @@ -| Self | getDiagnosticsName: | Self | getCanonicalType: | Self | getStaticSelfType: | X | +| Self | getName: | Self | getCanonicalType: | Self | getStaticSelfType: | X | diff --git a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql index a9ae23f6bab..24168993ef3 100644 --- a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql +++ b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from DynamicSelfType x, string getDiagnosticsName, Type getCanonicalType, Type getStaticSelfType +from DynamicSelfType x, string getName, Type getCanonicalType, Type getStaticSelfType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getStaticSelfType = x.getStaticSelfType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getStaticSelfType:", getStaticSelfType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getStaticSelfType:", + getStaticSelfType diff --git a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected index 30cd19ebd4e..39ad24b358b 100644 --- a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected +++ b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected @@ -1,2 +1,3 @@ -| ExplicitExistential | getDiagnosticsName: | ExplicitExistential | getCanonicalType: | ExplicitExistential | getConstraint: | ExplicitExistential | -| ImplicitExistential | getDiagnosticsName: | ImplicitExistential | getCanonicalType: | ImplicitExistential | getConstraint: | ImplicitExistential | +| ExplicitExistential | getName: | ExplicitExistential | getCanonicalType: | ExplicitExistential | getConstraint: | ExplicitExistential | +| ImplicitExistential | getName: | ImplicitExistential | getCanonicalType: | ImplicitExistential | getConstraint: | ImplicitExistential | +| P1 & P2 | getName: | P1 & P2 | getCanonicalType: | P1 & P2 | getConstraint: | P1 & P2 | diff --git a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql index b679d5d89a2..70fd9f1ea2b 100644 --- a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql +++ b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from ExistentialType x, string getDiagnosticsName, Type getCanonicalType, Type getConstraint +from ExistentialType x, string getName, Type getCanonicalType, Type getConstraint where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getConstraint = x.getConstraint() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getConstraint:", getConstraint +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getConstraint:", + getConstraint diff --git a/swift/ql/test/extractor-tests/generated/type/ExistentialType/existential_types.swift b/swift/ql/test/extractor-tests/generated/type/ExistentialType/existential_types.swift index ade646efc74..8fad6cce47a 100644 --- a/swift/ql/test/extractor-tests/generated/type/ExistentialType/existential_types.swift +++ b/swift/ql/test/extractor-tests/generated/type/ExistentialType/existential_types.swift @@ -1,5 +1,8 @@ protocol ExplicitExistential {} protocol ImplicitExistential {} +protocol P1 {} +protocol P2 {} func foo1(_: any ExplicitExistential) {} func foo2(_: ImplicitExistential) {} // valid for now, will be an error in some future swift release +func foo3(_: any P1 & P2) {} diff --git a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.expected b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.expected index b227fccd42b..a9d0e530015 100644 --- a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.expected +++ b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.expected @@ -1,2 +1,2 @@ -| inout Int | getDiagnosticsName: | inout Int | getCanonicalType: | inout Int | getObjectType: | Int | -| inout S | getDiagnosticsName: | inout S | getCanonicalType: | inout S | getObjectType: | S | +| inout Int | getName: | inout Int | getCanonicalType: | inout Int | getObjectType: | Int | +| inout S | getName: | inout S | getCanonicalType: | inout S | getObjectType: | S | diff --git a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql index 973d0257381..1120208101d 100644 --- a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql +++ b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from InOutType x, string getDiagnosticsName, Type getCanonicalType, Type getObjectType +from InOutType x, string getName, Type getCanonicalType, Type getObjectType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getObjectType = x.getObjectType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getObjectType:", getObjectType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getObjectType:", + getObjectType diff --git a/swift/ql/test/extractor-tests/generated/type/InOutType/in_out.swift b/swift/ql/test/extractor-tests/generated/type/InOutType/in_out.swift index ae15ad1b884..54bf9be192d 100644 --- a/swift/ql/test/extractor-tests/generated/type/InOutType/in_out.swift +++ b/swift/ql/test/extractor-tests/generated/type/InOutType/in_out.swift @@ -8,5 +8,5 @@ struct S { mutating func bar() {} } -var s: S +var s: S = S() s.bar() diff --git a/swift/ql/test/extractor-tests/generated/type/ModuleType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/ModuleType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/ModuleType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.expected b/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.expected new file mode 100644 index 00000000000..3a688c7fbd6 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.expected @@ -0,0 +1,2 @@ +| module | getName: | module | getCanonicalType: | module | getModule: | file://:0:0:0:0 | Foo | +| module | getName: | module | getCanonicalType: | module | getModule: | file://:0:0:0:0 | default_module_name | diff --git a/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.ql b/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.ql new file mode 100644 index 00000000000..aa070b52e34 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.ql @@ -0,0 +1,12 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ModuleType x, string getName, Type getCanonicalType, ModuleDecl getModule +where + toBeTested(x) and + not x.isUnknown() and + getName = x.getName() and + getCanonicalType = x.getCanonicalType() and + getModule = x.getModule() +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getModule:", getModule diff --git a/swift/ql/test/extractor-tests/generated/type/ModuleType/default_module_name.swift b/swift/ql/test/extractor-tests/generated/type/ModuleType/default_module_name.swift new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/type/ModuleType/modules.swift b/swift/ql/test/extractor-tests/generated/type/ModuleType/modules.swift new file mode 100644 index 00000000000..bb12ed63ddd --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ModuleType/modules.swift @@ -0,0 +1 @@ +//codeql-extractor-options: -module-name Foo diff --git a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.expected b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.expected index 30f113c662f..0575e43769c 100644 --- a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.expected +++ b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.expected @@ -1,4 +1,4 @@ -| Impl1.Associated | getDiagnosticsName: | Impl1.Associated | getCanonicalType: | Impl1.Associated | getName: | Associated | getInterfaceType: | Impl1.Associated | getParent: | Impl1 | getAssociatedTypeDeclaration: | nested_archetypes.swift:2:5:2:20 | Associated | -| Impl2.AssociatedWithProtocols | getDiagnosticsName: | Impl2.AssociatedWithProtocols | getCanonicalType: | Impl2.AssociatedWithProtocols | getName: | AssociatedWithProtocols | getInterfaceType: | Impl2.AssociatedWithProtocols | getParent: | Impl2 | getAssociatedTypeDeclaration: | nested_archetypes.swift:6:5:6:57 | AssociatedWithProtocols | -| Impl3.AssociatedWithSuperclass | getDiagnosticsName: | Impl3.AssociatedWithSuperclass | getCanonicalType: | Impl3.AssociatedWithSuperclass | getName: | AssociatedWithSuperclass | getInterfaceType: | Impl3.AssociatedWithSuperclass | getParent: | Impl3 | getAssociatedTypeDeclaration: | nested_archetypes.swift:12:5:12:47 | AssociatedWithSuperclass | -| Impl4.AssociatedWithSuperclassAndProtocols | getDiagnosticsName: | Impl4.AssociatedWithSuperclassAndProtocols | getCanonicalType: | Impl4.AssociatedWithSuperclassAndProtocols | getName: | AssociatedWithSuperclassAndProtocols | getInterfaceType: | Impl4.AssociatedWithSuperclassAndProtocols | getParent: | Impl4 | getAssociatedTypeDeclaration: | nested_archetypes.swift:16:5:16:73 | AssociatedWithSuperclassAndProtocols | +| Impl1.Associated | getName: | Impl1.Associated | getCanonicalType: | Impl1.Associated | getInterfaceType: | Impl1.Associated | getParent: | Impl1 | getAssociatedTypeDeclaration: | nested_archetypes.swift:2:5:2:20 | Associated | +| Impl2.AssociatedWithProtocols | getName: | Impl2.AssociatedWithProtocols | getCanonicalType: | Impl2.AssociatedWithProtocols | getInterfaceType: | Impl2.AssociatedWithProtocols | getParent: | Impl2 | getAssociatedTypeDeclaration: | nested_archetypes.swift:6:5:6:57 | AssociatedWithProtocols | +| Impl3.AssociatedWithSuperclass | getName: | Impl3.AssociatedWithSuperclass | getCanonicalType: | Impl3.AssociatedWithSuperclass | getInterfaceType: | Impl3.AssociatedWithSuperclass | getParent: | Impl3 | getAssociatedTypeDeclaration: | nested_archetypes.swift:12:5:12:47 | AssociatedWithSuperclass | +| Impl4.AssociatedWithSuperclassAndProtocols | getName: | Impl4.AssociatedWithSuperclassAndProtocols | getCanonicalType: | Impl4.AssociatedWithSuperclassAndProtocols | getInterfaceType: | Impl4.AssociatedWithSuperclassAndProtocols | getParent: | Impl4 | getAssociatedTypeDeclaration: | nested_archetypes.swift:16:5:16:73 | AssociatedWithSuperclassAndProtocols | diff --git a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql index 8306bfeacac..b74c0e43099 100644 --- a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql +++ b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql @@ -3,17 +3,16 @@ import codeql.swift.elements import TestUtils from - NestedArchetypeType x, string getDiagnosticsName, Type getCanonicalType, string getName, - Type getInterfaceType, ArchetypeType getParent, AssociatedTypeDecl getAssociatedTypeDeclaration + NestedArchetypeType x, string getName, Type getCanonicalType, Type getInterfaceType, + ArchetypeType getParent, AssociatedTypeDecl getAssociatedTypeDeclaration where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and - getCanonicalType = x.getCanonicalType() and getName = x.getName() and + getCanonicalType = x.getCanonicalType() and getInterfaceType = x.getInterfaceType() and getParent = x.getParent() and getAssociatedTypeDeclaration = x.getAssociatedTypeDeclaration() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getName:", getName, "getInterfaceType:", getInterfaceType, "getParent:", getParent, - "getAssociatedTypeDeclaration:", getAssociatedTypeDeclaration +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getInterfaceType:", + getInterfaceType, "getParent:", getParent, "getAssociatedTypeDeclaration:", + getAssociatedTypeDeclaration diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.expected b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.expected new file mode 100644 index 00000000000..f6c15bca419 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.expected @@ -0,0 +1 @@ +| C & P1 & P2 | getName: | C & P1 & P2 | getCanonicalType: | C & P1 & P2 | getInterfaceType: | \u03c4_0_0 | diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.ql b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.ql new file mode 100644 index 00000000000..b558c08f666 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.ql @@ -0,0 +1,13 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from OpenedArchetypeType x, string getName, Type getCanonicalType, Type getInterfaceType +where + toBeTested(x) and + not x.isUnknown() and + getName = x.getName() and + getCanonicalType = x.getCanonicalType() and + getInterfaceType = x.getInterfaceType() +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getInterfaceType:", + getInterfaceType diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.expected b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.expected new file mode 100644 index 00000000000..5899ea9308a --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.expected @@ -0,0 +1,2 @@ +| C & P1 & P2 | 0 | opened_archetypes.swift:3:1:3:14 | P1 | +| C & P1 & P2 | 1 | opened_archetypes.swift:9:1:9:14 | P2 | diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.ql b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.ql new file mode 100644 index 00000000000..58fed5dda7b --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from OpenedArchetypeType x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getProtocol(index) diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.expected b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.expected new file mode 100644 index 00000000000..be1cb7dcb05 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.expected @@ -0,0 +1 @@ +| C & P1 & P2 | C | diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.ql b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.ql new file mode 100644 index 00000000000..46f00a08c88 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from OpenedArchetypeType x +where toBeTested(x) and not x.isUnknown() +select x, x.getSuperclass() diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/opened_archetypes.swift b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/opened_archetypes.swift new file mode 100644 index 00000000000..93d58b6163f --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/opened_archetypes.swift @@ -0,0 +1,25 @@ +// code inspired by https://github.com/apple/swift-evolution/blob/main/proposals/0352-implicit-open-existentials.md + +protocol P1 {} + +func isFoo(_: T) -> Bool { + return true +} + +protocol P2 {} + +class C {} + +// will be ok with swift 5.7 +// func test(value: any P1 & P2 & C) -> Bool { return isFoo(value) } + +extension P1 { + var isFooMember: Bool { + isFoo(self) + } +} + + +func testMember(value: any P1 & P2 & C) -> Bool { + return value.isFooMember // here the existential type is implicitly "opened" +} diff --git a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.expected b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.expected index 47d540c489a..c29242f0b27 100644 --- a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.expected +++ b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.expected @@ -1,4 +1,4 @@ -| Param | getDiagnosticsName: | Param | getCanonicalType: | Param | getName: | Param | getInterfaceType: | Param | -| ParamWithProtocols | getDiagnosticsName: | ParamWithProtocols | getCanonicalType: | ParamWithProtocols | getName: | ParamWithProtocols | getInterfaceType: | ParamWithProtocols | -| ParamWithSuperclass | getDiagnosticsName: | ParamWithSuperclass | getCanonicalType: | ParamWithSuperclass | getName: | ParamWithSuperclass | getInterfaceType: | ParamWithSuperclass | -| ParamWithSuperclassAndProtocols | getDiagnosticsName: | ParamWithSuperclassAndProtocols | getCanonicalType: | ParamWithSuperclassAndProtocols | getName: | ParamWithSuperclassAndProtocols | getInterfaceType: | ParamWithSuperclassAndProtocols | +| Param | getName: | Param | getCanonicalType: | Param | getInterfaceType: | Param | +| ParamWithProtocols | getName: | ParamWithProtocols | getCanonicalType: | ParamWithProtocols | getInterfaceType: | ParamWithProtocols | +| ParamWithSuperclass | getName: | ParamWithSuperclass | getCanonicalType: | ParamWithSuperclass | getInterfaceType: | ParamWithSuperclass | +| ParamWithSuperclassAndProtocols | getName: | ParamWithSuperclassAndProtocols | getCanonicalType: | ParamWithSuperclassAndProtocols | getInterfaceType: | ParamWithSuperclassAndProtocols | diff --git a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql index 925bf85dcbf..32cb2204418 100644 --- a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql +++ b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql @@ -2,15 +2,12 @@ import codeql.swift.elements import TestUtils -from - PrimaryArchetypeType x, string getDiagnosticsName, Type getCanonicalType, string getName, - Type getInterfaceType +from PrimaryArchetypeType x, string getName, Type getCanonicalType, Type getInterfaceType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and - getCanonicalType = x.getCanonicalType() and getName = x.getName() and + getCanonicalType = x.getCanonicalType() and getInterfaceType = x.getInterfaceType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getName:", getName, "getInterfaceType:", getInterfaceType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getInterfaceType:", + getInterfaceType diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected new file mode 100644 index 00000000000..7be629a81ca --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected @@ -0,0 +1,4 @@ +| P1 & (P2 & P3) | getName: | P1 & (P2 & P3) | getCanonicalType: | P1 & P2 & P3 | +| P1 & P2 & P3 | getName: | P1 & P2 & P3 | getCanonicalType: | P1 & P2 & P3 | +| P1 & P23 | getName: | P1 & P23 | getCanonicalType: | P1 & P2 & P3 | +| P2 & P4 | getName: | P2 & P4 | getCanonicalType: | P2 & P4 | diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql new file mode 100644 index 00000000000..8d3b769eff5 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ProtocolCompositionType x, string getName, Type getCanonicalType +where + toBeTested(x) and + not x.isUnknown() and + getName = x.getName() and + getCanonicalType = x.getCanonicalType() +select x, "getName:", getName, "getCanonicalType:", getCanonicalType diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.expected b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.expected new file mode 100644 index 00000000000..4792394a757 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.expected @@ -0,0 +1,9 @@ +| P1 & (P2 & P3) | 0 | P1 | +| P1 & (P2 & P3) | 1 | (P2 & P3) | +| P1 & P2 & P3 | 0 | P1 | +| P1 & P2 & P3 | 1 | P2 | +| P1 & P2 & P3 | 2 | P3 | +| P1 & P23 | 0 | P1 | +| P1 & P23 | 1 | P23 | +| P2 & P4 | 0 | P2 | +| P2 & P4 | 1 | P4 | diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.ql b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.ql new file mode 100644 index 00000000000..4804b223727 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ProtocolCompositionType x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getMember(index) diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/protocol_composition.swift b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/protocol_composition.swift new file mode 100644 index 00000000000..ba760d00ef6 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/protocol_composition.swift @@ -0,0 +1,13 @@ +protocol P1 {} +protocol P2 {} +protocol P3 {} + +var x: P1 & P2 & P3 + +protocol P4: P1 {} +var y: P1 & P2 & P4 + +var z: P1 & (P2 & P3) + +typealias P23 = P2 & P3 +var zz: P1 & P23 diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/TypeRepr/MISSING_SOURCE.txt similarity index 100% rename from swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/MISSING_SOURCE.txt rename to swift/ql/test/extractor-tests/generated/type/TypeRepr/MISSING_SOURCE.txt diff --git a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected index 1841fffc8c2..fd0739cefbc 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected +++ b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected @@ -1 +1,2 @@ -| A? | getDiagnosticsName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| A? | getName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| Optional | getName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | diff --git a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql index 396988db25e..747bfa62e43 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from UnmanagedStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType +from UnmanagedStorageType x, string getName, Type getCanonicalType, Type getReferentType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getReferentType:", getReferentType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getReferentType:", + getReferentType diff --git a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected index 1841fffc8c2..fd0739cefbc 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected +++ b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected @@ -1 +1,2 @@ -| A? | getDiagnosticsName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| A? | getName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| Optional | getName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | diff --git a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql index 17744a437d7..85a48fd3710 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from UnownedStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType +from UnownedStorageType x, string getName, Type getCanonicalType, Type getReferentType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getReferentType:", getReferentType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getReferentType:", + getReferentType diff --git a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.expected b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.expected index 117748421b6..3bc4a94f39b 100644 --- a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.expected +++ b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.expected @@ -1,3 +1,3 @@ -| Int... | getDiagnosticsName: | Int... | getCanonicalType: | Array | getBaseType: | Int | -| T... | getDiagnosticsName: | T... | getCanonicalType: | Array | getBaseType: | T | -| T... | getDiagnosticsName: | T... | getCanonicalType: | Array<\u03c4_0_0> | getBaseType: | T | +| Int... | getName: | Int... | getCanonicalType: | Array | getBaseType: | Int | +| T... | getName: | T... | getCanonicalType: | Array | getBaseType: | T | +| T... | getName: | T... | getCanonicalType: | Array<\u03c4_0_0> | getBaseType: | T | diff --git a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql index 5a89dbcafab..7d4a8ea1af7 100644 --- a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql +++ b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql @@ -2,12 +2,11 @@ import codeql.swift.elements import TestUtils -from VariadicSequenceType x, string getDiagnosticsName, Type getCanonicalType, Type getBaseType +from VariadicSequenceType x, string getName, Type getCanonicalType, Type getBaseType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getBaseType = x.getBaseType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getBaseType:", getBaseType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getBaseType:", getBaseType diff --git a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected index 1841fffc8c2..fd0739cefbc 100644 --- a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected +++ b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected @@ -1 +1,2 @@ -| A? | getDiagnosticsName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| A? | getName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| Optional | getName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | diff --git a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql index 3209b0e7d3d..e332f518a40 100644 --- a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from WeakStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType +from WeakStorageType x, string getName, Type getCanonicalType, Type getReferentType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getReferentType:", getReferentType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getReferentType:", + getReferentType diff --git a/swift/ql/test/extractor-tests/generated/typerepr/ArrayTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/ArrayTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/ArrayTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/AttributedTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/AttributedTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/AttributedTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/CompileTimeConstTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/CompileTimeConstTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/CompileTimeConstTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/CompositionTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/CompositionTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/CompositionTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/CompoundIdentTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/CompoundIdentTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/CompoundIdentTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/DictionaryTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/DictionaryTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/DictionaryTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/ErrorTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/ErrorTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/ErrorTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/ExistentialTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/ExistentialTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/ExistentialTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/FixedTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/FixedTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/FixedTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/FunctionTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/FunctionTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/FunctionTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/GenericIdentTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/GenericIdentTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/GenericIdentTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/InOutTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/InOutTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/InOutTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/IsolatedTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/IsolatedTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/IsolatedTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/MetatypeTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/MetatypeTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/MetatypeTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/NamedOpaqueReturnTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/NamedOpaqueReturnTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/NamedOpaqueReturnTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/OpaqueReturnTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/OpaqueReturnTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/OpaqueReturnTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/OptionalTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/OptionalTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/OptionalTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/OwnedTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/OwnedTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/OwnedTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/PlaceholderTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/PlaceholderTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/PlaceholderTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/ProtocolTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/ProtocolTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/ProtocolTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/SharedTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/SharedTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/SharedTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/SilBoxTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/SilBoxTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/SilBoxTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/SimpleIdentTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/SimpleIdentTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/SimpleIdentTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/TupleTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/TupleTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/TupleTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index 3164022150d..d14ec33b48e 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -281,15 +281,12 @@ cfg.swift: #-----| -> ... is ... # 37| ... is ... -#-----| -> SimpleIdentTypeRepr +#-----| -> ... is ... # 37| ... is ... #-----| match -> print(_:separator:terminator:) #-----| no-match -> case ... -# 37| SimpleIdentTypeRepr -#-----| -> ... is ... - # 38| print(_:separator:terminator:) #-----| -> MyError @@ -414,7 +411,13 @@ cfg.swift: # 51| enter createClosure2(x:) #-----| -> createClosure2(x:) +# 51| exit createClosure2(x:) + +# 51| exit createClosure2(x:) (normal) +#-----| -> exit createClosure2(x:) + # 51| x +#-----| -> f(y:) # 52| enter f(y:) #-----| -> f(y:) @@ -424,6 +427,9 @@ cfg.swift: # 52| exit f(y:) (normal) #-----| -> exit f(y:) +# 52| f(y:) +#-----| -> f(y:) + # 52| f(y:) #-----| -> y @@ -451,6 +457,12 @@ cfg.swift: # 53| y #-----| -> ... call to +(_:_:) ... +# 55| return ... +#-----| return -> exit createClosure2(x:) (normal) + +# 55| f(y:) +#-----| -> return ... + # 58| createClosure3(x:) #-----| -> x @@ -722,6 +734,11 @@ cfg.swift: # 81| enter testInOut() #-----| -> testInOut() +# 81| exit testInOut() + +# 81| exit testInOut() (normal) +#-----| -> exit testInOut() + # 81| testInOut() #-----| -> temp @@ -732,10 +749,14 @@ cfg.swift: #-----| match -> 10 # 82| temp +#-----| -> add(a:) # 82| 10 #-----| -> var ... = ... +# 84| add(a:) +#-----| -> addOptional(a:) + # 84| add(a:) #-----| -> a @@ -777,6 +798,9 @@ cfg.swift: # 85| 1 #-----| -> ... call to +(_:_:) ... +# 88| addOptional(a:) +#-----| -> add(a:) + # 88| addOptional(a:) #-----| -> a @@ -800,6 +824,78 @@ cfg.swift: # 89| nil #-----| -> ... = ... +# 92| add(a:) +#-----| -> temp + +# 92| call to add(a:) +#-----| -> tempOptional + +# 92| &... +#-----| -> call to add(a:) + +# 92| temp +#-----| -> &... + +# 93| var ... = ... +#-----| -> tempOptional + +# 93| tempOptional +#-----| match -> ... as ... + +# 93| tempOptional +#-----| -> addOptional(a:) + +# 93| ... as ... +#-----| match -> 10 + +# 93| (Int?) ... +#-----| -> var ... = ... + +# 93| 10 +#-----| -> (Int?) ... + +# 94| addOptional(a:) +#-----| -> tempOptional + +# 94| call to addOptional(a:) +#-----| -> +(_:_:) + +# 94| &... +#-----| -> call to addOptional(a:) + +# 94| tempOptional +#-----| -> &... + +# 95| return ... +#-----| return -> exit testInOut() (normal) + +# 95| (Int) ... +#-----| -> tempOptional + +# 95| temp +#-----| -> (Int) ... + +# 95| ... call to +(_:_:) ... +#-----| -> return ... + +# 95| +(_:_:) +#-----| -> Int.Type + +# 95| Int.Type +#-----| -> call to +(_:_:) + +# 95| call to +(_:_:) +#-----| -> temp + +# 95| (Int?) ... +#-----| -> ...! + +# 95| tempOptional +#-----| -> (Int?) ... + +# 95| ...! +#-----| -> ... call to +(_:_:) ... + # 98| deinit #-----| -> { ... } @@ -1670,11 +1766,17 @@ cfg.swift: #-----| -> 2 # 185| ... call to <=(_:_:) ... -#-----| -> { ... } +#-----| false -> [false] ... call to &&(_:_:) ... +#-----| true -> { ... } # 185| ... call to &&(_:_:) ... #-----| exception -> exit m1(x:) (normal) -#-----| -> { ... } +#-----| false -> [false] ... call to &&(_:_:) ... +#-----| true -> { ... } + +# 185| [false] ... call to &&(_:_:) ... +#-----| exception -> exit m1(x:) (normal) +#-----| false -> [false] ... call to &&(_:_:) ... # 185| ... call to &&(_:_:) ... #-----| exception -> exit m1(x:) (normal) @@ -1682,7 +1784,11 @@ cfg.swift: #-----| false -> print(_:separator:terminator:) # 185| StmtCondition -#-----| -> &&(_:_:) +#-----| -> <=(_:_:) + +# 185| [false] ... call to &&(_:_:) ... +#-----| exception -> exit m1(x:) (normal) +#-----| false -> print(_:separator:terminator:) # 185| <=(_:_:) #-----| -> Int.Type @@ -1696,29 +1802,59 @@ cfg.swift: # 185| 2 #-----| -> ... call to <=(_:_:) ... -# 185| &&(_:_:) -#-----| -> Bool.Type +# 185| x +#-----| -> 0 -# 185| Bool.Type -#-----| -> call to &&(_:_:) +# 185| ... call to >(_:_:) ... +#-----| -> return ... -# 185| call to &&(_:_:) -#-----| -> <=(_:_:) - -# 185| { ... } +# 185| return ... #-----| -> ... call to &&(_:_:) ... -# 185| &&(_:_:) -#-----| -> Bool.Type +# 185| { ... } +#-----| -> >(_:_:) -# 185| Bool.Type -#-----| -> call to &&(_:_:) +# 185| >(_:_:) +#-----| -> Int.Type -# 185| call to &&(_:_:) -#-----| -> &&(_:_:) +# 185| Int.Type +#-----| -> call to >(_:_:) + +# 185| call to >(_:_:) +#-----| -> x + +# 185| 0 +#-----| -> ... call to >(_:_:) ... + +# 185| call to ... +#-----| -> return ... + +# 185| return ... +#-----| -> ... call to &&(_:_:) ... # 185| { ... } -#-----| -> ... call to &&(_:_:) ... +#-----| -> ==(_:_:) + +# 185| (...) +#-----| -> call to ... + +# 185| x +#-----| -> 5 + +# 185| ... call to ==(_:_:) ... +#-----| -> (...) + +# 185| ==(_:_:) +#-----| -> Int.Type + +# 185| Int.Type +#-----| -> call to ==(_:_:) + +# 185| call to ==(_:_:) +#-----| -> x + +# 185| 5 +#-----| -> ... call to ==(_:_:) ... # 186| print(_:separator:terminator:) #-----| -> x is 1 @@ -2058,48 +2194,14 @@ cfg.swift: # 224| if ... then { ... } #-----| -> StmtCondition -# 224| !(_:) -#-----| -> Bool.Type - -# 224| Bool.Type -#-----| -> call to !(_:) - -# 224| call to !(_:) +# 224| StmtCondition #-----| -> true -# 224| StmtCondition -#-----| -> !(_:) - -# 224| call to ... +# 224| [false] call to ... #-----| false -> exit constant_condition() (normal) -#-----| true -> print(_:separator:terminator:) # 224| true -#-----| -> call to ... - -# 225| print(_:separator:terminator:) -#-----| -> Impossible - -# 225| call to print(_:separator:terminator:) -#-----| -> exit constant_condition() (normal) - -# 225| default separator -#-----| -> default terminator - -# 225| default terminator -#-----| -> call to print(_:separator:terminator:) - -# 225| (Any) ... -#-----| -> [...] - -# 225| Impossible -#-----| -> (Any) ... - -# 225| [...] -#-----| -> default separator - -# 225| [...] -#-----| -> [...] +#-----| true -> [false] call to ... # 229| empty_else(b:) #-----| -> b @@ -2197,7 +2299,7 @@ cfg.swift: #-----| -> StmtCondition # 238| StmtCondition -#-----| -> ||(_:_:) +#-----| -> b1 # 238| [false] (...) #-----| false -> exit disjunct(b1:b2:) (normal) @@ -2206,24 +2308,26 @@ cfg.swift: #-----| true -> print(_:separator:terminator:) # 238| b1 -#-----| -> { ... } +#-----| true -> [true] ... call to ||(_:_:) ... +#-----| false -> { ... } # 238| ... call to ||(_:_:) ... #-----| exception -> exit disjunct(b1:b2:) (normal) #-----| false -> [false] (...) #-----| true -> [true] (...) -# 238| Bool.Type -#-----| -> call to ||(_:_:) +# 238| [true] ... call to ||(_:_:) ... +#-----| exception -> exit disjunct(b1:b2:) (normal) +#-----| true -> [true] (...) -# 238| call to ||(_:_:) -#-----| -> b1 +# 238| b2 +#-----| -> return ... -# 238| ||(_:_:) -#-----| -> Bool.Type +# 238| return ... +#-----| -> ... call to ||(_:_:) ... # 238| { ... } -#-----| -> ... call to ||(_:_:) ... +#-----| -> b2 # 239| print(_:separator:terminator:) #-----| -> b1 or b2 @@ -5131,292 +5235,944 @@ cfg.swift: # 405| y #-----| -> (...) -# 409| (unnamed function decl) +# 408| enter localDeclarations() +#-----| -> localDeclarations() -# 409| enter (unnamed function decl) +# 408| exit localDeclarations() + +# 408| exit localDeclarations() (normal) +#-----| -> exit localDeclarations() + +# 408| localDeclarations() +#-----| -> MyLocalClass + +# 409| MyLocalClass +#-----| -> MyLocalStruct + +# 409| deinit +#-----| -> { ... } + +# 409| enter deinit +#-----| -> deinit + +# 409| exit deinit + +# 409| exit deinit (normal) +#-----| -> exit deinit + +# 409| { ... } +#-----| -> exit deinit (normal) + +# 410| (unnamed function decl) + +# 410| enter (unnamed function decl) #-----| -> (unnamed function decl) -# 409| enter get +# 410| enter get #-----| -> get -# 409| enter set +# 410| enter set #-----| -> set -# 409| exit (unnamed function decl) +# 410| exit (unnamed function decl) -# 409| exit (unnamed function decl) (normal) +# 410| exit (unnamed function decl) (normal) #-----| -> exit (unnamed function decl) -# 409| exit get +# 410| exit get -# 409| exit get (normal) +# 410| exit get (normal) #-----| -> exit get -# 409| exit set +# 410| exit set -# 409| exit set (normal) +# 410| exit set (normal) #-----| -> exit set -# 409| get +# 410| get -# 409| set +# 410| set #-----| -> value -# 409| value +# 410| value -# 409| yield ... +# 410| yield ... #-----| -> exit (unnamed function decl) (normal) -# 413| (unnamed function decl) +# 411| enter init +#-----| -> init -# 413| enter (unnamed function decl) +# 411| exit init + +# 411| exit init (normal) +#-----| -> exit init + +# 411| init +#-----| -> self + +# 412| .x +#-----| -> 10 + +# 412| self +#-----| -> .x + +# 412| ... = ... +#-----| -> return + +# 412| 10 +#-----| -> ... = ... + +# 413| return +#-----| return -> exit init (normal) + +# 416| MyLocalStruct +#-----| -> MyLocalEnum + +# 417| (unnamed function decl) + +# 417| enter (unnamed function decl) #-----| -> (unnamed function decl) -# 413| enter get +# 417| enter get #-----| -> get -# 413| enter set +# 417| enter set #-----| -> set -# 413| exit (unnamed function decl) +# 417| exit (unnamed function decl) -# 413| exit (unnamed function decl) (normal) +# 417| exit (unnamed function decl) (normal) #-----| -> exit (unnamed function decl) -# 413| exit get +# 417| exit get -# 413| exit get (normal) +# 417| exit get (normal) #-----| -> exit get -# 413| exit set +# 417| exit set -# 413| exit set (normal) +# 417| exit set (normal) #-----| -> exit set -# 413| get +# 417| get -# 413| set +# 417| set #-----| -> value -# 413| value +# 417| value -# 413| yield ... +# 417| yield ... #-----| -> exit (unnamed function decl) (normal) -# 414| (unnamed function decl) +# 418| enter init +#-----| -> init -# 414| enter (unnamed function decl) +# 418| exit init + +# 418| exit init (normal) +#-----| -> exit init + +# 418| init +#-----| -> self + +# 419| .x +#-----| -> 10 + +# 419| self +#-----| -> .x + +# 419| ... = ... +#-----| -> return + +# 419| 10 +#-----| -> ... = ... + +# 420| return +#-----| return -> exit init (normal) + +# 423| MyLocalEnum +#-----| -> myLocalVar + +# 428| var ... = ... +#-----| -> myLocalVar + +# 428| myLocalVar +#-----| match -> ... as ... + +# 428| myLocalVar +#-----| -> 0 + +# 428| ... as ... +#-----| match -> var ... = ... + +# 442| return ... +#-----| return -> exit localDeclarations() (normal) + +# 442| 0 +#-----| -> return ... + +# 446| (unnamed function decl) + +# 446| enter (unnamed function decl) #-----| -> (unnamed function decl) -# 414| enter get +# 446| enter get #-----| -> get -# 414| enter set +# 446| enter set #-----| -> set -# 414| exit (unnamed function decl) +# 446| exit (unnamed function decl) -# 414| exit (unnamed function decl) (normal) +# 446| exit (unnamed function decl) (normal) #-----| -> exit (unnamed function decl) -# 414| exit get +# 446| exit get -# 414| exit get (normal) +# 446| exit get (normal) #-----| -> exit get -# 414| exit set +# 446| exit set -# 414| exit set (normal) +# 446| exit set (normal) #-----| -> exit set -# 414| get +# 446| get -# 414| set +# 446| set #-----| -> value -# 414| value +# 446| value -# 414| yield ... +# 446| yield ... #-----| -> exit (unnamed function decl) (normal) -# 415| (unnamed function decl) +# 450| (unnamed function decl) -# 415| enter (unnamed function decl) +# 450| enter (unnamed function decl) #-----| -> (unnamed function decl) -# 415| enter get +# 450| enter get #-----| -> get -# 415| enter set +# 450| enter set #-----| -> set -# 415| exit (unnamed function decl) +# 450| exit (unnamed function decl) -# 415| exit (unnamed function decl) (normal) +# 450| exit (unnamed function decl) (normal) #-----| -> exit (unnamed function decl) -# 415| exit get +# 450| exit get -# 415| exit get (normal) +# 450| exit get (normal) #-----| -> exit get -# 415| exit set +# 450| exit set -# 415| exit set (normal) +# 450| exit set (normal) #-----| -> exit set -# 415| get +# 450| get -# 415| set +# 450| set #-----| -> value -# 415| value +# 450| value -# 415| yield ... +# 450| yield ... #-----| -> exit (unnamed function decl) (normal) -# 418| enter test(a:) +# 451| (unnamed function decl) + +# 451| enter (unnamed function decl) +#-----| -> (unnamed function decl) + +# 451| enter get +#-----| -> get + +# 451| enter set +#-----| -> set + +# 451| exit (unnamed function decl) + +# 451| exit (unnamed function decl) (normal) +#-----| -> exit (unnamed function decl) + +# 451| exit get + +# 451| exit get (normal) +#-----| -> exit get + +# 451| exit set + +# 451| exit set (normal) +#-----| -> exit set + +# 451| get + +# 451| set +#-----| -> value + +# 451| value + +# 451| yield ... +#-----| -> exit (unnamed function decl) (normal) + +# 452| (unnamed function decl) + +# 452| enter (unnamed function decl) +#-----| -> (unnamed function decl) + +# 452| enter get +#-----| -> get + +# 452| enter set +#-----| -> set + +# 452| exit (unnamed function decl) + +# 452| exit (unnamed function decl) (normal) +#-----| -> exit (unnamed function decl) + +# 452| exit get + +# 452| exit get (normal) +#-----| -> exit get + +# 452| exit set + +# 452| exit set (normal) +#-----| -> exit set + +# 452| get + +# 452| set +#-----| -> value + +# 452| value + +# 452| yield ... +#-----| -> exit (unnamed function decl) (normal) + +# 455| enter test(a:) #-----| -> test(a:) -# 418| exit test(a:) +# 455| exit test(a:) -# 418| exit test(a:) (normal) +# 455| exit test(a:) (normal) #-----| -> exit test(a:) -# 418| test(a:) +# 455| test(a:) #-----| -> a -# 418| a +# 455| a #-----| -> kpGet_b_x -# 419| var ... = ... +# 456| var ... = ... #-----| -> kpGet_b_x -# 419| kpGet_b_x +# 456| var ... = ... +#-----| -> kpGet_b_x + +# 456| kpGet_b_x #-----| match -> #keyPath(...) -# 419| kpGet_b_x +# 456| kpGet_b_x #-----| -> kpGet_bs_0_x -# 419| #keyPath(...) -#-----| -> var ... = ... - -# 420| var ... = ... +# 456| kpGet_b_x #-----| -> kpGet_bs_0_x -# 420| kpGet_bs_0_x -#-----| match -> #keyPath(...) - -# 420| kpGet_bs_0_x -#-----| -> kpGet_mayB_force_x - -# 420| #keyPath(...) +# 456| #keyPath(...) #-----| -> var ... = ... -# 421| var ... = ... -#-----| -> kpGet_mayB_force_x +# 456| #keyPath(...) +#-----| -> var ... = ... +#-----| -> exit #keyPath(...) (normal) -# 421| kpGet_mayB_force_x +# 456| enter #keyPath(...) +#-----| -> #keyPath(...) + +# 456| exit #keyPath(...) + +# 456| exit #keyPath(...) (normal) +#-----| -> exit #keyPath(...) + +# 457| var ... = ... +#-----| -> kpGet_bs_0_x + +# 457| var ... = ... +#-----| -> kpGet_bs_0_x + +# 457| var ... = ... +#-----| -> kpGet_bs_0_x + +# 457| kpGet_bs_0_x #-----| match -> #keyPath(...) -# 421| kpGet_mayB_force_x +# 457| kpGet_bs_0_x +#-----| -> kpGet_mayB_force_x + +# 457| kpGet_bs_0_x +#-----| match -> #keyPath(...) + +# 457| kpGet_bs_0_x +#-----| -> kpGet_mayB_force_x + +# 457| kpGet_bs_0_x +#-----| -> kpGet_mayB_force_x + +# 457| #keyPath(...) +#-----| -> var ... = ... + +# 457| #keyPath(...) +#-----| -> var ... = ... + +# 457| #keyPath(...) +#-----| -> var ... = ... +#-----| -> exit #keyPath(...) (normal) + +# 457| enter #keyPath(...) +#-----| -> #keyPath(...) + +# 457| exit #keyPath(...) + +# 457| exit #keyPath(...) (normal) +#-----| -> exit #keyPath(...) + +# 458| var ... = ... +#-----| -> kpGet_mayB_force_x + +# 458| var ... = ... +#-----| -> kpGet_mayB_force_x + +# 458| var ... = ... +#-----| -> kpGet_mayB_force_x + +# 458| var ... = ... +#-----| -> kpGet_mayB_force_x + +# 458| kpGet_mayB_force_x +#-----| match -> #keyPath(...) + +# 458| kpGet_mayB_force_x #-----| -> kpGet_mayB_x -# 421| #keyPath(...) -#-----| -> var ... = ... - -# 422| var ... = ... -#-----| -> kpGet_mayB_x - -# 422| kpGet_mayB_x +# 458| kpGet_mayB_force_x #-----| match -> #keyPath(...) -# 422| kpGet_mayB_x -#-----| -> apply_kpGet_b_x +# 458| kpGet_mayB_force_x +#-----| -> kpGet_mayB_x -# 422| #keyPath(...) +# 458| kpGet_mayB_force_x +#-----| match -> #keyPath(...) + +# 458| kpGet_mayB_force_x +#-----| -> kpGet_mayB_x + +# 458| kpGet_mayB_force_x +#-----| -> kpGet_mayB_x + +# 458| #keyPath(...) #-----| -> var ... = ... -# 424| var ... = ... +# 458| #keyPath(...) +#-----| -> var ... = ... + +# 458| #keyPath(...) +#-----| -> var ... = ... + +# 458| #keyPath(...) +#-----| -> var ... = ... +#-----| -> exit #keyPath(...) (normal) + +# 458| enter #keyPath(...) +#-----| -> #keyPath(...) + +# 458| exit #keyPath(...) + +# 458| exit #keyPath(...) (normal) +#-----| -> exit #keyPath(...) + +# 459| var ... = ... +#-----| -> kpGet_mayB_x + +# 459| var ... = ... +#-----| -> kpGet_mayB_x + +# 459| var ... = ... +#-----| -> kpGet_mayB_x + +# 459| var ... = ... +#-----| -> kpGet_mayB_x + +# 459| var ... = ... +#-----| -> kpGet_mayB_x + +# 459| kpGet_mayB_x +#-----| match -> #keyPath(...) + +# 459| kpGet_mayB_x #-----| -> apply_kpGet_b_x -# 424| apply_kpGet_b_x +# 459| kpGet_mayB_x +#-----| match -> #keyPath(...) + +# 459| kpGet_mayB_x +#-----| -> apply_kpGet_b_x + +# 459| kpGet_mayB_x +#-----| match -> #keyPath(...) + +# 459| kpGet_mayB_x +#-----| -> apply_kpGet_b_x + +# 459| kpGet_mayB_x +#-----| match -> #keyPath(...) + +# 459| kpGet_mayB_x +#-----| -> apply_kpGet_b_x + +# 459| kpGet_mayB_x +#-----| -> apply_kpGet_b_x + +# 459| #keyPath(...) +#-----| -> var ... = ... + +# 459| #keyPath(...) +#-----| -> var ... = ... + +# 459| #keyPath(...) +#-----| -> var ... = ... + +# 459| #keyPath(...) +#-----| -> var ... = ... + +# 459| #keyPath(...) +#-----| -> var ... = ... +#-----| -> exit #keyPath(...) (normal) + +# 459| enter #keyPath(...) +#-----| -> #keyPath(...) + +# 459| exit #keyPath(...) + +# 459| exit #keyPath(...) (normal) +#-----| -> exit #keyPath(...) + +# 461| var ... = ... +#-----| -> apply_kpGet_b_x + +# 461| var ... = ... +#-----| -> apply_kpGet_b_x + +# 461| var ... = ... +#-----| -> apply_kpGet_b_x + +# 461| var ... = ... +#-----| -> apply_kpGet_b_x + +# 461| var ... = ... +#-----| -> apply_kpGet_b_x + +# 461| apply_kpGet_b_x #-----| match -> a -# 424| apply_kpGet_b_x +# 461| apply_kpGet_b_x #-----| -> apply_kpGet_bs_0_x -# 424| a +# 461| apply_kpGet_b_x +#-----| match -> a + +# 461| apply_kpGet_b_x +#-----| -> apply_kpGet_bs_0_x + +# 461| apply_kpGet_b_x +#-----| match -> a + +# 461| apply_kpGet_b_x +#-----| -> apply_kpGet_bs_0_x + +# 461| apply_kpGet_b_x +#-----| match -> a + +# 461| apply_kpGet_b_x +#-----| -> apply_kpGet_bs_0_x + +# 461| apply_kpGet_b_x +#-----| match -> a + +# 461| apply_kpGet_b_x +#-----| -> apply_kpGet_bs_0_x + +# 461| a #-----| -> kpGet_b_x -# 424| \...[...] +# 461| a +#-----| -> kpGet_b_x + +# 461| a +#-----| -> kpGet_b_x + +# 461| a +#-----| -> kpGet_b_x + +# 461| a +#-----| -> kpGet_b_x + +# 461| \...[...] #-----| -> var ... = ... -# 424| (WritableKeyPath) ... +# 461| \...[...] +#-----| -> var ... = ... + +# 461| \...[...] +#-----| -> var ... = ... + +# 461| \...[...] +#-----| -> var ... = ... + +# 461| \...[...] +#-----| -> var ... = ... + +# 461| (WritableKeyPath) ... #-----| -> \...[...] -# 424| kpGet_b_x +# 461| (WritableKeyPath) ... +#-----| -> \...[...] + +# 461| (WritableKeyPath) ... +#-----| -> \...[...] + +# 461| (WritableKeyPath) ... +#-----| -> \...[...] + +# 461| (WritableKeyPath) ... +#-----| -> \...[...] + +# 461| kpGet_b_x #-----| -> (WritableKeyPath) ... -# 425| var ... = ... +# 461| kpGet_b_x +#-----| -> (WritableKeyPath) ... + +# 461| kpGet_b_x +#-----| -> (WritableKeyPath) ... + +# 461| kpGet_b_x +#-----| -> (WritableKeyPath) ... + +# 461| kpGet_b_x +#-----| -> (WritableKeyPath) ... + +# 462| var ... = ... #-----| -> apply_kpGet_bs_0_x -# 425| apply_kpGet_bs_0_x +# 462| var ... = ... +#-----| -> apply_kpGet_bs_0_x + +# 462| var ... = ... +#-----| -> apply_kpGet_bs_0_x + +# 462| var ... = ... +#-----| -> apply_kpGet_bs_0_x + +# 462| var ... = ... +#-----| -> apply_kpGet_bs_0_x + +# 462| apply_kpGet_bs_0_x #-----| match -> a -# 425| apply_kpGet_bs_0_x +# 462| apply_kpGet_bs_0_x #-----| -> apply_kpGet_mayB_force_x -# 425| a +# 462| apply_kpGet_bs_0_x +#-----| match -> a + +# 462| apply_kpGet_bs_0_x +#-----| -> apply_kpGet_mayB_force_x + +# 462| apply_kpGet_bs_0_x +#-----| match -> a + +# 462| apply_kpGet_bs_0_x +#-----| -> apply_kpGet_mayB_force_x + +# 462| apply_kpGet_bs_0_x +#-----| match -> a + +# 462| apply_kpGet_bs_0_x +#-----| -> apply_kpGet_mayB_force_x + +# 462| apply_kpGet_bs_0_x +#-----| match -> a + +# 462| apply_kpGet_bs_0_x +#-----| -> apply_kpGet_mayB_force_x + +# 462| a #-----| -> kpGet_bs_0_x -# 425| \...[...] +# 462| a +#-----| -> kpGet_bs_0_x + +# 462| a +#-----| -> kpGet_bs_0_x + +# 462| a +#-----| -> kpGet_bs_0_x + +# 462| a +#-----| -> kpGet_bs_0_x + +# 462| \...[...] #-----| -> var ... = ... -# 425| (WritableKeyPath) ... +# 462| \...[...] +#-----| -> var ... = ... + +# 462| \...[...] +#-----| -> var ... = ... + +# 462| \...[...] +#-----| -> var ... = ... + +# 462| \...[...] +#-----| -> var ... = ... + +# 462| (WritableKeyPath) ... #-----| -> \...[...] -# 425| kpGet_bs_0_x +# 462| (WritableKeyPath) ... +#-----| -> \...[...] + +# 462| (WritableKeyPath) ... +#-----| -> \...[...] + +# 462| (WritableKeyPath) ... +#-----| -> \...[...] + +# 462| (WritableKeyPath) ... +#-----| -> \...[...] + +# 462| kpGet_bs_0_x #-----| -> (WritableKeyPath) ... -# 426| var ... = ... +# 462| kpGet_bs_0_x +#-----| -> (WritableKeyPath) ... + +# 462| kpGet_bs_0_x +#-----| -> (WritableKeyPath) ... + +# 462| kpGet_bs_0_x +#-----| -> (WritableKeyPath) ... + +# 462| kpGet_bs_0_x +#-----| -> (WritableKeyPath) ... + +# 463| var ... = ... #-----| -> apply_kpGet_mayB_force_x -# 426| apply_kpGet_mayB_force_x +# 463| var ... = ... +#-----| -> apply_kpGet_mayB_force_x + +# 463| var ... = ... +#-----| -> apply_kpGet_mayB_force_x + +# 463| var ... = ... +#-----| -> apply_kpGet_mayB_force_x + +# 463| var ... = ... +#-----| -> apply_kpGet_mayB_force_x + +# 463| apply_kpGet_mayB_force_x #-----| match -> a -# 426| apply_kpGet_mayB_force_x +# 463| apply_kpGet_mayB_force_x #-----| -> apply_kpGet_mayB_x -# 426| a +# 463| apply_kpGet_mayB_force_x +#-----| match -> a + +# 463| apply_kpGet_mayB_force_x +#-----| -> apply_kpGet_mayB_x + +# 463| apply_kpGet_mayB_force_x +#-----| match -> a + +# 463| apply_kpGet_mayB_force_x +#-----| -> apply_kpGet_mayB_x + +# 463| apply_kpGet_mayB_force_x +#-----| match -> a + +# 463| apply_kpGet_mayB_force_x +#-----| -> apply_kpGet_mayB_x + +# 463| apply_kpGet_mayB_force_x +#-----| match -> a + +# 463| apply_kpGet_mayB_force_x +#-----| -> apply_kpGet_mayB_x + +# 463| a #-----| -> kpGet_mayB_force_x -# 426| \...[...] +# 463| a +#-----| -> kpGet_mayB_force_x + +# 463| a +#-----| -> kpGet_mayB_force_x + +# 463| a +#-----| -> kpGet_mayB_force_x + +# 463| a +#-----| -> kpGet_mayB_force_x + +# 463| \...[...] #-----| -> var ... = ... -# 426| (WritableKeyPath) ... +# 463| \...[...] +#-----| -> var ... = ... + +# 463| \...[...] +#-----| -> var ... = ... + +# 463| \...[...] +#-----| -> var ... = ... + +# 463| \...[...] +#-----| -> var ... = ... + +# 463| (WritableKeyPath) ... #-----| -> \...[...] -# 426| kpGet_mayB_force_x +# 463| (WritableKeyPath) ... +#-----| -> \...[...] + +# 463| (WritableKeyPath) ... +#-----| -> \...[...] + +# 463| (WritableKeyPath) ... +#-----| -> \...[...] + +# 463| (WritableKeyPath) ... +#-----| -> \...[...] + +# 463| kpGet_mayB_force_x #-----| -> (WritableKeyPath) ... -# 427| var ... = ... +# 463| kpGet_mayB_force_x +#-----| -> (WritableKeyPath) ... + +# 463| kpGet_mayB_force_x +#-----| -> (WritableKeyPath) ... + +# 463| kpGet_mayB_force_x +#-----| -> (WritableKeyPath) ... + +# 463| kpGet_mayB_force_x +#-----| -> (WritableKeyPath) ... + +# 464| var ... = ... #-----| -> apply_kpGet_mayB_x -# 427| apply_kpGet_mayB_x +# 464| var ... = ... +#-----| -> apply_kpGet_mayB_x + +# 464| var ... = ... +#-----| -> apply_kpGet_mayB_x + +# 464| var ... = ... +#-----| -> apply_kpGet_mayB_x + +# 464| var ... = ... +#-----| -> apply_kpGet_mayB_x + +# 464| apply_kpGet_mayB_x #-----| match -> a -# 427| apply_kpGet_mayB_x +# 464| apply_kpGet_mayB_x #-----| -> exit test(a:) (normal) -# 427| a +# 464| apply_kpGet_mayB_x +#-----| match -> a + +# 464| apply_kpGet_mayB_x + +# 464| apply_kpGet_mayB_x +#-----| match -> a + +# 464| apply_kpGet_mayB_x + +# 464| apply_kpGet_mayB_x +#-----| match -> a + +# 464| apply_kpGet_mayB_x + +# 464| apply_kpGet_mayB_x +#-----| match -> a + +# 464| apply_kpGet_mayB_x + +# 464| a #-----| -> kpGet_mayB_x -# 427| \...[...] +# 464| a +#-----| -> kpGet_mayB_x + +# 464| a +#-----| -> kpGet_mayB_x + +# 464| a +#-----| -> kpGet_mayB_x + +# 464| a +#-----| -> kpGet_mayB_x + +# 464| \...[...] #-----| -> var ... = ... -# 427| (KeyPath) ... +# 464| \...[...] +#-----| -> var ... = ... + +# 464| \...[...] +#-----| -> var ... = ... + +# 464| \...[...] +#-----| -> var ... = ... + +# 464| \...[...] +#-----| -> var ... = ... + +# 464| (KeyPath) ... #-----| -> \...[...] -# 427| kpGet_mayB_x +# 464| (KeyPath) ... +#-----| -> \...[...] + +# 464| (KeyPath) ... +#-----| -> \...[...] + +# 464| (KeyPath) ... +#-----| -> \...[...] + +# 464| (KeyPath) ... +#-----| -> \...[...] + +# 464| kpGet_mayB_x +#-----| -> (KeyPath) ... + +# 464| kpGet_mayB_x +#-----| -> (KeyPath) ... + +# 464| kpGet_mayB_x +#-----| -> (KeyPath) ... + +# 464| kpGet_mayB_x +#-----| -> (KeyPath) ... + +# 464| kpGet_mayB_x #-----| -> (KeyPath) ... diff --git a/swift/ql/test/library-tests/controlflow/graph/cfg.swift b/swift/ql/test/library-tests/controlflow/graph/cfg.swift index 6c162dfcc9d..166f6ecafdc 100644 --- a/swift/ql/test/library-tests/controlflow/graph/cfg.swift +++ b/swift/ql/test/library-tests/controlflow/graph/cfg.swift @@ -405,6 +405,43 @@ func dictionaryLiteral(x: Int, y: Int) -> [String: Int] { return ["x": x, "y": y] } +func localDeclarations() -> Int { + class MyLocalClass { + var x: Int + init() { + x = 10 + } + } + + struct MyLocalStruct { + var x: Int + init() { + x = 10 + } + } + + enum MyLocalEnum { + case A + case B + } + + var myLocalVar : Int; + + // Error: declaration is only valid at file scope + // extension Int { + // func myExtensionMethod() -> Int { + // return self + // } + // } + + // protocol 'MyProtocol' cannot be nested inside another declaration + // protocol MyProtocol { + // func myMethod() + // } + + return 0 +} + struct B { var x : Int } diff --git a/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.expected b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.expected new file mode 100644 index 00000000000..3d20366aec6 --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.expected @@ -0,0 +1,6 @@ +| arithmeticoperation.swift:6:6:6:10 | ... call to +(_:_:) ... | AddExpr, BinaryArithmeticOperation | +| arithmeticoperation.swift:7:6:7:10 | ... call to -(_:_:) ... | BinaryArithmeticOperation, SubExpr | +| arithmeticoperation.swift:8:6:8:10 | ... call to *(_:_:) ... | BinaryArithmeticOperation, MulExpr | +| arithmeticoperation.swift:9:6:9:10 | ... call to /(_:_:) ... | BinaryArithmeticOperation, DivExpr | +| arithmeticoperation.swift:10:6:10:10 | ... call to %(_:_:) ... | BinaryArithmeticOperation, RemExpr | +| arithmeticoperation.swift:11:6:11:7 | call to ... | UnaryArithmeticOperation, UnaryMinusExpr | diff --git a/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql new file mode 100644 index 00000000000..9d98daa68af --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql @@ -0,0 +1,22 @@ +import swift + +string describe(ArithmeticOperation e) { + e instanceof BinaryArithmeticOperation and result = "BinaryArithmeticOperation" + or + e instanceof AddExpr and result = "AddExpr" + or + e instanceof SubExpr and result = "SubExpr" + or + e instanceof MulExpr and result = "MulExpr" + or + e instanceof DivExpr and result = "DivExpr" + or + e instanceof RemExpr and result = "RemExpr" + or + e instanceof UnaryArithmeticOperation and result = "UnaryArithmeticOperation" + or + e instanceof UnaryMinusExpr and result = "UnaryMinusExpr" +} + +from ArithmeticOperation e +select e, concat(describe(e), ", ") diff --git a/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.swift b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.swift new file mode 100644 index 00000000000..096b6709600 --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.swift @@ -0,0 +1,12 @@ + +func test(c: Bool, x: Int, y: Int, z: Int) { + var v = 0 + + // arithmetic operations + v = x + y; + v = x - 1; + v = 2 * y; + v = 3 / 4; + v = x % y; + v = -x; +} diff --git a/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.expected b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.expected new file mode 100644 index 00000000000..1b3ccaab17f --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.expected @@ -0,0 +1,6 @@ +| logicaloperation.swift:4:6:4:11 | ... call to &&(_:_:) ... | BinaryLogicalExpr, LogicalAndExpr | +| logicaloperation.swift:5:6:5:11 | ... call to \|\|(_:_:) ... | BinaryLogicalExpr, LogicalOrExpr | +| logicaloperation.swift:6:6:6:7 | call to ... | NotExpr, UnaryLogicalOperation | +| logicaloperation.swift:7:6:7:21 | call to ... | NotExpr, UnaryLogicalOperation | +| logicaloperation.swift:7:8:7:20 | ... call to \|\|(_:_:) ... | BinaryLogicalExpr, LogicalOrExpr | +| logicaloperation.swift:7:9:7:14 | ... call to &&(_:_:) ... | BinaryLogicalExpr, LogicalAndExpr | diff --git a/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql new file mode 100644 index 00000000000..f9c361ed214 --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql @@ -0,0 +1,16 @@ +import swift + +string describe(LogicalOperation e) { + e instanceof BinaryLogicalOperation and result = "BinaryLogicalExpr" + or + e instanceof LogicalAndExpr and result = "LogicalAndExpr" + or + e instanceof LogicalOrExpr and result = "LogicalOrExpr" + or + e instanceof UnaryLogicalOperation and result = "UnaryLogicalOperation" + or + e instanceof NotExpr and result = "NotExpr" +} + +from LogicalOperation e +select e, concat(describe(e), ", ") diff --git a/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.swift b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.swift new file mode 100644 index 00000000000..a1af03ab2c0 --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.swift @@ -0,0 +1,8 @@ + +func test(a: Bool, b: Bool, c: Bool) { + // logical operations + if (a && b) {} + if (a || b) {} + if (!a) {} + if (!((a && b) || c)) {} +} diff --git a/swift/ql/test/library-tests/parent/parent.expected b/swift/ql/test/library-tests/parent/parent.expected index ab98c789f82..8ebbf1dd372 100644 --- a/swift/ql/test/library-tests/parent/parent.expected +++ b/swift/ql/test/library-tests/parent/parent.expected @@ -22,13 +22,13 @@ | declarations.swift:3:7:3:7 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr | | declarations.swift:3:7:3:7 | { ... } | BraceStmt | declarations.swift:3:7:3:7 | yield ... | YieldStmt | | declarations.swift:3:7:3:14 | ... as ... | TypedPattern | declarations.swift:3:7:3:7 | next | NamedPattern | -| declarations.swift:3:7:3:14 | ... as ... | TypedPattern | declarations.swift:3:14:3:14 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:3:7:3:14 | ... as ... | TypedPattern | declarations.swift:3:14:3:14 | Int | TypeRepr | | declarations.swift:4:5:4:24 | get | AccessorDecl | declarations.swift:4:9:4:24 | { ... } | BraceStmt | | declarations.swift:4:9:4:24 | { ... } | BraceStmt | declarations.swift:4:11:4:22 | return ... | ReturnStmt | | declarations.swift:4:11:4:22 | return ... | ReturnStmt | declarations.swift:4:18:4:22 | ... call to +(_:_:) ... | BinaryExpr | | declarations.swift:4:18:4:18 | .x | MemberRefExpr | declarations.swift:4:18:4:18 | self | DeclRefExpr | | declarations.swift:4:18:4:22 | ... call to +(_:_:) ... | BinaryExpr | declarations.swift:4:20:4:20 | call to +(_:_:) | DotSyntaxCallExpr | -| declarations.swift:4:20:4:20 | Int.Type | TypeExpr | declarations.swift:4:20:4:20 | FixedTypeRepr | FixedTypeRepr | +| declarations.swift:4:20:4:20 | Int.Type | TypeExpr | declarations.swift:4:20:4:20 | Int | TypeRepr | | declarations.swift:4:20:4:20 | call to +(_:_:) | DotSyntaxCallExpr | declarations.swift:4:20:4:20 | +(_:_:) | DeclRefExpr | | declarations.swift:5:5:5:38 | set | AccessorDecl | declarations.swift:5:9:5:9 | newValue | ParamDecl | | declarations.swift:5:5:5:38 | set | AccessorDecl | declarations.swift:5:19:5:38 | { ... } | BraceStmt | @@ -37,7 +37,7 @@ | declarations.swift:5:21:5:36 | ... = ... | AssignExpr | declarations.swift:5:21:5:21 | .x | MemberRefExpr | | declarations.swift:5:21:5:36 | ... = ... | AssignExpr | declarations.swift:5:25:5:36 | ... call to -(_:_:) ... | BinaryExpr | | declarations.swift:5:25:5:36 | ... call to -(_:_:) ... | BinaryExpr | declarations.swift:5:34:5:34 | call to -(_:_:) | DotSyntaxCallExpr | -| declarations.swift:5:34:5:34 | Int.Type | TypeExpr | declarations.swift:5:34:5:34 | FixedTypeRepr | FixedTypeRepr | +| declarations.swift:5:34:5:34 | Int.Type | TypeExpr | declarations.swift:5:34:5:34 | Int | TypeRepr | | declarations.swift:5:34:5:34 | call to -(_:_:) | DotSyntaxCallExpr | declarations.swift:5:34:5:34 | -(_:_:) | DeclRefExpr | | declarations.swift:9:7:9:7 | deinit | DestructorDecl | declarations.swift:9:7:9:7 | { ... } | BraceStmt | | declarations.swift:9:7:9:7 | init | ConstructorDecl | declarations.swift:9:7:9:7 | { ... } | BraceStmt | @@ -56,7 +56,7 @@ | declarations.swift:9:17:9:17 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | declarations.swift:9:17:9:17 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:9:17:9:21 | ... as ... | TypedPattern | declarations.swift:9:17:9:17 | x | NamedPattern | -| declarations.swift:9:17:9:21 | ... as ... | TypedPattern | declarations.swift:9:21:9:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:9:17:9:21 | ... as ... | TypedPattern | declarations.swift:9:21:9:21 | Double | TypeRepr | | declarations.swift:12:5:12:18 | case ... | EnumCaseDecl | declarations.swift:12:10:12:10 | value1 | EnumElementDecl | | declarations.swift:12:5:12:18 | case ... | EnumCaseDecl | declarations.swift:12:18:12:18 | value2 | EnumElementDecl | | declarations.swift:13:5:13:26 | case ... | EnumCaseDecl | declarations.swift:13:10:13:10 | value3 | EnumElementDecl | @@ -75,12 +75,12 @@ | declarations.swift:23:9:23:9 | mustBeSettable | ConcreteVarDecl | declarations.swift:23:31:23:31 | get | AccessorDecl | | declarations.swift:23:9:23:9 | mustBeSettable | ConcreteVarDecl | declarations.swift:23:35:23:35 | set | AccessorDecl | | declarations.swift:23:9:23:25 | ... as ... | TypedPattern | declarations.swift:23:9:23:9 | mustBeSettable | NamedPattern | -| declarations.swift:23:9:23:25 | ... as ... | TypedPattern | declarations.swift:23:25:23:25 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:23:9:23:25 | ... as ... | TypedPattern | declarations.swift:23:25:23:25 | Int | TypeRepr | | declarations.swift:23:35:23:35 | set | AccessorDecl | declarations.swift:23:35:23:35 | newValue | ParamDecl | | declarations.swift:24:5:24:44 | var ... = ... | PatternBindingDecl | declarations.swift:24:9:24:34 | ... as ... | TypedPattern | | declarations.swift:24:9:24:9 | doesNotNeedToBeSettable | ConcreteVarDecl | declarations.swift:24:40:24:40 | get | AccessorDecl | | declarations.swift:24:9:24:34 | ... as ... | TypedPattern | declarations.swift:24:9:24:9 | doesNotNeedToBeSettable | NamedPattern | -| declarations.swift:24:9:24:34 | ... as ... | TypedPattern | declarations.swift:24:34:24:34 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:24:9:24:34 | ... as ... | TypedPattern | declarations.swift:24:34:24:34 | Int | TypeRepr | | declarations.swift:28:1:28:37 | a_function(a_parameter:) | ConcreteFuncDecl | declarations.swift:28:17:28:31 | a_parameter | ParamDecl | | declarations.swift:28:1:28:37 | a_function(a_parameter:) | ConcreteFuncDecl | declarations.swift:28:36:28:37 | { ... } | BraceStmt | | declarations.swift:30:1:30:18 | var ... = ... | PatternBindingDecl | declarations.swift:30:5:30:5 | a_variable | NamedPattern | @@ -93,7 +93,7 @@ | declarations.swift:31:5:31:5 | a_property | ConcreteVarDecl | declarations.swift:32:3:34:3 | get | AccessorDecl | | declarations.swift:31:5:31:5 | a_property | ConcreteVarDecl | declarations.swift:35:3:35:18 | set | AccessorDecl | | declarations.swift:31:5:31:18 | ... as ... | TypedPattern | declarations.swift:31:5:31:5 | a_property | NamedPattern | -| declarations.swift:31:5:31:18 | ... as ... | TypedPattern | declarations.swift:31:18:31:18 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:31:5:31:18 | ... as ... | TypedPattern | declarations.swift:31:18:31:18 | String | TypeRepr | | declarations.swift:32:3:34:3 | get | AccessorDecl | declarations.swift:32:7:34:3 | { ... } | BraceStmt | | declarations.swift:32:7:34:3 | { ... } | BraceStmt | declarations.swift:33:5:33:12 | return ... | ReturnStmt | | declarations.swift:33:5:33:12 | return ... | ReturnStmt | declarations.swift:33:12:33:12 | here | StringLiteralExpr | @@ -118,7 +118,7 @@ | declarations.swift:41:7:41:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | declarations.swift:41:7:41:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:41:7:41:14 | ... as ... | TypedPattern | declarations.swift:41:7:41:7 | field | NamedPattern | -| declarations.swift:41:7:41:14 | ... as ... | TypedPattern | declarations.swift:41:14:41:14 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:41:7:41:14 | ... as ... | TypedPattern | declarations.swift:41:14:41:14 | Int | TypeRepr | | declarations.swift:42:3:44:3 | init | ConstructorDecl | declarations.swift:42:10:44:3 | { ... } | BraceStmt | | declarations.swift:42:10:44:3 | { ... } | BraceStmt | declarations.swift:43:5:43:13 | ... = ... | AssignExpr | | declarations.swift:42:10:44:3 | { ... } | BraceStmt | declarations.swift:44:3:44:3 | return | ReturnStmt | @@ -139,7 +139,7 @@ | declarations.swift:69:3:73:3 | var ... = ... | PatternBindingDecl | declarations.swift:69:7:69:21 | ... as ... | TypedPattern | | declarations.swift:69:7:69:7 | wrappedValue | ConcreteVarDecl | declarations.swift:70:5:72:5 | get | AccessorDecl | | declarations.swift:69:7:69:21 | ... as ... | TypedPattern | declarations.swift:69:7:69:7 | wrappedValue | NamedPattern | -| declarations.swift:69:7:69:21 | ... as ... | TypedPattern | declarations.swift:69:21:69:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:69:7:69:21 | ... as ... | TypedPattern | declarations.swift:69:21:69:21 | Int | TypeRepr | | declarations.swift:70:5:72:5 | get | AccessorDecl | declarations.swift:70:9:72:5 | { ... } | BraceStmt | | declarations.swift:70:9:72:5 | { ... } | BraceStmt | declarations.swift:71:7:71:14 | return ... | ReturnStmt | | declarations.swift:71:7:71:14 | return ... | ReturnStmt | declarations.swift:71:14:71:14 | 0 | IntegerLiteralExpr | @@ -147,7 +147,7 @@ | declarations.swift:76:19:79:1 | { ... } | BraceStmt | declarations.swift:77:16:77:23 | var ... = ... | PatternBindingDecl | | declarations.swift:76:19:79:1 | { ... } | BraceStmt | declarations.swift:77:20:77:20 | x | ConcreteVarDecl | | declarations.swift:76:19:79:1 | { ... } | BraceStmt | declarations.swift:78:3:78:10 | return ... | ReturnStmt | -| declarations.swift:77:4:77:4 | ZeroWrapper.Type | TypeExpr | declarations.swift:77:4:77:4 | FixedTypeRepr | FixedTypeRepr | +| declarations.swift:77:4:77:4 | ZeroWrapper.Type | TypeExpr | declarations.swift:77:4:77:4 | ZeroWrapper | TypeRepr | | declarations.swift:77:4:77:4 | call to ... | CallExpr | declarations.swift:77:4:77:4 | call to init | ConstructorRefCallExpr | | declarations.swift:77:4:77:4 | call to init | ConstructorRefCallExpr | declarations.swift:77:4:77:4 | init | DeclRefExpr | | declarations.swift:77:16:77:23 | var ... = ... | PatternBindingDecl | declarations.swift:77:20:77:23 | ... as ... | TypedPattern | @@ -156,7 +156,7 @@ | declarations.swift:77:20:77:20 | x | ConcreteVarDecl | declarations.swift:77:20:77:20 | get | AccessorDecl | | declarations.swift:77:20:77:20 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:77:20:77:23 | ... as ... | TypedPattern | declarations.swift:77:20:77:20 | x | NamedPattern | -| declarations.swift:77:20:77:23 | ... as ... | TypedPattern | declarations.swift:77:23:77:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:77:20:77:23 | ... as ... | TypedPattern | declarations.swift:77:23:77:23 | Int | TypeRepr | | declarations.swift:78:3:78:10 | return ... | ReturnStmt | declarations.swift:78:10:78:10 | x | DeclRefExpr | | declarations.swift:81:8:81:8 | init | ConstructorDecl | declarations.swift:81:8:81:8 | hasBoth | ParamDecl | | declarations.swift:81:8:81:8 | init | ConstructorDecl | declarations.swift:81:8:81:8 | hasDidSet1 | ParamDecl | @@ -172,7 +172,7 @@ | declarations.swift:82:7:82:7 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr | | declarations.swift:82:7:82:7 | { ... } | BraceStmt | declarations.swift:82:7:82:7 | yield ... | YieldStmt | | declarations.swift:82:7:82:22 | ... as ... | TypedPattern | declarations.swift:82:7:82:7 | settableField | NamedPattern | -| declarations.swift:82:7:82:22 | ... as ... | TypedPattern | declarations.swift:82:22:82:22 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:82:7:82:22 | ... as ... | TypedPattern | declarations.swift:82:22:82:22 | Int | TypeRepr | | declarations.swift:83:5:83:11 | set | AccessorDecl | declarations.swift:83:5:83:5 | newValue | ParamDecl | | declarations.swift:83:5:83:11 | set | AccessorDecl | declarations.swift:83:9:83:11 | { ... } | BraceStmt | | declarations.swift:84:5:86:5 | get | AccessorDecl | declarations.swift:84:9:86:5 | { ... } | BraceStmt | @@ -181,14 +181,14 @@ | declarations.swift:91:3:93:3 | var ... = ... | PatternBindingDecl | declarations.swift:91:7:91:23 | ... as ... | TypedPattern | | declarations.swift:91:7:91:7 | readOnlyField1 | ConcreteVarDecl | declarations.swift:91:27:93:3 | get | AccessorDecl | | declarations.swift:91:7:91:23 | ... as ... | TypedPattern | declarations.swift:91:7:91:7 | readOnlyField1 | NamedPattern | -| declarations.swift:91:7:91:23 | ... as ... | TypedPattern | declarations.swift:91:23:91:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:91:7:91:23 | ... as ... | TypedPattern | declarations.swift:91:23:91:23 | Int | TypeRepr | | declarations.swift:91:27:93:3 | get | AccessorDecl | declarations.swift:91:27:93:3 | { ... } | BraceStmt | | declarations.swift:91:27:93:3 | { ... } | BraceStmt | declarations.swift:92:5:92:12 | return ... | ReturnStmt | | declarations.swift:92:5:92:12 | return ... | ReturnStmt | declarations.swift:92:12:92:12 | 0 | IntegerLiteralExpr | | declarations.swift:96:3:100:3 | var ... = ... | PatternBindingDecl | declarations.swift:96:7:96:23 | ... as ... | TypedPattern | | declarations.swift:96:7:96:7 | readOnlyField2 | ConcreteVarDecl | declarations.swift:97:5:99:5 | get | AccessorDecl | | declarations.swift:96:7:96:23 | ... as ... | TypedPattern | declarations.swift:96:7:96:7 | readOnlyField2 | NamedPattern | -| declarations.swift:96:7:96:23 | ... as ... | TypedPattern | declarations.swift:96:23:96:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:96:7:96:23 | ... as ... | TypedPattern | declarations.swift:96:23:96:23 | Int | TypeRepr | | declarations.swift:97:5:99:5 | get | AccessorDecl | declarations.swift:97:9:99:5 | { ... } | BraceStmt | | declarations.swift:97:9:99:5 | { ... } | BraceStmt | declarations.swift:98:7:98:14 | return ... | ReturnStmt | | declarations.swift:98:7:98:14 | return ... | ReturnStmt | declarations.swift:98:14:98:14 | 0 | IntegerLiteralExpr | @@ -205,7 +205,7 @@ | declarations.swift:102:7:102:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | declarations.swift:102:7:102:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:102:7:102:21 | ... as ... | TypedPattern | declarations.swift:102:7:102:7 | normalField | NamedPattern | -| declarations.swift:102:7:102:21 | ... as ... | TypedPattern | declarations.swift:102:21:102:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:102:7:102:21 | ... as ... | TypedPattern | declarations.swift:102:21:102:21 | Int | TypeRepr | | declarations.swift:104:3:104:3 | (unnamed function decl) | AccessorDecl | declarations.swift:104:3:104:3 | { ... } | BraceStmt | | declarations.swift:104:3:104:3 | (unnamed function decl) | AccessorDecl | file://:0:0:0:0 | x | ParamDecl | | declarations.swift:104:3:104:3 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr | @@ -244,7 +244,7 @@ | declarations.swift:115:7:115:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr | | declarations.swift:115:7:115:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:115:7:115:21 | ... as ... | TypedPattern | declarations.swift:115:7:115:7 | hasWillSet1 | NamedPattern | -| declarations.swift:115:7:115:21 | ... as ... | TypedPattern | declarations.swift:115:21:115:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:115:7:115:21 | ... as ... | TypedPattern | declarations.swift:115:21:115:21 | Int | TypeRepr | | declarations.swift:116:5:116:25 | willSet | AccessorDecl | declarations.swift:116:13:116:13 | newValue | ParamDecl | | declarations.swift:116:5:116:25 | willSet | AccessorDecl | declarations.swift:116:23:116:25 | { ... } | BraceStmt | | declarations.swift:119:3:121:3 | var ... = ... | PatternBindingDecl | declarations.swift:119:7:119:21 | ... as ... | TypedPattern | @@ -262,7 +262,7 @@ | declarations.swift:119:7:119:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr | | declarations.swift:119:7:119:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:119:7:119:21 | ... as ... | TypedPattern | declarations.swift:119:7:119:7 | hasWillSet2 | NamedPattern | -| declarations.swift:119:7:119:21 | ... as ... | TypedPattern | declarations.swift:119:21:119:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:119:7:119:21 | ... as ... | TypedPattern | declarations.swift:119:21:119:21 | Int | TypeRepr | | declarations.swift:120:5:120:15 | willSet | AccessorDecl | declarations.swift:120:5:120:5 | newValue | ParamDecl | | declarations.swift:120:5:120:15 | willSet | AccessorDecl | declarations.swift:120:13:120:15 | { ... } | BraceStmt | | declarations.swift:123:3:125:3 | var ... = ... | PatternBindingDecl | declarations.swift:123:7:123:20 | ... as ... | TypedPattern | @@ -282,7 +282,7 @@ | declarations.swift:123:7:123:7 | { ... } | BraceStmt | file://:0:0:0:0 | tmp | ConcreteVarDecl | | declarations.swift:123:7:123:7 | { ... } | BraceStmt | file://:0:0:0:0 | var ... = ... | PatternBindingDecl | | declarations.swift:123:7:123:20 | ... as ... | TypedPattern | declarations.swift:123:7:123:7 | hasDidSet1 | NamedPattern | -| declarations.swift:123:7:123:20 | ... as ... | TypedPattern | declarations.swift:123:20:123:20 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:123:7:123:20 | ... as ... | TypedPattern | declarations.swift:123:20:123:20 | Int | TypeRepr | | declarations.swift:124:5:124:24 | didSet | AccessorDecl | declarations.swift:124:12:124:12 | oldValue | ParamDecl | | declarations.swift:124:5:124:24 | didSet | AccessorDecl | declarations.swift:124:22:124:24 | { ... } | BraceStmt | | declarations.swift:127:3:129:3 | var ... = ... | PatternBindingDecl | declarations.swift:127:7:127:20 | ... as ... | TypedPattern | @@ -301,7 +301,7 @@ | declarations.swift:127:7:127:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr | | declarations.swift:127:7:127:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:127:7:127:20 | ... as ... | TypedPattern | declarations.swift:127:7:127:7 | hasDidSet2 | NamedPattern | -| declarations.swift:127:7:127:20 | ... as ... | TypedPattern | declarations.swift:127:20:127:20 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:127:7:127:20 | ... as ... | TypedPattern | declarations.swift:127:20:127:20 | Int | TypeRepr | | declarations.swift:128:5:128:14 | didSet | AccessorDecl | declarations.swift:128:12:128:14 | { ... } | BraceStmt | | declarations.swift:131:3:135:3 | var ... = ... | PatternBindingDecl | declarations.swift:131:7:131:17 | ... as ... | TypedPattern | | declarations.swift:131:7:131:7 | (unnamed function decl) | AccessorDecl | declarations.swift:131:7:131:7 | { ... } | BraceStmt | @@ -320,7 +320,7 @@ | declarations.swift:131:7:131:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr | | declarations.swift:131:7:131:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:131:7:131:17 | ... as ... | TypedPattern | declarations.swift:131:7:131:7 | hasBoth | NamedPattern | -| declarations.swift:131:7:131:17 | ... as ... | TypedPattern | declarations.swift:131:17:131:17 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:131:7:131:17 | ... as ... | TypedPattern | declarations.swift:131:17:131:17 | Int | TypeRepr | | declarations.swift:132:5:132:15 | willSet | AccessorDecl | declarations.swift:132:5:132:5 | newValue | ParamDecl | | declarations.swift:132:5:132:15 | willSet | AccessorDecl | declarations.swift:132:13:132:15 | { ... } | BraceStmt | | declarations.swift:134:5:134:14 | didSet | AccessorDecl | declarations.swift:134:12:134:14 | { ... } | BraceStmt | @@ -382,7 +382,7 @@ | expressions.swift:8:1:8:15 | { ... } | BraceStmt | expressions.swift:8:1:8:15 | var ... = ... | PatternBindingDecl | | expressions.swift:8:1:8:15 | { ... } | TopLevelCodeDecl | expressions.swift:8:1:8:15 | { ... } | BraceStmt | | expressions.swift:8:5:8:11 | ... as ... | TypedPattern | expressions.swift:8:5:8:5 | n | NamedPattern | -| expressions.swift:8:5:8:11 | ... as ... | TypedPattern | expressions.swift:8:8:8:11 | ...? | OptionalTypeRepr | +| expressions.swift:8:5:8:11 | ... as ... | TypedPattern | expressions.swift:8:8:8:11 | Int? | TypeRepr | | expressions.swift:11:3:11:8 | case ... | EnumCaseDecl | expressions.swift:11:8:11:8 | failed | EnumElementDecl | | expressions.swift:14:1:18:1 | failure(_:) | ConcreteFuncDecl | expressions.swift:14:14:14:19 | x | ParamDecl | | expressions.swift:14:1:18:1 | failure(_:) | ConcreteFuncDecl | expressions.swift:14:31:18:1 | { ... } | BraceStmt | @@ -390,11 +390,11 @@ | expressions.swift:15:3:17:3 | guard ... else { ... } | GuardStmt | expressions.swift:15:9:15:14 | StmtCondition | StmtCondition | | expressions.swift:15:3:17:3 | guard ... else { ... } | GuardStmt | expressions.swift:15:21:17:3 | { ... } | BraceStmt | | expressions.swift:15:9:15:14 | ... call to !=(_:_:) ... | BinaryExpr | expressions.swift:15:11:15:11 | call to !=(_:_:) | DotSyntaxCallExpr | -| expressions.swift:15:11:15:11 | Int.Type | TypeExpr | expressions.swift:15:11:15:11 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:15:11:15:11 | Int.Type | TypeExpr | expressions.swift:15:11:15:11 | Int | TypeRepr | | expressions.swift:15:11:15:11 | call to !=(_:_:) | DotSyntaxCallExpr | expressions.swift:15:11:15:11 | !=(_:_:) | DeclRefExpr | | expressions.swift:15:21:17:3 | { ... } | BraceStmt | expressions.swift:16:5:16:19 | throw ... | ThrowStmt | | expressions.swift:16:5:16:19 | throw ... | ThrowStmt | expressions.swift:16:11:16:19 | (Error) ... | ErasureExpr | -| expressions.swift:16:11:16:11 | AnError.Type | TypeExpr | expressions.swift:16:11:16:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:16:11:16:11 | AnError.Type | TypeExpr | expressions.swift:16:11:16:11 | AnError | TypeRepr | | expressions.swift:16:11:16:19 | (Error) ... | ErasureExpr | expressions.swift:16:11:16:19 | call to ... | DotSyntaxCallExpr | | expressions.swift:16:11:16:19 | call to ... | DotSyntaxCallExpr | expressions.swift:16:19:16:19 | failed | DeclRefExpr | | expressions.swift:20:1:20:16 | try! ... | ForceTryExpr | expressions.swift:20:6:20:16 | call to failure(_:) | CallExpr | @@ -413,7 +413,7 @@ | expressions.swift:27:1:27:19 | var ... = ... | PatternBindingDecl | expressions.swift:27:13:27:19 | call to ... | CallExpr | | expressions.swift:27:1:27:19 | { ... } | BraceStmt | expressions.swift:27:1:27:19 | var ... = ... | PatternBindingDecl | | expressions.swift:27:1:27:19 | { ... } | TopLevelCodeDecl | expressions.swift:27:1:27:19 | { ... } | BraceStmt | -| expressions.swift:27:13:27:13 | Klass.Type | TypeExpr | expressions.swift:27:13:27:13 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:27:13:27:13 | Klass.Type | TypeExpr | expressions.swift:27:13:27:13 | Klass | TypeRepr | | expressions.swift:27:13:27:13 | call to init | ConstructorRefCallExpr | expressions.swift:27:13:27:13 | init | DeclRefExpr | | expressions.swift:27:13:27:19 | call to ... | CallExpr | expressions.swift:27:13:27:13 | call to init | ConstructorRefCallExpr | | expressions.swift:29:1:29:19 | var ... = ... | PatternBindingDecl | expressions.swift:29:5:29:5 | d | NamedPattern | @@ -467,7 +467,7 @@ | expressions.swift:41:10:43:1 | { ... } | ClosureExpr | expressions.swift:41:21:41:24 | y | ParamDecl | | expressions.swift:42:5:42:16 | return ... | ReturnStmt | expressions.swift:42:12:42:16 | ... call to +(_:_:) ... | BinaryExpr | | expressions.swift:42:12:42:16 | ... call to +(_:_:) ... | BinaryExpr | expressions.swift:42:14:42:14 | call to +(_:_:) | DotSyntaxCallExpr | -| expressions.swift:42:14:42:14 | Int.Type | TypeExpr | expressions.swift:42:14:42:14 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:42:14:42:14 | Int.Type | TypeExpr | expressions.swift:42:14:42:14 | Int | TypeRepr | | expressions.swift:42:14:42:14 | call to +(_:_:) | DotSyntaxCallExpr | expressions.swift:42:14:42:14 | +(_:_:) | DeclRefExpr | | expressions.swift:44:1:46:1 | call to closured(closure:) | CallExpr | expressions.swift:44:1:44:1 | closured(closure:) | DeclRefExpr | | expressions.swift:44:1:46:1 | { ... } | BraceStmt | expressions.swift:44:1:46:1 | call to closured(closure:) | CallExpr | @@ -478,7 +478,7 @@ | expressions.swift:44:10:46:1 | { ... } | ClosureExpr | expressions.swift:44:15:44:15 | y | ParamDecl | | expressions.swift:45:5:45:16 | return ... | ReturnStmt | expressions.swift:45:12:45:16 | ... call to +(_:_:) ... | BinaryExpr | | expressions.swift:45:12:45:16 | ... call to +(_:_:) ... | BinaryExpr | expressions.swift:45:14:45:14 | call to +(_:_:) | DotSyntaxCallExpr | -| expressions.swift:45:14:45:14 | Int.Type | TypeExpr | expressions.swift:45:14:45:14 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:45:14:45:14 | Int.Type | TypeExpr | expressions.swift:45:14:45:14 | Int | TypeRepr | | expressions.swift:45:14:45:14 | call to +(_:_:) | DotSyntaxCallExpr | expressions.swift:45:14:45:14 | +(_:_:) | DeclRefExpr | | expressions.swift:47:1:47:27 | call to closured(closure:) | CallExpr | expressions.swift:47:1:47:1 | closured(closure:) | DeclRefExpr | | expressions.swift:47:1:47:27 | { ... } | BraceStmt | expressions.swift:47:1:47:27 | call to closured(closure:) | CallExpr | @@ -489,7 +489,7 @@ | expressions.swift:47:10:47:27 | { ... } | ClosureExpr | expressions.swift:47:10:47:27 | { ... } | BraceStmt | | expressions.swift:47:12:47:24 | return ... | ReturnStmt | expressions.swift:47:19:47:24 | ... call to +(_:_:) ... | BinaryExpr | | expressions.swift:47:19:47:24 | ... call to +(_:_:) ... | BinaryExpr | expressions.swift:47:22:47:22 | call to +(_:_:) | DotSyntaxCallExpr | -| expressions.swift:47:22:47:22 | Int.Type | TypeExpr | expressions.swift:47:22:47:22 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:47:22:47:22 | Int.Type | TypeExpr | expressions.swift:47:22:47:22 | Int | TypeRepr | | expressions.swift:47:22:47:22 | call to +(_:_:) | DotSyntaxCallExpr | expressions.swift:47:22:47:22 | +(_:_:) | DeclRefExpr | | expressions.swift:48:1:48:20 | call to closured(closure:) | CallExpr | expressions.swift:48:1:48:1 | closured(closure:) | DeclRefExpr | | expressions.swift:48:1:48:20 | { ... } | BraceStmt | expressions.swift:48:1:48:20 | call to closured(closure:) | CallExpr | @@ -500,7 +500,7 @@ | expressions.swift:48:10:48:20 | { ... } | ClosureExpr | expressions.swift:48:10:48:20 | { ... } | BraceStmt | | expressions.swift:48:12:48:17 | ... call to +(_:_:) ... | BinaryExpr | expressions.swift:48:15:48:15 | call to +(_:_:) | DotSyntaxCallExpr | | expressions.swift:48:12:48:17 | return ... | ReturnStmt | expressions.swift:48:12:48:17 | ... call to +(_:_:) ... | BinaryExpr | -| expressions.swift:48:15:48:15 | Int.Type | TypeExpr | expressions.swift:48:15:48:15 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:48:15:48:15 | Int.Type | TypeExpr | expressions.swift:48:15:48:15 | Int | TypeRepr | | expressions.swift:48:15:48:15 | call to +(_:_:) | DotSyntaxCallExpr | expressions.swift:48:15:48:15 | +(_:_:) | DeclRefExpr | | expressions.swift:50:8:50:8 | init | ConstructorDecl | expressions.swift:50:8:50:8 | x | ParamDecl | | expressions.swift:51:3:51:10 | var ... = ... | PatternBindingDecl | expressions.swift:51:7:51:10 | ... as ... | TypedPattern | @@ -508,14 +508,12 @@ | expressions.swift:51:7:51:7 | x | ConcreteVarDecl | expressions.swift:51:7:51:7 | get | AccessorDecl | | expressions.swift:51:7:51:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:51:7:51:10 | ... as ... | TypedPattern | expressions.swift:51:7:51:7 | x | NamedPattern | -| expressions.swift:51:7:51:10 | ... as ... | TypedPattern | expressions.swift:51:10:51:10 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:51:7:51:10 | ... as ... | TypedPattern | expressions.swift:51:10:51:10 | Int | TypeRepr | | expressions.swift:54:1:54:8 | ... = ... | AssignExpr | expressions.swift:54:1:54:1 | _ | DiscardAssignmentExpr | | expressions.swift:54:1:54:8 | ... = ... | AssignExpr | expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr | | expressions.swift:54:1:54:8 | { ... } | BraceStmt | expressions.swift:54:1:54:8 | ... = ... | AssignExpr | | expressions.swift:54:1:54:8 | { ... } | TopLevelCodeDecl | expressions.swift:54:1:54:8 | { ... } | BraceStmt | -| expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr | expressions.swift:54:6:54:8 | ... .x | UnresolvedDotExpr | -| expressions.swift:54:6:54:6 | (no string representation) | TypeExpr | expressions.swift:54:6:54:6 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | -| expressions.swift:54:6:54:8 | ... .x | UnresolvedDotExpr | expressions.swift:54:6:54:6 | (no string representation) | TypeExpr | +| expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr | expressions.swift:54:6:54:6 | S | TypeRepr | | expressions.swift:56:1:57:1 | unsafeFunction(pointer:) | ConcreteFuncDecl | expressions.swift:56:21:56:47 | pointer | ParamDecl | | expressions.swift:56:1:57:1 | unsafeFunction(pointer:) | ConcreteFuncDecl | expressions.swift:56:50:57:1 | { ... } | BraceStmt | | expressions.swift:58:1:58:16 | var ... = ... | PatternBindingDecl | expressions.swift:58:5:58:5 | myNumber | NamedPattern | @@ -545,7 +543,7 @@ | expressions.swift:64:5:66:5 | if ... then { ... } | IfStmt | expressions.swift:64:8:64:12 | StmtCondition | StmtCondition | | expressions.swift:64:5:66:5 | if ... then { ... } | IfStmt | expressions.swift:64:14:66:5 | { ... } | BraceStmt | | expressions.swift:64:8:64:12 | ... call to <(_:_:) ... | BinaryExpr | expressions.swift:64:10:64:10 | call to <(_:_:) | DotSyntaxCallExpr | -| expressions.swift:64:10:64:10 | Int.Type | TypeExpr | expressions.swift:64:10:64:10 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:64:10:64:10 | Int.Type | TypeExpr | expressions.swift:64:10:64:10 | Int | TypeRepr | | expressions.swift:64:10:64:10 | call to <(_:_:) | DotSyntaxCallExpr | expressions.swift:64:10:64:10 | <(_:_:) | DeclRefExpr | | expressions.swift:64:14:66:5 | { ... } | BraceStmt | expressions.swift:65:7:65:14 | fail | FailStmt | | expressions.swift:70:7:70:7 | deinit | DestructorDecl | expressions.swift:70:7:70:7 | { ... } | BraceStmt | @@ -554,7 +552,7 @@ | expressions.swift:71:7:71:7 | xx | ConcreteVarDecl | expressions.swift:71:7:71:7 | get | AccessorDecl | | expressions.swift:71:7:71:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:71:7:71:11 | ... as ... | TypedPattern | expressions.swift:71:7:71:7 | xx | NamedPattern | -| expressions.swift:71:7:71:11 | ... as ... | TypedPattern | expressions.swift:71:11:71:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:71:7:71:11 | ... as ... | TypedPattern | expressions.swift:71:11:71:11 | Int | TypeRepr | | expressions.swift:72:3:74:3 | init | ConstructorDecl | expressions.swift:72:8:72:11 | x | ParamDecl | | expressions.swift:72:3:74:3 | init | ConstructorDecl | expressions.swift:72:16:74:3 | { ... } | BraceStmt | | expressions.swift:72:16:74:3 | { ... } | BraceStmt | expressions.swift:73:5:73:10 | ... = ... | AssignExpr | @@ -577,7 +575,7 @@ | expressions.swift:83:1:83:23 | var ... = ... | PatternBindingDecl | expressions.swift:83:15:83:23 | call to ... | CallExpr | | expressions.swift:83:1:83:23 | { ... } | BraceStmt | expressions.swift:83:1:83:23 | var ... = ... | PatternBindingDecl | | expressions.swift:83:1:83:23 | { ... } | TopLevelCodeDecl | expressions.swift:83:1:83:23 | { ... } | BraceStmt | -| expressions.swift:83:15:83:15 | Derived.Type | TypeExpr | expressions.swift:83:15:83:15 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:83:15:83:15 | Derived.Type | TypeExpr | expressions.swift:83:15:83:15 | Derived | TypeRepr | | expressions.swift:83:15:83:15 | call to init | ConstructorRefCallExpr | expressions.swift:83:15:83:15 | init | DeclRefExpr | | expressions.swift:83:15:83:23 | call to ... | CallExpr | expressions.swift:83:15:83:15 | call to init | ConstructorRefCallExpr | | expressions.swift:84:1:84:13 | ... = ... | AssignExpr | expressions.swift:84:1:84:1 | _ | DiscardAssignmentExpr | @@ -591,7 +589,7 @@ | expressions.swift:86:1:86:13 | { ... } | BraceStmt | expressions.swift:86:1:86:13 | var ... = ... | PatternBindingDecl | | expressions.swift:86:1:86:13 | { ... } | TopLevelCodeDecl | expressions.swift:86:1:86:13 | { ... } | BraceStmt | | expressions.swift:86:5:86:13 | ... as ... | TypedPattern | expressions.swift:86:5:86:5 | opt | NamedPattern | -| expressions.swift:86:5:86:13 | ... as ... | TypedPattern | expressions.swift:86:10:86:13 | ...? | OptionalTypeRepr | +| expressions.swift:86:5:86:13 | ... as ... | TypedPattern | expressions.swift:86:10:86:13 | Int? | TypeRepr | | expressions.swift:87:1:87:4 | ...! | ForceValueExpr | expressions.swift:87:1:87:1 | opt | DeclRefExpr | | expressions.swift:87:1:87:4 | { ... } | BraceStmt | expressions.swift:87:1:87:4 | ...! | ForceValueExpr | | expressions.swift:87:1:87:4 | { ... } | TopLevelCodeDecl | expressions.swift:87:1:87:4 | { ... } | BraceStmt | @@ -606,15 +604,15 @@ | expressions.swift:92:1:92:55 | var ... = ... | PatternBindingDecl | expressions.swift:92:14:92:55 | call to ... | CallExpr | | expressions.swift:92:1:92:55 | { ... } | BraceStmt | expressions.swift:92:1:92:55 | var ... = ... | PatternBindingDecl | | expressions.swift:92:1:92:55 | { ... } | TopLevelCodeDecl | expressions.swift:92:1:92:55 | { ... } | BraceStmt | -| expressions.swift:92:14:92:14 | Unmanaged.Type | TypeExpr | expressions.swift:92:14:92:14 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:92:14:92:14 | Unmanaged.Type | TypeExpr | expressions.swift:92:14:92:14 | Unmanaged | TypeRepr | | expressions.swift:92:14:92:24 | call to passRetained(_:) | DotSyntaxCallExpr | expressions.swift:92:24:92:24 | passRetained(_:) | DeclRefExpr | | expressions.swift:92:14:92:44 | call to ... | CallExpr | expressions.swift:92:14:92:24 | call to passRetained(_:) | DotSyntaxCallExpr | | expressions.swift:92:14:92:46 | call to toOpaque() | DotSyntaxCallExpr | expressions.swift:92:46:92:46 | toOpaque() | DeclRefExpr | | expressions.swift:92:14:92:55 | call to ... | CallExpr | expressions.swift:92:14:92:46 | call to toOpaque() | DotSyntaxCallExpr | -| expressions.swift:92:37:92:37 | ToPtr.Type | TypeExpr | expressions.swift:92:37:92:37 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:92:37:92:37 | ToPtr.Type | TypeExpr | expressions.swift:92:37:92:37 | ToPtr | TypeRepr | | expressions.swift:92:37:92:37 | call to init | ConstructorRefCallExpr | expressions.swift:92:37:92:37 | init | DeclRefExpr | | expressions.swift:92:37:92:43 | call to ... | CallExpr | expressions.swift:92:37:92:37 | call to init | ConstructorRefCallExpr | -| expressions.swift:93:1:93:16 | Unmanaged.Type | TypeExpr | expressions.swift:93:1:93:16 | ...<...> | GenericIdentTypeRepr | +| expressions.swift:93:1:93:16 | Unmanaged.Type | TypeExpr | expressions.swift:93:1:93:16 | Unmanaged | TypeRepr | | expressions.swift:93:1:93:18 | call to fromOpaque(_:) | DotSyntaxCallExpr | expressions.swift:93:18:93:18 | fromOpaque(_:) | DeclRefExpr | | expressions.swift:93:1:93:35 | call to ... | CallExpr | expressions.swift:93:1:93:18 | call to fromOpaque(_:) | DotSyntaxCallExpr | | expressions.swift:93:1:93:35 | { ... } | BraceStmt | expressions.swift:93:1:93:35 | call to ... | CallExpr | @@ -629,7 +627,7 @@ | expressions.swift:96:7:96:7 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr | | expressions.swift:96:7:96:7 | { ... } | BraceStmt | expressions.swift:96:7:96:7 | yield ... | YieldStmt | | expressions.swift:96:7:96:22 | ... as ... | TypedPattern | expressions.swift:96:7:96:7 | settableField | NamedPattern | -| expressions.swift:96:7:96:22 | ... as ... | TypedPattern | expressions.swift:96:22:96:22 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:96:7:96:22 | ... as ... | TypedPattern | expressions.swift:96:22:96:22 | Int | TypeRepr | | expressions.swift:97:5:97:11 | set | AccessorDecl | expressions.swift:97:5:97:5 | newValue | ParamDecl | | expressions.swift:97:5:97:11 | set | AccessorDecl | expressions.swift:97:9:97:11 | { ... } | BraceStmt | | expressions.swift:98:5:100:5 | get | AccessorDecl | expressions.swift:98:9:100:5 | { ... } | BraceStmt | @@ -638,14 +636,14 @@ | expressions.swift:105:3:107:3 | var ... = ... | PatternBindingDecl | expressions.swift:105:7:105:23 | ... as ... | TypedPattern | | expressions.swift:105:7:105:7 | readOnlyField1 | ConcreteVarDecl | expressions.swift:105:27:107:3 | get | AccessorDecl | | expressions.swift:105:7:105:23 | ... as ... | TypedPattern | expressions.swift:105:7:105:7 | readOnlyField1 | NamedPattern | -| expressions.swift:105:7:105:23 | ... as ... | TypedPattern | expressions.swift:105:23:105:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:105:7:105:23 | ... as ... | TypedPattern | expressions.swift:105:23:105:23 | Int | TypeRepr | | expressions.swift:105:27:107:3 | get | AccessorDecl | expressions.swift:105:27:107:3 | { ... } | BraceStmt | | expressions.swift:105:27:107:3 | { ... } | BraceStmt | expressions.swift:106:5:106:12 | return ... | ReturnStmt | | expressions.swift:106:5:106:12 | return ... | ReturnStmt | expressions.swift:106:12:106:12 | 0 | IntegerLiteralExpr | | expressions.swift:110:3:114:3 | var ... = ... | PatternBindingDecl | expressions.swift:110:7:110:23 | ... as ... | TypedPattern | | expressions.swift:110:7:110:7 | readOnlyField2 | ConcreteVarDecl | expressions.swift:111:5:113:5 | get | AccessorDecl | | expressions.swift:110:7:110:23 | ... as ... | TypedPattern | expressions.swift:110:7:110:7 | readOnlyField2 | NamedPattern | -| expressions.swift:110:7:110:23 | ... as ... | TypedPattern | expressions.swift:110:23:110:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:110:7:110:23 | ... as ... | TypedPattern | expressions.swift:110:23:110:23 | Int | TypeRepr | | expressions.swift:111:5:113:5 | get | AccessorDecl | expressions.swift:111:9:113:5 | { ... } | BraceStmt | | expressions.swift:111:9:113:5 | { ... } | BraceStmt | expressions.swift:112:7:112:14 | return ... | ReturnStmt | | expressions.swift:112:7:112:14 | return ... | ReturnStmt | expressions.swift:112:14:112:14 | 0 | IntegerLiteralExpr | @@ -662,7 +660,7 @@ | expressions.swift:116:7:116:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | expressions.swift:116:7:116:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:116:7:116:21 | ... as ... | TypedPattern | expressions.swift:116:7:116:7 | normalField | NamedPattern | -| expressions.swift:116:7:116:21 | ... as ... | TypedPattern | expressions.swift:116:21:116:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:116:7:116:21 | ... as ... | TypedPattern | expressions.swift:116:21:116:21 | Int | TypeRepr | | expressions.swift:118:3:118:3 | (unnamed function decl) | AccessorDecl | expressions.swift:118:3:118:3 | { ... } | BraceStmt | | expressions.swift:118:3:118:3 | (unnamed function decl) | AccessorDecl | file://:0:0:0:0 | x | ParamDecl | | expressions.swift:118:3:118:3 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr | @@ -743,7 +741,7 @@ | expressions.swift:142:7:142:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | expressions.swift:142:7:142:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:142:7:142:11 | ... as ... | TypedPattern | expressions.swift:142:7:142:7 | x | NamedPattern | -| expressions.swift:142:7:142:11 | ... as ... | TypedPattern | expressions.swift:142:11:142:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:142:7:142:11 | ... as ... | TypedPattern | expressions.swift:142:11:142:11 | Int | TypeRepr | | expressions.swift:145:8:145:8 | init | ConstructorDecl | expressions.swift:145:8:145:8 | b | ParamDecl | | expressions.swift:145:8:145:8 | init | ConstructorDecl | expressions.swift:145:8:145:8 | bs | ParamDecl | | expressions.swift:145:8:145:8 | init | ConstructorDecl | expressions.swift:145:8:145:8 | mayB | ParamDecl | @@ -760,7 +758,7 @@ | expressions.swift:146:7:146:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | expressions.swift:146:7:146:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:146:7:146:11 | ... as ... | TypedPattern | expressions.swift:146:7:146:7 | b | NamedPattern | -| expressions.swift:146:7:146:11 | ... as ... | TypedPattern | expressions.swift:146:11:146:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:146:7:146:11 | ... as ... | TypedPattern | expressions.swift:146:11:146:11 | B | TypeRepr | | expressions.swift:147:3:147:14 | var ... = ... | PatternBindingDecl | expressions.swift:147:7:147:14 | ... as ... | TypedPattern | | expressions.swift:147:7:147:7 | (unnamed function decl) | AccessorDecl | expressions.swift:147:7:147:7 | { ... } | BraceStmt | | expressions.swift:147:7:147:7 | bs | ConcreteVarDecl | expressions.swift:147:7:147:7 | (unnamed function decl) | AccessorDecl | @@ -774,7 +772,7 @@ | expressions.swift:147:7:147:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | expressions.swift:147:7:147:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:147:7:147:14 | ... as ... | TypedPattern | expressions.swift:147:7:147:7 | bs | NamedPattern | -| expressions.swift:147:7:147:14 | ... as ... | TypedPattern | expressions.swift:147:12:147:14 | [...] | ArrayTypeRepr | +| expressions.swift:147:7:147:14 | ... as ... | TypedPattern | expressions.swift:147:12:147:14 | [B] | TypeRepr | | expressions.swift:148:3:148:15 | var ... = ... | PatternBindingDecl | expressions.swift:148:7:148:15 | ... as ... | TypedPattern | | expressions.swift:148:3:148:15 | var ... = ... | PatternBindingDecl | file://:0:0:0:0 | nil | NilLiteralExpr | | expressions.swift:148:7:148:7 | (unnamed function decl) | AccessorDecl | expressions.swift:148:7:148:7 | { ... } | BraceStmt | @@ -789,7 +787,7 @@ | expressions.swift:148:7:148:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | expressions.swift:148:7:148:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:148:7:148:15 | ... as ... | TypedPattern | expressions.swift:148:7:148:7 | mayB | NamedPattern | -| expressions.swift:148:7:148:15 | ... as ... | TypedPattern | expressions.swift:148:14:148:15 | ...? | OptionalTypeRepr | +| expressions.swift:148:7:148:15 | ... as ... | TypedPattern | expressions.swift:148:14:148:15 | B? | TypeRepr | | expressions.swift:151:1:155:1 | test(a:keyPathInt:keyPathB:) | ConcreteFuncDecl | expressions.swift:151:11:151:15 | a | ParamDecl | | expressions.swift:151:1:155:1 | test(a:keyPathInt:keyPathB:) | ConcreteFuncDecl | expressions.swift:151:18:151:53 | keyPathInt | ParamDecl | | expressions.swift:151:1:155:1 | test(a:keyPathInt:keyPathB:) | ConcreteFuncDecl | expressions.swift:151:56:151:87 | keyPathB | ParamDecl | @@ -814,9 +812,7 @@ | expressions.swift:154:22:154:41 | \\...[...] | KeyPathApplicationExpr | expressions.swift:154:33:154:33 | keyPathB | DeclRefExpr | | expressions.swift:154:22:154:56 | \\...[...] | KeyPathApplicationExpr | expressions.swift:154:22:154:41 | \\...[...] | KeyPathApplicationExpr | | expressions.swift:154:22:154:56 | \\...[...] | KeyPathApplicationExpr | expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr | -| expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr | expressions.swift:154:53:154:55 | ... .x | UnresolvedDotExpr | -| expressions.swift:154:53:154:53 | (no string representation) | TypeExpr | expressions.swift:154:53:154:53 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | -| expressions.swift:154:53:154:55 | ... .x | UnresolvedDotExpr | expressions.swift:154:53:154:53 | (no string representation) | TypeExpr | +| expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr | expressions.swift:154:53:154:53 | B | TypeRepr | | patterns.swift:1:1:7:1 | basic_patterns() | ConcreteFuncDecl | patterns.swift:1:23:7:1 | { ... } | BraceStmt | | patterns.swift:1:23:7:1 | { ... } | BraceStmt | patterns.swift:2:5:2:18 | var ... = ... | PatternBindingDecl | | patterns.swift:1:23:7:1 | { ... } | BraceStmt | patterns.swift:2:9:2:9 | an_int | ConcreteVarDecl | @@ -833,7 +829,7 @@ | patterns.swift:3:5:3:28 | var ... = ... | PatternBindingDecl | patterns.swift:3:9:3:19 | ... as ... | TypedPattern | | patterns.swift:3:5:3:28 | var ... = ... | PatternBindingDecl | patterns.swift:3:28:3:28 | here | StringLiteralExpr | | patterns.swift:3:9:3:19 | ... as ... | TypedPattern | patterns.swift:3:9:3:9 | a_string | NamedPattern | -| patterns.swift:3:9:3:19 | ... as ... | TypedPattern | patterns.swift:3:19:3:19 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| patterns.swift:3:9:3:19 | ... as ... | TypedPattern | patterns.swift:3:19:3:19 | String | TypeRepr | | patterns.swift:4:5:4:29 | var ... = ... | PatternBindingDecl | patterns.swift:4:9:4:17 | (...) | TuplePattern | | patterns.swift:4:5:4:29 | var ... = ... | PatternBindingDecl | patterns.swift:4:21:4:29 | (...) | TupleExpr | | patterns.swift:4:9:4:17 | (...) | TuplePattern | patterns.swift:4:10:4:10 | x | NamedPattern | @@ -900,8 +896,8 @@ | patterns.swift:24:5:24:19 | var ... = ... | PatternBindingDecl | patterns.swift:24:9:24:12 | ... as ... | TypedPattern | | patterns.swift:24:5:24:19 | var ... = ... | PatternBindingDecl | patterns.swift:24:18:24:19 | call to ... | DotSyntaxCallExpr | | patterns.swift:24:9:24:12 | ... as ... | TypedPattern | patterns.swift:24:9:24:9 | v | NamedPattern | -| patterns.swift:24:9:24:12 | ... as ... | TypedPattern | patterns.swift:24:12:24:12 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | -| patterns.swift:24:18:24:18 | Foo.Type | TypeExpr | patterns.swift:24:18:24:18 | FixedTypeRepr | FixedTypeRepr | +| patterns.swift:24:9:24:12 | ... as ... | TypedPattern | patterns.swift:24:12:24:12 | Foo | TypeRepr | +| patterns.swift:24:18:24:18 | Foo.Type | TypeExpr | patterns.swift:24:18:24:18 | Foo | TypeRepr | | patterns.swift:24:18:24:19 | call to ... | DotSyntaxCallExpr | patterns.swift:24:19:24:19 | bar | DeclRefExpr | | patterns.swift:26:5:29:5 | switch v { ... } | SwitchStmt | patterns.swift:26:12:26:12 | v | DeclRefExpr | | patterns.swift:26:5:29:5 | switch v { ... } | SwitchStmt | patterns.swift:27:5:27:16 | case ... | CaseStmt | @@ -921,7 +917,7 @@ | patterns.swift:31:5:31:19 | var ... = ... | PatternBindingDecl | patterns.swift:31:9:31:15 | ... as ... | TypedPattern | | patterns.swift:31:5:31:19 | var ... = ... | PatternBindingDecl | patterns.swift:31:19:31:19 | nil | NilLiteralExpr | | patterns.swift:31:9:31:15 | ... as ... | TypedPattern | patterns.swift:31:9:31:9 | w | NamedPattern | -| patterns.swift:31:9:31:15 | ... as ... | TypedPattern | patterns.swift:31:12:31:15 | ...? | OptionalTypeRepr | +| patterns.swift:31:9:31:15 | ... as ... | TypedPattern | patterns.swift:31:12:31:15 | Int? | TypeRepr | | patterns.swift:33:5:36:5 | switch w { ... } | SwitchStmt | patterns.swift:33:12:33:12 | w | DeclRefExpr | | patterns.swift:33:5:36:5 | switch w { ... } | SwitchStmt | patterns.swift:34:5:34:18 | case ... | CaseStmt | | patterns.swift:33:5:36:5 | switch w { ... } | SwitchStmt | patterns.swift:35:5:35:13 | case ... | CaseStmt | @@ -938,7 +934,7 @@ | patterns.swift:38:5:38:18 | var ... = ... | PatternBindingDecl | patterns.swift:38:9:38:12 | ... as ... | TypedPattern | | patterns.swift:38:5:38:18 | var ... = ... | PatternBindingDecl | patterns.swift:38:18:38:18 | (Any) ... | ErasureExpr | | patterns.swift:38:9:38:12 | ... as ... | TypedPattern | patterns.swift:38:9:38:9 | a | NamedPattern | -| patterns.swift:38:9:38:12 | ... as ... | TypedPattern | patterns.swift:38:12:38:12 | CompositionTypeRepr | CompositionTypeRepr | +| patterns.swift:38:9:38:12 | ... as ... | TypedPattern | patterns.swift:38:12:38:12 | Any | TypeRepr | | patterns.swift:38:18:38:18 | (Any) ... | ErasureExpr | patterns.swift:38:18:38:18 | any | StringLiteralExpr | | patterns.swift:40:5:44:5 | switch a { ... } | SwitchStmt | patterns.swift:40:12:40:12 | a | DeclRefExpr | | patterns.swift:40:5:44:5 | switch a { ... } | SwitchStmt | patterns.swift:41:5:41:18 | case ... | CaseStmt | @@ -947,14 +943,14 @@ | patterns.swift:41:5:41:18 | case ... | CaseStmt | patterns.swift:41:10:41:13 | ... is ... | CaseLabelItem | | patterns.swift:41:5:41:18 | case ... | CaseStmt | patterns.swift:41:18:41:18 | { ... } | BraceStmt | | patterns.swift:41:10:41:13 | ... is ... | CaseLabelItem | patterns.swift:41:10:41:13 | ... is ... | IsPattern | -| patterns.swift:41:10:41:13 | ... is ... | IsPattern | patterns.swift:41:13:41:13 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| patterns.swift:41:10:41:13 | ... is ... | IsPattern | patterns.swift:41:13:41:13 | Int | TypeRepr | | patterns.swift:41:18:41:18 | { ... } | BraceStmt | patterns.swift:41:18:41:18 | is pattern | StringLiteralExpr | | patterns.swift:42:5:42:27 | case ... | CaseStmt | patterns.swift:42:10:42:19 | let ... | CaseLabelItem | | patterns.swift:42:5:42:27 | case ... | CaseStmt | patterns.swift:42:27:42:27 | { ... } | BraceStmt | | patterns.swift:42:10:42:19 | let ... | BindingPattern | patterns.swift:42:14:42:19 | ... is ... | IsPattern | | patterns.swift:42:10:42:19 | let ... | CaseLabelItem | patterns.swift:42:10:42:19 | let ... | BindingPattern | | patterns.swift:42:14:42:19 | ... is ... | IsPattern | patterns.swift:42:14:42:14 | x | NamedPattern | -| patterns.swift:42:14:42:19 | ... is ... | IsPattern | patterns.swift:42:19:42:19 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| patterns.swift:42:14:42:19 | ... is ... | IsPattern | patterns.swift:42:19:42:19 | String | TypeRepr | | patterns.swift:42:27:42:27 | { ... } | BraceStmt | patterns.swift:42:27:42:27 | as pattern | StringLiteralExpr | | patterns.swift:43:5:43:13 | case ... | CaseStmt | patterns.swift:43:10:43:10 | _ | CaseLabelItem | | patterns.swift:43:5:43:13 | case ... | CaseStmt | patterns.swift:43:13:43:13 | { ... } | BraceStmt | @@ -986,14 +982,14 @@ | statements.swift:2:3:8:3 | for ... in ... { ... } | ForEachStmt | statements.swift:2:20:2:24 | ... call to ...(_:_:) ... | BinaryExpr | | statements.swift:2:3:8:3 | for ... in ... { ... } | ForEachStmt | statements.swift:2:26:8:3 | { ... } | BraceStmt | | statements.swift:2:20:2:24 | ... call to ...(_:_:) ... | BinaryExpr | statements.swift:2:21:2:21 | call to ...(_:_:) | DotSyntaxCallExpr | -| statements.swift:2:21:2:21 | Int.Type | TypeExpr | statements.swift:2:21:2:21 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:2:21:2:21 | Int.Type | TypeExpr | statements.swift:2:21:2:21 | Int | TypeRepr | | statements.swift:2:21:2:21 | call to ...(_:_:) | DotSyntaxCallExpr | statements.swift:2:21:2:21 | ...(_:_:) | DeclRefExpr | | statements.swift:2:26:8:3 | { ... } | BraceStmt | statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | | statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | statements.swift:3:8:3:13 | StmtCondition | StmtCondition | | statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | statements.swift:3:15:5:5 | { ... } | BraceStmt | | statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | statements.swift:5:12:7:5 | { ... } | BraceStmt | | statements.swift:3:8:3:13 | ... call to ==(_:_:) ... | BinaryExpr | statements.swift:3:10:3:10 | call to ==(_:_:) | DotSyntaxCallExpr | -| statements.swift:3:10:3:10 | Int.Type | TypeExpr | statements.swift:3:10:3:10 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:3:10:3:10 | Int.Type | TypeExpr | statements.swift:3:10:3:10 | Int | TypeRepr | | statements.swift:3:10:3:10 | call to ==(_:_:) | DotSyntaxCallExpr | statements.swift:3:10:3:10 | ==(_:_:) | DeclRefExpr | | statements.swift:3:15:5:5 | { ... } | BraceStmt | statements.swift:4:9:4:9 | break | BreakStmt | | statements.swift:5:12:7:5 | { ... } | BraceStmt | statements.swift:6:9:6:9 | continue | ContinueStmt | @@ -1004,14 +1000,14 @@ | statements.swift:10:17:10:24 | (...) | ParenExpr | statements.swift:10:18:10:22 | ... call to <(_:_:) ... | BinaryExpr | | statements.swift:10:18:10:18 | (Int) ... | LoadExpr | statements.swift:10:18:10:18 | i | DeclRefExpr | | statements.swift:10:18:10:22 | ... call to <(_:_:) ... | BinaryExpr | statements.swift:10:20:10:20 | call to <(_:_:) | DotSyntaxCallExpr | -| statements.swift:10:20:10:20 | Int.Type | TypeExpr | statements.swift:10:20:10:20 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:10:20:10:20 | Int.Type | TypeExpr | statements.swift:10:20:10:20 | Int | TypeRepr | | statements.swift:10:20:10:20 | call to <(_:_:) | DotSyntaxCallExpr | statements.swift:10:20:10:20 | <(_:_:) | DeclRefExpr | | statements.swift:10:26:12:3 | { ... } | BraceStmt | statements.swift:11:5:11:13 | ... = ... | AssignExpr | | statements.swift:11:5:11:13 | ... = ... | AssignExpr | statements.swift:11:5:11:5 | i | DeclRefExpr | | statements.swift:11:5:11:13 | ... = ... | AssignExpr | statements.swift:11:9:11:13 | ... call to +(_:_:) ... | BinaryExpr | | statements.swift:11:9:11:9 | (Int) ... | LoadExpr | statements.swift:11:9:11:9 | i | DeclRefExpr | | statements.swift:11:9:11:13 | ... call to +(_:_:) ... | BinaryExpr | statements.swift:11:11:11:11 | call to +(_:_:) | DotSyntaxCallExpr | -| statements.swift:11:11:11:11 | Int.Type | TypeExpr | statements.swift:11:11:11:11 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:11:11:11:11 | Int.Type | TypeExpr | statements.swift:11:11:11:11 | Int | TypeRepr | | statements.swift:11:11:11:11 | call to +(_:_:) | DotSyntaxCallExpr | statements.swift:11:11:11:11 | +(_:_:) | DeclRefExpr | | statements.swift:14:3:14:7 | ... = ... | AssignExpr | statements.swift:14:3:14:3 | i | DeclRefExpr | | statements.swift:14:3:14:7 | ... = ... | AssignExpr | statements.swift:14:7:14:7 | 0 | IntegerLiteralExpr | @@ -1022,12 +1018,12 @@ | statements.swift:16:5:16:13 | ... = ... | AssignExpr | statements.swift:16:9:16:13 | ... call to +(_:_:) ... | BinaryExpr | | statements.swift:16:9:16:9 | (Int) ... | LoadExpr | statements.swift:16:9:16:9 | i | DeclRefExpr | | statements.swift:16:9:16:13 | ... call to +(_:_:) ... | BinaryExpr | statements.swift:16:11:16:11 | call to +(_:_:) | DotSyntaxCallExpr | -| statements.swift:16:11:16:11 | Int.Type | TypeExpr | statements.swift:16:11:16:11 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:16:11:16:11 | Int.Type | TypeExpr | statements.swift:16:11:16:11 | Int | TypeRepr | | statements.swift:16:11:16:11 | call to +(_:_:) | DotSyntaxCallExpr | statements.swift:16:11:16:11 | +(_:_:) | DeclRefExpr | | statements.swift:17:11:17:18 | (...) | ParenExpr | statements.swift:17:12:17:16 | ... call to <(_:_:) ... | BinaryExpr | | statements.swift:17:12:17:12 | (Int) ... | LoadExpr | statements.swift:17:12:17:12 | i | DeclRefExpr | | statements.swift:17:12:17:16 | ... call to <(_:_:) ... | BinaryExpr | statements.swift:17:14:17:14 | call to <(_:_:) | DotSyntaxCallExpr | -| statements.swift:17:14:17:14 | Int.Type | TypeExpr | statements.swift:17:14:17:14 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:17:14:17:14 | Int.Type | TypeExpr | statements.swift:17:14:17:14 | Int | TypeRepr | | statements.swift:17:14:17:14 | call to <(_:_:) | DotSyntaxCallExpr | statements.swift:17:14:17:14 | <(_:_:) | DeclRefExpr | | statements.swift:19:3:23:3 | do { ... } catch { ... } | DoCatchStmt | statements.swift:19:6:21:3 | { ... } | BraceStmt | | statements.swift:19:3:23:3 | do { ... } catch { ... } | DoCatchStmt | statements.swift:21:5:23:3 | case ... | CaseStmt | @@ -1074,11 +1070,11 @@ | statements.swift:39:3:41:3 | guard ... else { ... } | GuardStmt | statements.swift:39:9:39:14 | StmtCondition | StmtCondition | | statements.swift:39:3:41:3 | guard ... else { ... } | GuardStmt | statements.swift:39:21:41:3 | { ... } | BraceStmt | | statements.swift:39:9:39:14 | ... call to !=(_:_:) ... | BinaryExpr | statements.swift:39:11:39:11 | call to !=(_:_:) | DotSyntaxCallExpr | -| statements.swift:39:11:39:11 | Int.Type | TypeExpr | statements.swift:39:11:39:11 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:39:11:39:11 | Int.Type | TypeExpr | statements.swift:39:11:39:11 | Int | TypeRepr | | statements.swift:39:11:39:11 | call to !=(_:_:) | DotSyntaxCallExpr | statements.swift:39:11:39:11 | !=(_:_:) | DeclRefExpr | | statements.swift:39:21:41:3 | { ... } | BraceStmt | statements.swift:40:5:40:19 | throw ... | ThrowStmt | | statements.swift:40:5:40:19 | throw ... | ThrowStmt | statements.swift:40:11:40:19 | (Error) ... | ErasureExpr | -| statements.swift:40:11:40:11 | AnError.Type | TypeExpr | statements.swift:40:11:40:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| statements.swift:40:11:40:11 | AnError.Type | TypeExpr | statements.swift:40:11:40:11 | AnError | TypeRepr | | statements.swift:40:11:40:19 | (Error) ... | ErasureExpr | statements.swift:40:11:40:19 | call to ... | DotSyntaxCallExpr | | statements.swift:40:11:40:19 | call to ... | DotSyntaxCallExpr | statements.swift:40:19:40:19 | failed | DeclRefExpr | | statements.swift:44:1:46:1 | defer { ... } | DeferStmt | statements.swift:44:7:46:1 | { ... } | BraceStmt | @@ -1143,7 +1139,7 @@ | statements.swift:64:1:64:15 | { ... } | BraceStmt | statements.swift:64:1:64:15 | var ... = ... | PatternBindingDecl | | statements.swift:64:1:64:15 | { ... } | TopLevelCodeDecl | statements.swift:64:1:64:15 | { ... } | BraceStmt | | statements.swift:64:5:64:11 | ... as ... | TypedPattern | statements.swift:64:5:64:5 | x | NamedPattern | -| statements.swift:64:5:64:11 | ... as ... | TypedPattern | statements.swift:64:8:64:11 | ...? | OptionalTypeRepr | +| statements.swift:64:5:64:11 | ... as ... | TypedPattern | statements.swift:64:8:64:11 | Int? | TypeRepr | | statements.swift:64:15:64:15 | (Int?) ... | InjectIntoOptionalExpr | statements.swift:64:15:64:15 | 4 | IntegerLiteralExpr | | statements.swift:65:1:66:1 | if ... then { ... } | IfStmt | statements.swift:65:4:65:19 | StmtCondition | StmtCondition | | statements.swift:65:1:66:1 | if ... then { ... } | IfStmt | statements.swift:65:21:66:1 | { ... } | BraceStmt | @@ -1172,9 +1168,9 @@ | statements.swift:71:1:72:1 | { ... } | TopLevelCodeDecl | statements.swift:71:1:72:1 | { ... } | BraceStmt | | statements.swift:71:29:71:38 | ... call to %(_:_:) ... | BinaryExpr | statements.swift:71:36:71:36 | call to %(_:_:) | DotSyntaxCallExpr | | statements.swift:71:29:71:43 | ... call to ==(_:_:) ... | BinaryExpr | statements.swift:71:40:71:40 | call to ==(_:_:) | DotSyntaxCallExpr | -| statements.swift:71:36:71:36 | Int.Type | TypeExpr | statements.swift:71:36:71:36 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:71:36:71:36 | Int.Type | TypeExpr | statements.swift:71:36:71:36 | Int | TypeRepr | | statements.swift:71:36:71:36 | call to %(_:_:) | DotSyntaxCallExpr | statements.swift:71:36:71:36 | %(_:_:) | DeclRefExpr | -| statements.swift:71:40:71:40 | Int.Type | TypeExpr | statements.swift:71:40:71:40 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:71:40:71:40 | Int.Type | TypeExpr | statements.swift:71:40:71:40 | Int | TypeRepr | | statements.swift:71:40:71:40 | call to ==(_:_:) | DotSyntaxCallExpr | statements.swift:71:40:71:40 | ==(_:_:) | DeclRefExpr | | statements.swift:74:8:74:8 | init | ConstructorDecl | statements.swift:74:8:74:8 | x | ParamDecl | | statements.swift:75:3:75:11 | var ... = ... | PatternBindingDecl | statements.swift:75:7:75:11 | ... as ... | TypedPattern | @@ -1190,7 +1186,7 @@ | statements.swift:75:7:75:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | statements.swift:75:7:75:7 | { ... } | BraceStmt | statements.swift:75:7:75:7 | yield ... | YieldStmt | | statements.swift:75:7:75:11 | ... as ... | TypedPattern | statements.swift:75:7:75:7 | x | NamedPattern | -| statements.swift:75:7:75:11 | ... as ... | TypedPattern | statements.swift:75:11:75:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| statements.swift:75:7:75:11 | ... as ... | TypedPattern | statements.swift:75:11:75:11 | Int | TypeRepr | | statements.swift:76:3:84:3 | var ... = ... | PatternBindingDecl | statements.swift:76:7:76:19 | ... as ... | TypedPattern | | statements.swift:76:7:76:7 | hasModify | ConcreteVarDecl | statements.swift:76:7:76:7 | set | AccessorDecl | | statements.swift:76:7:76:7 | hasModify | ConcreteVarDecl | statements.swift:77:5:79:5 | (unnamed function decl) | AccessorDecl | @@ -1199,7 +1195,7 @@ | statements.swift:76:7:76:7 | set | AccessorDecl | statements.swift:76:7:76:7 | { ... } | BraceStmt | | statements.swift:76:7:76:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | statements.swift:76:7:76:19 | ... as ... | TypedPattern | statements.swift:76:7:76:7 | hasModify | NamedPattern | -| statements.swift:76:7:76:19 | ... as ... | TypedPattern | statements.swift:76:19:76:19 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| statements.swift:76:7:76:19 | ... as ... | TypedPattern | statements.swift:76:19:76:19 | Int | TypeRepr | | statements.swift:77:5:79:5 | (unnamed function decl) | AccessorDecl | statements.swift:77:13:79:5 | { ... } | BraceStmt | | statements.swift:77:13:79:5 | { ... } | BraceStmt | statements.swift:78:7:78:14 | yield ... | YieldStmt | | statements.swift:78:7:78:14 | yield ... | YieldStmt | statements.swift:78:13:78:14 | &... | InOutExpr | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index 0dd91ca7b53..e5191b6446d 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -1,8 +1,74 @@ edges +| StringLengthConflation2.swift:37:34:37:36 | .count : | StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:60:47:60:50 | .length : | StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | +| StringLengthConflation.swift:66:33:66:36 | .length : | StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | +| StringLengthConflation.swift:93:28:93:31 | .length : | StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:97:27:97:30 | .length : | StringLengthConflation.swift:97:27:97:39 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:101:25:101:28 | .length : | StringLengthConflation.swift:101:25:101:37 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:105:25:105:28 | .length : | StringLengthConflation.swift:105:25:105:37 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:111:23:111:26 | .length : | StringLengthConflation.swift:111:23:111:35 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:117:22:117:25 | .length : | StringLengthConflation.swift:117:22:117:34 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:122:34:122:36 | .count : | StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:123:36:123:38 | .count : | StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:128:36:128:38 | .count : | StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:129:38:129:40 | .count : | StringLengthConflation.swift:129:38:129:48 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:134:34:134:36 | .count : | StringLengthConflation.swift:134:34:134:44 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:135:36:135:38 | .count : | StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:141:28:141:30 | .count : | StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | nodes +| StringLengthConflation2.swift:37:34:37:36 | .count : | semmle.label | .count : | +| StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:53:43:53:46 | .length | semmle.label | .length | +| StringLengthConflation.swift:60:47:60:50 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | semmle.label | ... call to /(_:_:) ... | +| StringLengthConflation.swift:66:33:66:36 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | semmle.label | ... call to /(_:_:) ... | | StringLengthConflation.swift:72:33:72:35 | .count | semmle.label | .count | | StringLengthConflation.swift:78:47:78:49 | .count | semmle.label | .count | +| StringLengthConflation.swift:93:28:93:31 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:97:27:97:30 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:97:27:97:39 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:101:25:101:28 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:101:25:101:37 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:105:25:105:28 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:105:25:105:37 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:111:23:111:26 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:111:23:111:35 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:117:22:117:25 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:117:22:117:34 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:122:34:122:36 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:123:36:123:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:128:36:128:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:129:38:129:40 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:129:38:129:48 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:134:34:134:36 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:134:34:134:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:135:36:135:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:141:28:141:30 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | subpaths #select +| StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | StringLengthConflation2.swift:37:34:37:36 | .count : | StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | StringLengthConflation.swift:60:47:60:50 | .length : | StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | StringLengthConflation.swift:66:33:66:36 | .length : | StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:72:33:72:35 | .count | StringLengthConflation.swift:72:33:72:35 | .count | StringLengthConflation.swift:72:33:72:35 | .count | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:78:47:78:49 | .count | StringLengthConflation.swift:78:47:78:49 | .count | StringLengthConflation.swift:78:47:78:49 | .count | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | StringLengthConflation.swift:93:28:93:31 | .length : | StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:97:27:97:39 | ... call to -(_:_:) ... | StringLengthConflation.swift:97:27:97:30 | .length : | StringLengthConflation.swift:97:27:97:39 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:101:25:101:37 | ... call to -(_:_:) ... | StringLengthConflation.swift:101:25:101:28 | .length : | StringLengthConflation.swift:101:25:101:37 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:105:25:105:37 | ... call to -(_:_:) ... | StringLengthConflation.swift:105:25:105:28 | .length : | StringLengthConflation.swift:105:25:105:37 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:111:23:111:35 | ... call to -(_:_:) ... | StringLengthConflation.swift:111:23:111:26 | .length : | StringLengthConflation.swift:111:23:111:35 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:117:22:117:34 | ... call to -(_:_:) ... | StringLengthConflation.swift:117:22:117:25 | .length : | StringLengthConflation.swift:117:22:117:34 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:122:34:122:36 | .count : | StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:123:36:123:38 | .count : | StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:128:36:128:38 | .count : | StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:129:38:129:48 | ... call to -(_:_:) ... | StringLengthConflation.swift:129:38:129:40 | .count : | StringLengthConflation.swift:129:38:129:48 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:134:34:134:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:134:34:134:36 | .count : | StringLengthConflation.swift:134:34:134:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:135:36:135:38 | .count : | StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | StringLengthConflation.swift:141:28:141:30 | .count : | StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index b8174455f9d..527cacd772b 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -28,6 +28,7 @@ class NSMutableString : NSString class NSRange { init(location: Int, length: Int) { self.description = "" } + init(_ r: R, in: S) { self.description = "" } private(set) var description: String } @@ -36,7 +37,6 @@ func NSMakeRange(_ loc: Int, _ len: Int) -> NSRange { return NSRange(location: l - // --- tests --- func test(s: String) { @@ -51,9 +51,9 @@ func test(s: String) { let ix1 = String.Index(encodedOffset: s.count) // GOOD let ix2 = String.Index(encodedOffset: ns.length) // BAD: NSString length used in String.Index - let ix3 = String.Index(encodedOffset: s.utf8.count) // BAD: String.utf8 length used in String.Index - let ix4 = String.Index(encodedOffset: s.utf16.count) // BAD: String.utf16 length used in String.Index - let ix5 = String.Index(encodedOffset: s.unicodeScalars.count) // BAD: string.unicodeScalars length used in String.Index + let ix3 = String.Index(encodedOffset: s.utf8.count) // BAD: String.utf8 length used in String.Index [NOT DETECTED] + let ix4 = String.Index(encodedOffset: s.utf16.count) // BAD: String.utf16 length used in String.Index [NOT DETECTED] + let ix5 = String.Index(encodedOffset: s.unicodeScalars.count) // BAD: string.unicodeScalars length used in String.Index [NOT DETECTED] print("String.Index '\(ix1.encodedOffset)' / '\(ix2.encodedOffset)' '\(ix3.encodedOffset)' '\(ix4.encodedOffset)' '\(ix5.encodedOffset)'") let ix6 = s.index(s.startIndex, offsetBy: s.count / 2) // GOOD @@ -70,14 +70,23 @@ func test(s: String) { let range1 = NSMakeRange(0, ns.length) // GOOD let range2 = NSMakeRange(0, s.count) // BAD: String length used in NSMakeRange - let range3 = NSMakeRange(0, s.reversed().count) // BAD: String length used in NSMakeRange - let range4 = NSMakeRange(0, s.distance(from: s.startIndex, to: s.endIndex)) // BAD: String length used in NSMakeRange + let range3 = NSMakeRange(0, s.reversed().count) // BAD: String length used in NSMakeRange [NOT DETECTED] + let range4 = NSMakeRange(0, s.distance(from: s.startIndex, to: s.endIndex)) // BAD: String length used in NSMakeRange [NOT DETECTED] print("NSMakeRange '\(range1.description)' / '\(range2.description)' '\(range3.description)' '\(range4.description)'") let range5 = NSRange(location: 0, length: ns.length) // GOOD let range6 = NSRange(location: 0, length: s.count) // BAD: String length used in NSMakeRange print("NSRange '\(range5.description)' / '\(range6.description)'") + // --- converting Range to NSRange --- + + let range7 = s.startIndex ..< s.endIndex + let range8 = NSRange(range7, in: s) // GOOD + let location = s.distance(from: s.startIndex, to: range7.lowerBound) + let length = s.distance(from: range7.lowerBound, to: range7.upperBound) + let range9 = NSRange(location: location, length: length) // BAD [NOT DETECTED] + print("NSRange '\(range8.description)' / '\(range9.description)'") + // --- String operations using an integer directly --- let str1 = s.dropFirst(s.count - 1) // GOOD @@ -96,6 +105,18 @@ func test(s: String) { let str8 = s.suffix(ns.length - 1) // BAD: NSString length used in String print("suffix '\(str7)' / '\(str8)'") + var str9 = s + str9.removeFirst(s.count - 1) // GOOD + var str10 = s + str10.removeFirst(ns.length - 1) // BAD: NSString length used in String + print("removeFirst '\(str9)' / '\(str10)'") + + var str11 = s + str11.removeLast(s.count - 1) // GOOD + var str12 = s + str12.removeLast(ns.length - 1) // BAD: NSString length used in String + print("removeLast '\(str11)' / '\(str12)'") + let nstr1 = ns.character(at: ns.length - 1) // GOOD let nmstr1 = nms.character(at: nms.length - 1) // GOOD let nstr2 = ns.character(at: s.count - 1) // BAD: String length used in NSString diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift new file mode 100644 index 00000000000..39b1456e604 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift @@ -0,0 +1,42 @@ +// this test is in a separate file, because we want to test with a slightly different library +// implementation. In this version, some of the functions of `NSString` are in fact implemented +// in a base class `NSStringBase`. + +// --- stubs --- + +func print(_ items: Any...) {} + +typealias unichar = UInt16 + +class NSObject +{ +} + +class NSStringBase : NSObject +{ + func substring(from: Int) -> String { return "" } +} + +class NSString : NSStringBase +{ + init(string: String) { length = string.count } + + func substring(to: Int) -> String { return "" } + + private(set) var length: Int +} + +// --- tests --- + +func test(s: String) { + let ns = NSString(string: s) + + let nstr1 = ns.substring(from: ns.length - 1) // GOOD + let nstr2 = ns.substring(from: s.count - 1) // BAD: String length used in NSString [NOT DETECTED] + let nstr3 = ns.substring(to: ns.length - 1) // GOOD + let nstr4 = ns.substring(to: s.count - 1) // BAD: String length used in NSString + print("substrings '\(nstr1)' '\(nstr2)' / '\(nstr3)' '\(nstr4)'") +} + +// `begin :thumbsup: end`, with thumbs up emoji and skin tone modifier +test(s: "begin \u{0001F44D}\u{0001F3FF} end") diff --git a/swift/tools/qltest.sh b/swift/tools/qltest.sh index 59d576af431..2232350c5b0 100755 --- a/swift/tools/qltest.sh +++ b/swift/tools/qltest.sh @@ -7,5 +7,8 @@ QLTEST_LOG="$CODEQL_EXTRACTOR_SWIFT_LOG_DIR"/qltest.log export LD_LIBRARY_PATH="$CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM" for src in *.swift; do - "$CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor" -sdk "$CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk" -c -primary-file $src >> $QLTEST_LOG 2>&1 + opts=(-sdk "$CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk" -c -primary-file $src) + opts+=($(sed -n '1 s=//codeql-extractor-options:==p' $src)) + echo -e "calling extractor with flags: ${opts[@]}\n" >> $QLTEST_LOG + "$CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor" "${opts[@]}" >> $QLTEST_LOG 2>&1 done diff --git a/swift/tools/tracing-config.lua b/swift/tools/tracing-config.lua index 558d6a95d3f..d9343285099 100644 --- a/swift/tools/tracing-config.lua +++ b/swift/tools/tracing-config.lua @@ -67,9 +67,6 @@ function RegisterExtractorPack(id) return nil end - -- Skip actions in which we cannot extract anything - if compilerArguments.argv[1] == '-merge-modules' then return nil end - strip_unsupported_args(compilerArguments.argv) insert_resource_dir_if_needed(compilerPath, compilerArguments.argv)