mirror of
https://github.com/github/codeql.git
synced 2026-05-26 17:11:24 +02:00
Compare commits
3 Commits
criemen/ex
...
aibaars/dr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4f81886d7 | ||
|
|
e7a3ca2ed4 | ||
|
|
0b59e408ba |
@@ -1,5 +1,4 @@
|
||||
{ "provide": [ "*/ql/src/qlpack.yml",
|
||||
"*/ql/lib/qlpack.yml",
|
||||
"*/ql/test/qlpack.yml",
|
||||
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
|
||||
"*/ql/examples/qlpack.yml",
|
||||
|
||||
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -48,6 +48,3 @@
|
||||
*.gif -text
|
||||
*.dll -text
|
||||
*.pdb -text
|
||||
|
||||
java/ql/test/stubs/**/*.java linguist-generated=true
|
||||
java/ql/test/experimental/stubs/**/*.java linguist-generated=true
|
||||
14
.github/workflows/csv-coverage-pr-artifacts.yml
vendored
14
.github/workflows/csv-coverage-pr-artifacts.yml
vendored
@@ -49,23 +49,19 @@ jobs:
|
||||
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
|
||||
- name: Generate CSV files on merge and base 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@v2
|
||||
with:
|
||||
@@ -80,12 +76,6 @@ jobs:
|
||||
path: |
|
||||
out_base/framework-coverage-*.csv
|
||||
out_base/framework-coverage-*.rst
|
||||
- name: Upload comparison results
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: comparison
|
||||
path: |
|
||||
comparison.md
|
||||
- name: Save PR number
|
||||
run: |
|
||||
mkdir -p pr
|
||||
|
||||
35
.github/workflows/csv-coverage-pr-comment.yml
vendored
35
.github/workflows/csv-coverage-pr-comment.yml
vendored
@@ -26,9 +26,40 @@ jobs:
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- name: Check coverage difference file and comment
|
||||
# download artifacts from the PR job:
|
||||
|
||||
- name: Download artifact - MERGE
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
run: |
|
||||
python misc/scripts/library-coverage/comment-pr.py "$GITHUB_REPOSITORY" "$RUN_ID"
|
||||
gh run download --name "csv-framework-coverage-merge" --dir "out_merge" "$RUN_ID"
|
||||
|
||||
- name: Download artifact - BASE
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
run: |
|
||||
gh run download --name "csv-framework-coverage-base" --dir "out_base" "$RUN_ID"
|
||||
|
||||
- name: Download artifact - PR
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
run: |
|
||||
gh run download --name "pr" --dir "pr" "$RUN_ID"
|
||||
|
||||
- name: Check coverage files
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
run: |
|
||||
PR=$(cat "pr/NR")
|
||||
python misc/scripts/library-coverage/compare-files-comment-pr.py \
|
||||
out_base out_merge comparison.md "$GITHUB_REPOSITORY" "$PR" "$RUN_ID"
|
||||
- name: Upload comparison results
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: comparison
|
||||
path: |
|
||||
comparison.md
|
||||
|
||||
44
.github/workflows/csv-coverage-update.yml
vendored
44
.github/workflows/csv-coverage-update.yml
vendored
@@ -1,44 +0,0 @@
|
||||
name: Update framework coverage reports
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
update:
|
||||
name: Update framework coverage report
|
||||
if: github.event.repository.fork == false
|
||||
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@v2
|
||||
with:
|
||||
path: ql
|
||||
fetch-depth: 0
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v2
|
||||
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 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"
|
||||
@@ -17,9 +17,3 @@
|
||||
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @github/codeql-java @github/codeql-go
|
||||
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go
|
||||
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go
|
||||
|
||||
# CodeQL tools and associated docs
|
||||
/docs/codeql-cli/ @github/codeql-cli-reviewers
|
||||
/docs/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
|
||||
/docs/ql-language-reference/ @github/codeql-frontend-reviewers
|
||||
/docs/query-*-style-guide.md @github/codeql-analysis-reviewers
|
||||
@@ -1,333 +1,332 @@
|
||||
{
|
||||
"DataFlow Java/C++/C#/Python": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll"
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll",
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll",
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll",
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll",
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll",
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll",
|
||||
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll",
|
||||
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll",
|
||||
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
|
||||
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll"
|
||||
],
|
||||
"DataFlow Java/C++/C#/Python Common": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll"
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll",
|
||||
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll"
|
||||
],
|
||||
"TaintTracking::Configuration Java/C++/C#/Python": [
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll",
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
"python/ql/src/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"python/ql/src/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
"python/ql/src/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll",
|
||||
"python/ql/src/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll"
|
||||
],
|
||||
"DataFlow Java/C++/C#/Python Consistency checks": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll"
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll"
|
||||
],
|
||||
"DataFlow Java/C# Flow Summaries": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll"
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll"
|
||||
],
|
||||
"SsaReadPosition Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
|
||||
],
|
||||
"Sign Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll"
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll"
|
||||
],
|
||||
"SignAnalysis Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll"
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll"
|
||||
],
|
||||
"Bound Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/Bound.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll"
|
||||
"java/ql/src/semmle/code/java/dataflow/Bound.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/Bound.qll"
|
||||
],
|
||||
"ModulusAnalysis Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/ModulusAnalysis.qll"
|
||||
"java/ql/src/semmle/code/java/dataflow/ModulusAnalysis.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/ModulusAnalysis.qll"
|
||||
],
|
||||
"C++ SubBasicBlocks": [
|
||||
"cpp/ql/lib/semmle/code/cpp/controlflow/SubBasicBlocks.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/controlflow/SubBasicBlocks.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll"
|
||||
],
|
||||
"IR Instruction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll"
|
||||
],
|
||||
"IR IRBlock": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll"
|
||||
],
|
||||
"IR IRVariable": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRVariable.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRVariable.qll"
|
||||
],
|
||||
"IR IRFunction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRFunction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRFunction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRFunction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRFunction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRFunction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRFunction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRFunction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRFunction.qll"
|
||||
],
|
||||
"IR Operand": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/Operand.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll"
|
||||
],
|
||||
"IR IRType": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/IRType.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/IRType.qll"
|
||||
],
|
||||
"IR IRConfiguration": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/IRConfiguration.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/IRConfiguration.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/IRConfiguration.qll"
|
||||
],
|
||||
"IR UseSoundEscapeAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/UseSoundEscapeAnalysis.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/UseSoundEscapeAnalysis.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/UseSoundEscapeAnalysis.qll"
|
||||
],
|
||||
"IR IRFunctionBase": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/IRFunctionBase.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/IRFunctionBase.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/IRFunctionBase.qll"
|
||||
],
|
||||
"IR Operand Tag": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/OperandTag.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/OperandTag.qll"
|
||||
],
|
||||
"IR TInstruction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TInstruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll"
|
||||
],
|
||||
"IR TIRVariable": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/TIRVariable.qll"
|
||||
],
|
||||
"IR IR": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IR.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IR.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IR.qll"
|
||||
],
|
||||
"IR IRConsistency": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRConsistency.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRConsistency.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRConsistency.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRConsistency.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRConsistency.qll"
|
||||
],
|
||||
"IR PrintIR": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/PrintIR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/PrintIR.qll"
|
||||
],
|
||||
"IR IntegerConstant": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerConstant.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/IntegerConstant.qll"
|
||||
],
|
||||
"IR IntegerInteval": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerInterval.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/internal/IntegerInterval.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/IntegerInterval.qll"
|
||||
],
|
||||
"IR IntegerPartial": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerPartial.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/internal/IntegerPartial.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/IntegerPartial.qll"
|
||||
],
|
||||
"IR Overlap": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/Overlap.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/internal/Overlap.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/Overlap.qll"
|
||||
],
|
||||
"IR EdgeKind": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/EdgeKind.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/EdgeKind.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/EdgeKind.qll"
|
||||
],
|
||||
"IR MemoryAccessKind": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/MemoryAccessKind.qll"
|
||||
],
|
||||
"IR TempVariableTag": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/TempVariableTag.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/TempVariableTag.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/TempVariableTag.qll"
|
||||
],
|
||||
"IR Opcode": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/Opcode.qll"
|
||||
],
|
||||
"IR SSAConsistency": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll"
|
||||
],
|
||||
"C++ IR InstructionImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/InstructionImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/InstructionImports.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/InstructionImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/InstructionImports.qll"
|
||||
],
|
||||
"C++ IR IRImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRImports.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRImports.qll"
|
||||
],
|
||||
"C++ IR IRBlockImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRBlockImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRBlockImports.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRBlockImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRBlockImports.qll"
|
||||
],
|
||||
"C++ IR IRFunctionImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRFunctionImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRFunctionImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRFunctionImports.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRFunctionImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRFunctionImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRFunctionImports.qll"
|
||||
],
|
||||
"C++ IR IRVariableImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRVariableImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRVariableImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRVariableImports.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRVariableImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRVariableImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRVariableImports.qll"
|
||||
],
|
||||
"C++ IR OperandImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/OperandImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/OperandImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/OperandImports.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/OperandImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/OperandImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/OperandImports.qll"
|
||||
],
|
||||
"C++ IR PrintIRImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/PrintIRImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintIRImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintIRImports.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/PrintIRImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintIRImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintIRImports.qll"
|
||||
],
|
||||
"C++ SSA SSAConstructionImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstructionImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstructionImports.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstructionImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstructionImports.qll"
|
||||
],
|
||||
"SSA AliasAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll"
|
||||
],
|
||||
"SSA PrintAliasAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintAliasAnalysis.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintAliasAnalysis.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintAliasAnalysis.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintAliasAnalysis.qll"
|
||||
],
|
||||
"C++ SSA AliasAnalysisImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysisImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysisImports.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysisImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysisImports.qll"
|
||||
],
|
||||
"C++ IR ValueNumberingImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingImports.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingImports.qll"
|
||||
],
|
||||
"IR SSA SimpleSSA": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll"
|
||||
],
|
||||
"IR AliasConfiguration (unaliased_ssa)": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasConfiguration.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasConfiguration.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/AliasConfiguration.qll"
|
||||
],
|
||||
"IR SSA SSAConstruction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll"
|
||||
],
|
||||
"IR SSA PrintSSA": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/PrintSSA.qll"
|
||||
],
|
||||
"IR ValueNumberInternal": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll"
|
||||
],
|
||||
"C++ IR ValueNumber": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/ValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll"
|
||||
],
|
||||
"C++ IR PrintValueNumbering": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/PrintValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/PrintValueNumbering.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/PrintValueNumbering.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/PrintValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/PrintValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll"
|
||||
],
|
||||
"C++ IR ConstantAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/constant/ConstantAnalysis.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/constant/ConstantAnalysis.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/constant/ConstantAnalysis.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/constant/ConstantAnalysis.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/constant/ConstantAnalysis.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/constant/ConstantAnalysis.qll"
|
||||
],
|
||||
"C++ IR PrintConstantAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/constant/PrintConstantAnalysis.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/constant/PrintConstantAnalysis.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/constant/PrintConstantAnalysis.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/constant/PrintConstantAnalysis.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/constant/PrintConstantAnalysis.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/constant/PrintConstantAnalysis.qll"
|
||||
],
|
||||
"C++ IR ReachableBlock": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/reachability/ReachableBlock.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/ReachableBlock.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/reachability/ReachableBlock.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/ReachableBlock.qll"
|
||||
],
|
||||
"C++ IR PrintReachableBlock": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/reachability/PrintReachableBlock.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/PrintReachableBlock.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/reachability/PrintReachableBlock.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/PrintReachableBlock.qll"
|
||||
],
|
||||
"C++ IR Dominance": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/reachability/Dominance.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/Dominance.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/reachability/Dominance.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/Dominance.qll"
|
||||
],
|
||||
"C++ IR PrintDominance": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/reachability/PrintDominance.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/PrintDominance.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/reachability/PrintDominance.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/PrintDominance.qll"
|
||||
],
|
||||
"C# IR InstructionImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/InstructionImports.qll",
|
||||
@@ -362,8 +361,8 @@
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll"
|
||||
],
|
||||
"C# ControlFlowReachability": [
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/ControlFlowReachability.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ControlFlowReachability.qll"
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/ControlFlowReachability.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/ControlFlowReachability.qll"
|
||||
],
|
||||
"Inline Test Expectations": [
|
||||
"cpp/ql/test/TestUtilities/InlineExpectationsTest.qll",
|
||||
@@ -379,11 +378,11 @@
|
||||
"cpp/ql/src/Security/CWE/CWE-020/ir/SafeExternalAPIFunction.qll"
|
||||
],
|
||||
"XML": [
|
||||
"cpp/ql/lib/semmle/code/cpp/XML.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/XML.qll",
|
||||
"java/ql/lib/semmle/code/xml/XML.qll",
|
||||
"javascript/ql/lib/semmle/javascript/XML.qll",
|
||||
"python/ql/lib/semmle/python/xml/XML.qll"
|
||||
"cpp/ql/src/semmle/code/cpp/XML.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/XML.qll",
|
||||
"java/ql/src/semmle/code/xml/XML.qll",
|
||||
"javascript/ql/src/semmle/javascript/XML.qll",
|
||||
"python/ql/src/semmle/python/xml/XML.qll"
|
||||
],
|
||||
"DuplicationProblems.inc.qhelp": [
|
||||
"cpp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp",
|
||||
@@ -437,29 +436,17 @@
|
||||
"python/ql/src/analysis/IDEContextual.qll"
|
||||
],
|
||||
"SSA C#": [
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll"
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll",
|
||||
"csharp/ql/src/semmle/code/cil/internal/SsaImplCommon.qll"
|
||||
],
|
||||
"CryptoAlgorithms Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",
|
||||
"python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll"
|
||||
"javascript/ql/src/semmle/javascript/security/CryptoAlgorithms.qll",
|
||||
"python/ql/src/semmle/python/concepts/CryptoAlgorithms.qll"
|
||||
],
|
||||
"SensitiveDataHeuristics Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
|
||||
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll"
|
||||
],
|
||||
"ReDoS Util Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll",
|
||||
"python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll"
|
||||
],
|
||||
"ReDoS Exponential Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/performance/ExponentialBackTracking.qll",
|
||||
"python/ql/lib/semmle/python/security/performance/ExponentialBackTracking.qll"
|
||||
],
|
||||
"ReDoS Polynomial Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
|
||||
"python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll"
|
||||
"javascript/ql/src/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
|
||||
"python/ql/src/semmle/python/security/internal/SensitiveDataHeuristics.qll"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* The DataFlow libraries have been augmented with support for `Configuration`-specific in-place read steps at, for example, sinks and custom taint steps. This means that it is now possible to specify sinks that accept flow with non-empty access paths.
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm
|
||||
* The 'Uncontrolled data in arithmetic expression' (cpp/uncontrolled-arithmetic) query now recognizes more sources of randomness.
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* The 'Wrong type of arguments to formatting function' (cpp/wrong-type-format-argument) query is now more accepting of the string and character formatting differences between Microsoft and non-Microsoft platforms. There are now fewer false positive results.
|
||||
@@ -1,3 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* The "Cleartext storage of sensitive information in file" (cpp/cleartext-storage-file) query now uses dataflow to produce additional results.
|
||||
* Heuristics in the SensitiveExprs.qll library have been improved, making the "Cleartext storage of sensitive information in file" (cpp/cleartext-storage-file), "Cleartext storage of sensitive information in buffer" (cpp/cleartext-storage-buffer) and "Cleartext storage of sensitive information in an SQLite" (cpp/cleartext-storage-database) queries more accurate.
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* Improvements have been made to the `cpp/toctou-race-condition` query, both to find more correct results and fewer false positive results.
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm
|
||||
* Improvements made to the (`cpp/uncontrolled-arithmetic`) query, reducing the frequency of false positive results.
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* Virtual function specifiers are now accessible via the new predicates on `Function` (`.isDeclaredVirtual`, `.isOverride`, and `.isFinal`).
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* Added `Function.hasTrailingReturnType` predicate to check whether a function was declared with a trailing return type.
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* Added `RoutineType.hasCLinkage` predicate to check whether a function type has "C" language linkage.
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* Lowered the precision of `cpp/potentially-dangerous-function` so it is run but not displayed on LGTM by default and so it's only run and displayed on Code Scanning if a broader suite like `cpp-security-extended` is opted into.
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* Added `Element.getPrimaryQlClasses()` predicate, which gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
|
||||
@@ -1,2 +0,0 @@
|
||||
lgtm,codescanning
|
||||
* The query `cpp/implicit-bitfield-downcast` now accounts for C++ reference types, which leads to more true positive results.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
dependencies: {}
|
||||
compiled: false
|
||||
lockVersion: 1.0.0
|
||||
@@ -1,4 +1,3 @@
|
||||
name: codeql/cpp-examples
|
||||
version: 0.0.2
|
||||
dependencies:
|
||||
codeql/cpp-all: "*"
|
||||
name: codeql-cpp-examples
|
||||
version: 0.0.0
|
||||
libraryPathDependencies: codeql-cpp
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
dependencies: {}
|
||||
compiled: false
|
||||
lockVersion: 1.0.0
|
||||
@@ -1,7 +0,0 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.0.2
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
library: true
|
||||
dependencies:
|
||||
codeql/cpp-upgrades: 0.0.2
|
||||
@@ -1,120 +0,0 @@
|
||||
/**
|
||||
* Provides an implementation of global (interprocedural) taint tracking.
|
||||
* This file re-exports the local (intraprocedural) taint-tracking analysis
|
||||
* from `TaintTrackingParameter::Public` and adds a global analysis, mainly
|
||||
* exposed through the `Configuration` class. For some languages, this file
|
||||
* exists in several identical copies, allowing queries to use multiple
|
||||
* `Configuration` classes that depend on each other without introducing
|
||||
* mutual recursion among those configurations.
|
||||
*/
|
||||
|
||||
import TaintTrackingParameter::Public
|
||||
private import TaintTrackingParameter::Private
|
||||
|
||||
/**
|
||||
* A configuration of interprocedural taint tracking analysis. This defines
|
||||
* sources, sinks, and any other configurable aspect of the analysis. Each
|
||||
* use of the taint tracking library must define its own unique extension of
|
||||
* this abstract class.
|
||||
*
|
||||
* A taint-tracking configuration is a special data flow configuration
|
||||
* (`DataFlow::Configuration`) that allows for flow through nodes that do not
|
||||
* necessarily preserve values but are still relevant from a taint tracking
|
||||
* perspective. (For example, string concatenation, where one of the operands
|
||||
* is tainted.)
|
||||
*
|
||||
* To create a configuration, extend this class with a subclass whose
|
||||
* characteristic predicate is a unique singleton string. For example, write
|
||||
*
|
||||
* ```ql
|
||||
* class MyAnalysisConfiguration extends TaintTracking::Configuration {
|
||||
* MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" }
|
||||
* // Override `isSource` and `isSink`.
|
||||
* // Optionally override `isSanitizer`.
|
||||
* // Optionally override `isSanitizerIn`.
|
||||
* // Optionally override `isSanitizerOut`.
|
||||
* // Optionally override `isSanitizerGuard`.
|
||||
* // Optionally override `isAdditionalTaintStep`.
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Then, to query whether there is flow between some `source` and `sink`,
|
||||
* write
|
||||
*
|
||||
* ```ql
|
||||
* exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink))
|
||||
* ```
|
||||
*
|
||||
* Multiple configurations can coexist, but it is unsupported to depend on
|
||||
* another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the
|
||||
* overridden predicates that define sources, sinks, or additional steps.
|
||||
* Instead, the dependency should go to a `TaintTracking2::Configuration` or a
|
||||
* `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc.
|
||||
*/
|
||||
abstract class Configuration extends DataFlow::Configuration {
|
||||
bindingset[this]
|
||||
Configuration() { any() }
|
||||
|
||||
/**
|
||||
* Holds if `source` is a relevant taint source.
|
||||
*
|
||||
* The smaller this predicate is, the faster `hasFlow()` will converge.
|
||||
*/
|
||||
// overridden to provide taint-tracking specific qldoc
|
||||
abstract override predicate isSource(DataFlow::Node source);
|
||||
|
||||
/**
|
||||
* Holds if `sink` is a relevant taint sink.
|
||||
*
|
||||
* The smaller this predicate is, the faster `hasFlow()` will converge.
|
||||
*/
|
||||
// overridden to provide taint-tracking specific qldoc
|
||||
abstract override predicate isSink(DataFlow::Node sink);
|
||||
|
||||
/** Holds if the node `node` is a taint sanitizer. */
|
||||
predicate isSanitizer(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrier(DataFlow::Node node) {
|
||||
isSanitizer(node) or
|
||||
defaultTaintSanitizer(node)
|
||||
}
|
||||
|
||||
/** Holds if taint propagation into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
|
||||
|
||||
/** Holds if taint propagation out of `node` is prohibited. */
|
||||
predicate isSanitizerOut(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
|
||||
|
||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||
|
||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
|
||||
|
||||
/**
|
||||
* Holds if the additional taint propagation step from `node1` to `node2`
|
||||
* must be taken into account in the analysis.
|
||||
*/
|
||||
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isAdditionalTaintStep(node1, node2) or
|
||||
defaultAdditionalTaintStep(node1, node2)
|
||||
}
|
||||
|
||||
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) {
|
||||
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
|
||||
defaultImplicitTaintRead(node, c)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if taint may flow from `source` to `sink` for this configuration.
|
||||
*/
|
||||
// overridden to provide taint-tracking specific qldoc
|
||||
override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) {
|
||||
super.hasFlow(source, sink)
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,10 @@
|
||||
|
||||
import cpp
|
||||
|
||||
class AnonymousCompilation extends Compilation {
|
||||
override string toString() { result = "<compilation>" }
|
||||
}
|
||||
|
||||
string describe(Compilation c) {
|
||||
if c.getArgument(1) = "--mimic"
|
||||
then result = "compiler invocation " + concat(int i | i > 1 | c.getArgument(i), " " order by i)
|
||||
@@ -15,4 +19,4 @@ string describe(Compilation c) {
|
||||
|
||||
from Compilation c
|
||||
where not c.normalTermination()
|
||||
select "Extraction aborted for " + describe(c)
|
||||
select c, "Extraction aborted for " + describe(c), 2
|
||||
|
||||
@@ -13,15 +13,10 @@
|
||||
|
||||
import cpp
|
||||
|
||||
from BitField fi, VariableAccess va, Type fct
|
||||
from BitField fi, VariableAccess va
|
||||
where
|
||||
(
|
||||
if va.getFullyConverted().getType() instanceof ReferenceType
|
||||
then fct = va.getFullyConverted().getType().(ReferenceType).getBaseType()
|
||||
else fct = va.getFullyConverted().getType()
|
||||
) and
|
||||
fi.getNumBits() > fct.getSize() * 8 and
|
||||
va.getExplicitlyConverted().getType().getSize() > fct.getSize() and
|
||||
fi.getNumBits() > va.getFullyConverted().getType().getSize() * 8 and
|
||||
va.getExplicitlyConverted().getType().getSize() > va.getFullyConverted().getType().getSize() and
|
||||
va.getTarget() = fi and
|
||||
not fct.getUnspecifiedType() instanceof BoolType
|
||||
not va.getActualType() instanceof BoolType
|
||||
select va, "Implicit downcast of bitfield $@", fi, fi.toString()
|
||||
|
||||
@@ -19,32 +19,28 @@ import cpp
|
||||
* Holds if the argument corresponding to the `pos` conversion specifier
|
||||
* of `ffc` is expected to have type `expected`.
|
||||
*/
|
||||
pragma[noopt]
|
||||
private predicate formattingFunctionCallExpectedType(
|
||||
FormattingFunctionCall ffc, int pos, Type expected
|
||||
) {
|
||||
ffc.getFormat().(FormatLiteral).getConversionType(pos) = expected
|
||||
exists(FormattingFunction f, int i, FormatLiteral fl |
|
||||
ffc instanceof FormattingFunctionCall and
|
||||
ffc.getTarget() = f and
|
||||
f.getFormatParameterIndex() = i and
|
||||
ffc.getArgument(i) = fl and
|
||||
fl.getConversionType(pos) = expected
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the argument corresponding to the `pos` conversion specifier
|
||||
* of `ffc` could alternatively have type `expected`, for example on a different
|
||||
* platform.
|
||||
*/
|
||||
private predicate formattingFunctionCallAlternateType(
|
||||
FormattingFunctionCall ffc, int pos, Type expected
|
||||
) {
|
||||
ffc.getFormat().(FormatLiteral).getConversionTypeAlternate(pos) = expected
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the argument corresponding to the `pos` conversion specifier
|
||||
* of `ffc` is `arg` and has type `actual`.
|
||||
* of `ffc` is expected to have type `expected` and the corresponding
|
||||
* argument `arg` has type `actual`.
|
||||
*/
|
||||
pragma[noopt]
|
||||
predicate formattingFunctionCallActualType(
|
||||
FormattingFunctionCall ffc, int pos, Expr arg, Type actual
|
||||
) {
|
||||
predicate formatArgType(FormattingFunctionCall ffc, int pos, Type expected, Expr arg, Type actual) {
|
||||
exists(Expr argConverted |
|
||||
formattingFunctionCallExpectedType(ffc, pos, expected) and
|
||||
ffc.getConversionArgument(pos) = arg and
|
||||
argConverted = arg.getFullyConverted() and
|
||||
actual = argConverted.getType()
|
||||
@@ -76,8 +72,7 @@ class ExpectedType extends Type {
|
||||
ExpectedType() {
|
||||
exists(Type t |
|
||||
(
|
||||
formattingFunctionCallExpectedType(_, _, t) or
|
||||
formattingFunctionCallAlternateType(_, _, t) or
|
||||
formatArgType(_, _, t, _, _) or
|
||||
formatOtherArgType(_, _, t, _, _)
|
||||
) and
|
||||
this = t.getUnspecifiedType()
|
||||
@@ -96,11 +91,7 @@ class ExpectedType extends Type {
|
||||
*/
|
||||
predicate trivialConversion(ExpectedType expected, Type actual) {
|
||||
exists(Type exp, Type act |
|
||||
(
|
||||
formattingFunctionCallExpectedType(_, _, exp) or
|
||||
formattingFunctionCallAlternateType(_, _, exp)
|
||||
) and
|
||||
formattingFunctionCallActualType(_, _, _, act) and
|
||||
formatArgType(_, _, exp, _, act) and
|
||||
expected = exp.getUnspecifiedType() and
|
||||
actual = act.getUnspecifiedType()
|
||||
) and
|
||||
@@ -155,13 +146,9 @@ int sizeof_IntType() { exists(IntType it | result = it.getSize()) }
|
||||
from FormattingFunctionCall ffc, int n, Expr arg, Type expected, Type actual
|
||||
where
|
||||
(
|
||||
formattingFunctionCallExpectedType(ffc, n, expected) and
|
||||
formattingFunctionCallActualType(ffc, n, arg, actual) and
|
||||
formatArgType(ffc, n, expected, arg, actual) and
|
||||
not exists(Type anyExpected |
|
||||
(
|
||||
formattingFunctionCallExpectedType(ffc, n, anyExpected) or
|
||||
formattingFunctionCallAlternateType(ffc, n, anyExpected)
|
||||
) and
|
||||
formatArgType(ffc, n, anyExpected, arg, actual) and
|
||||
trivialConversion(anyExpected.getUnspecifiedType(), actual.getUnspecifiedType())
|
||||
)
|
||||
or
|
||||
|
||||
@@ -29,19 +29,11 @@ class ImproperNullTerminationReachability extends StackVariableReachabilityWithR
|
||||
override predicate isSourceActual(ControlFlowNode node, StackVariable v) {
|
||||
node = declWithNoInit(v)
|
||||
or
|
||||
exists(Call c, int bufferArg, int sizeArg |
|
||||
exists(Call c, VariableAccess va |
|
||||
c = node and
|
||||
(
|
||||
c.getTarget().hasName("readlink") and bufferArg = 1 and sizeArg = 2
|
||||
or
|
||||
c.getTarget().hasName("readlinkat") and bufferArg = 2 and sizeArg = 3
|
||||
) and
|
||||
c.getArgument(bufferArg).(VariableAccess).getTarget() = v and
|
||||
(
|
||||
// buffer size parameter likely matches the full buffer size
|
||||
c.getArgument(sizeArg) instanceof SizeofOperator or
|
||||
c.getArgument(sizeArg).getValue().toInt() = v.getType().getSize()
|
||||
)
|
||||
c.getTarget().hasName("readlink") and
|
||||
c.getArgument(1) = va and
|
||||
va.getTarget() = v
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ DeclStmt declWithNoInit(LocalVariable v) {
|
||||
result.getADeclaration() = v and
|
||||
not exists(v.getInitializer()) and
|
||||
/* The type of the variable is not stack-allocated. */
|
||||
exists(Type t | t = v.getType() | not allocatedType(t))
|
||||
not allocatedType(v.getType())
|
||||
}
|
||||
|
||||
class UninitialisedLocalReachability extends StackVariableReachability {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* @tags reliability
|
||||
* external/cwe/cwe-573
|
||||
* external/cwe/cwe-252
|
||||
* @opaque-id SM02344
|
||||
* @microsoft.severity Important
|
||||
*/
|
||||
|
||||
|
||||
@@ -15,122 +15,58 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Overflow
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import DataFlow::PathGraph
|
||||
import semmle.code.cpp.security.TaintTracking
|
||||
import TaintedWithPath
|
||||
import Bounded
|
||||
|
||||
/**
|
||||
* A function that outputs random data such as `std::rand`.
|
||||
*/
|
||||
abstract class RandomFunction extends Function {
|
||||
/**
|
||||
* Gets the `FunctionOutput` that describes how this function returns the random data.
|
||||
*/
|
||||
FunctionOutput getFunctionOutput() { result.isReturnValue() }
|
||||
predicate isUnboundedRandCall(FunctionCall fc) {
|
||||
exists(Function func | func = fc.getTarget() |
|
||||
func.hasGlobalOrStdOrBslName("rand") and
|
||||
not bounded(fc) and
|
||||
func.getNumberOfParameters() = 0
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard function `std::rand`.
|
||||
*/
|
||||
private class StdRand extends RandomFunction {
|
||||
StdRand() {
|
||||
this.hasGlobalOrStdOrBslName("rand") and
|
||||
this.getNumberOfParameters() = 0
|
||||
}
|
||||
predicate isUnboundedRandCallOrParent(Expr e) {
|
||||
isUnboundedRandCall(e)
|
||||
or
|
||||
isUnboundedRandCallOrParent(e.getAChild())
|
||||
}
|
||||
|
||||
/**
|
||||
* The Unix function `rand_r`.
|
||||
*/
|
||||
private class RandR extends RandomFunction {
|
||||
RandR() {
|
||||
this.hasGlobalName("rand_r") and
|
||||
this.getNumberOfParameters() = 1
|
||||
}
|
||||
predicate isUnboundedRandValue(Expr e) {
|
||||
isUnboundedRandCall(e)
|
||||
or
|
||||
exists(MacroInvocation mi |
|
||||
e = mi.getExpr() and
|
||||
isUnboundedRandCallOrParent(e)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The Unix function `random`.
|
||||
*/
|
||||
private class Random extends RandomFunction {
|
||||
Random() {
|
||||
this.hasGlobalName("random") and
|
||||
this.getNumberOfParameters() = 1
|
||||
class SecurityOptionsArith extends SecurityOptions {
|
||||
override predicate isUserInput(Expr expr, string cause) {
|
||||
isUnboundedRandValue(expr) and
|
||||
cause = "rand"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Windows `rand_s` function.
|
||||
*/
|
||||
private class RandS extends RandomFunction {
|
||||
RandS() {
|
||||
this.hasGlobalName("rand_s") and
|
||||
this.getNumberOfParameters() = 1
|
||||
}
|
||||
|
||||
override FunctionOutput getFunctionOutput() { result.isParameterDeref(0) }
|
||||
}
|
||||
|
||||
predicate missingGuard(VariableAccess va, string effect) {
|
||||
exists(Operation op | op.getAnOperand() = va |
|
||||
// underflow - random numbers are usually non-negative, so underflow is
|
||||
// only likely if the type is unsigned. Multiplication is also unlikely to
|
||||
// cause underflow of a non-negative number.
|
||||
missingGuardAgainstUnderflow(op, va) and
|
||||
effect = "underflow" and
|
||||
op.getUnspecifiedType().(IntegralType).isUnsigned() and
|
||||
not op instanceof MulExpr
|
||||
missingGuardAgainstUnderflow(op, va) and effect = "underflow"
|
||||
or
|
||||
// overflow
|
||||
missingGuardAgainstOverflow(op, va) and effect = "overflow"
|
||||
)
|
||||
}
|
||||
|
||||
class UncontrolledArithConfiguration extends TaintTracking::Configuration {
|
||||
UncontrolledArithConfiguration() { this = "UncontrolledArithConfiguration" }
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element e) { missingGuard(e, _) }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(RandomFunction rand, Call call | call.getTarget() = rand |
|
||||
rand.getFunctionOutput().isReturnValue() and
|
||||
source.asExpr() = call
|
||||
or
|
||||
exists(int n |
|
||||
source.asDefiningArgument() = call.getArgument(n) and
|
||||
rand.getFunctionOutput().isParameterDeref(n)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { missingGuard(sink.asExpr(), _) }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
bounded(node.asExpr())
|
||||
or
|
||||
// If this expression is part of bitwise 'and' or 'or' operation it's likely that the value is
|
||||
// only used as a bit pattern.
|
||||
node.asExpr() =
|
||||
any(Operation op |
|
||||
op instanceof BitwiseOrExpr or
|
||||
op instanceof BitwiseAndExpr or
|
||||
op instanceof ComplementExpr
|
||||
).getAnOperand*()
|
||||
or
|
||||
// block unintended flow to pointers
|
||||
node.asExpr().getUnspecifiedType() instanceof PointerType
|
||||
}
|
||||
override predicate isBarrier(Expr e) { super.isBarrier(e) or bounded(e) }
|
||||
}
|
||||
|
||||
/** Gets the expression that corresponds to `node`, if any. */
|
||||
Expr getExpr(DataFlow::Node node) { result = [node.asExpr(), node.asDefiningArgument()] }
|
||||
|
||||
from
|
||||
UncontrolledArithConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink,
|
||||
VariableAccess va, string effect
|
||||
from Expr origin, VariableAccess va, string effect, PathNode sourceNode, PathNode sinkNode
|
||||
where
|
||||
config.hasFlowPath(source, sink) and
|
||||
sink.getNode().asExpr() = va and
|
||||
taintedWithPath(origin, va, sourceNode, sinkNode) and
|
||||
missingGuard(va, effect)
|
||||
select sink.getNode(), source, sink,
|
||||
"$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
|
||||
getExpr(source.getNode()), "Uncontrolled value"
|
||||
select va, sourceNode, sinkNode,
|
||||
"$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".", origin,
|
||||
"Uncontrolled value"
|
||||
|
||||
@@ -7,6 +7,25 @@ private import cpp
|
||||
private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||
|
||||
/**
|
||||
* An operand `e` of a division expression (i.e., `e` is an operand of either a `DivExpr` or
|
||||
* a `AssignDivExpr`) is bounded when `e` is the left-hand side of the division.
|
||||
*/
|
||||
pragma[inline]
|
||||
private predicate boundedDiv(Expr e, Expr left) { e = left }
|
||||
|
||||
/**
|
||||
* An operand `e` of a remainder expression `rem` (i.e., `rem` is either a `RemExpr` or
|
||||
* an `AssignRemExpr`) with left-hand side `left` and right-ahnd side `right` is bounded
|
||||
* when `e` is `left` and `right` is upper bounded by some number that is less than the maximum integer
|
||||
* allowed by the result type of `rem`.
|
||||
*/
|
||||
pragma[inline]
|
||||
private predicate boundedRem(Expr e, Expr rem, Expr left, Expr right) {
|
||||
e = left and
|
||||
upperBound(right.getFullyConverted()) < exprMaxVal(rem.getFullyConverted())
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand `e` of a bitwise and expression `andExpr` (i.e., `andExpr` is either an `BitwiseAndExpr`
|
||||
* or an `AssignAndExpr`) with operands `operand1` and `operand2` is the operand that is not `e` is upper
|
||||
@@ -31,10 +50,19 @@ predicate bounded(Expr e) {
|
||||
) and
|
||||
not convertedExprMightOverflow(e)
|
||||
or
|
||||
// Optimitically assume that a remainder expression always yields a much smaller value.
|
||||
e = any(RemExpr rem).getLeftOperand()
|
||||
// For `%` and `&` we require that `e` is bounded by a value that is strictly smaller than the
|
||||
// maximum possible value of the result type of the operation.
|
||||
// For example, the function call `rand()` is considered bounded in the following program:
|
||||
// ```
|
||||
// int i = rand() % (UINT8_MAX + 1);
|
||||
// ```
|
||||
// but not in:
|
||||
// ```
|
||||
// unsigned char uc = rand() % (UINT8_MAX + 1);
|
||||
// ```
|
||||
exists(RemExpr rem | boundedRem(e, rem, rem.getLeftOperand(), rem.getRightOperand()))
|
||||
or
|
||||
e = any(AssignRemExpr rem).getLValue()
|
||||
exists(AssignRemExpr rem | boundedRem(e, rem, rem.getLValue(), rem.getRValue()))
|
||||
or
|
||||
exists(BitwiseAndExpr andExpr |
|
||||
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand())
|
||||
@@ -45,11 +73,11 @@ predicate bounded(Expr e) {
|
||||
)
|
||||
or
|
||||
// Optimitically assume that a division always yields a much smaller value.
|
||||
e = any(DivExpr div).getLeftOperand()
|
||||
boundedDiv(e, any(DivExpr div).getLeftOperand())
|
||||
or
|
||||
e = any(AssignDivExpr div).getLValue()
|
||||
boundedDiv(e, any(AssignDivExpr div).getLValue())
|
||||
or
|
||||
e = any(RShiftExpr shift).getLeftOperand()
|
||||
boundedDiv(e, any(RShiftExpr shift).getLeftOperand())
|
||||
or
|
||||
e = any(AssignRShiftExpr div).getLValue()
|
||||
boundedDiv(e, any(AssignRShiftExpr div).getLValue())
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.5
|
||||
* @precision high
|
||||
* @precision medium
|
||||
* @id cpp/cleartext-storage-file
|
||||
* @tags security
|
||||
* external/cwe/cwe-313
|
||||
@@ -14,40 +14,10 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.security.SensitiveExprs
|
||||
import semmle.code.cpp.security.FileWrite
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
|
||||
/**
|
||||
* An operation on a filename.
|
||||
*/
|
||||
predicate filenameOperation(FunctionCall op, Expr path) {
|
||||
exists(string name | name = op.getTarget().getName() |
|
||||
name =
|
||||
[
|
||||
"remove", "unlink", "rmdir", "rename", "fopen", "open", "freopen", "_open", "_wopen",
|
||||
"_wfopen", "_fsopen", "_wfsopen", "chmod", "chown", "stat", "lstat", "fstat", "access",
|
||||
"_access", "_waccess", "_access_s", "_waccess_s"
|
||||
] and
|
||||
path = op.getArgument(0)
|
||||
or
|
||||
name = ["fopen_s", "wfopen_s", "rename"] and
|
||||
path = op.getArgument(1)
|
||||
)
|
||||
}
|
||||
|
||||
predicate isFileName(GVN gvn) {
|
||||
exists(FunctionCall op, Expr path |
|
||||
filenameOperation(op, path) and
|
||||
gvn = globalValueNumber(path)
|
||||
)
|
||||
}
|
||||
|
||||
from FileWrite w, SensitiveExpr source, Expr mid, Expr dest
|
||||
from FileWrite w, SensitiveExpr source, Expr dest
|
||||
where
|
||||
DataFlow::localFlow(DataFlow::exprNode(source), DataFlow::exprNode(mid)) and
|
||||
mid = w.getASource() and
|
||||
dest = w.getDest() and
|
||||
not isFileName(globalValueNumber(source)) and // file names are not passwords
|
||||
not exists(string convChar | convChar = w.getSourceConvChar(mid) | not convChar = ["s", "S"]) // ignore things written with other conversion characters
|
||||
source = w.getASource() and
|
||||
dest = w.getDest()
|
||||
select w, "This write into file '" + dest.toString() + "' may contain unencrypted data from $@",
|
||||
source, "this source."
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.7
|
||||
* @precision high
|
||||
* @precision medium
|
||||
* @id cpp/toctou-race-condition
|
||||
* @tags security
|
||||
* external/cwe/cwe-367
|
||||
@@ -16,60 +16,59 @@ import cpp
|
||||
import semmle.code.cpp.controlflow.Guards
|
||||
|
||||
/**
|
||||
* An operation on a filename that is likely to modify the corresponding file
|
||||
* and may return an indication of success.
|
||||
* An operation on a filename.
|
||||
*
|
||||
* Note: we're not interested in operations where the file is specified by a
|
||||
* descriptor, rather than a filename, as they are better behaved. We are
|
||||
* interested in functions that take a filename and return a file descriptor,
|
||||
* however.
|
||||
* Note: we're not interested in operations on file descriptors, as they
|
||||
* are better behaved.
|
||||
*/
|
||||
FunctionCall filenameOperation(Expr path) {
|
||||
exists(string name | name = result.getTarget().getName() |
|
||||
name =
|
||||
[
|
||||
"remove", "unlink", "rmdir", "rename", "fopen", "open", "freopen", "_open", "_wopen",
|
||||
"_wfopen", "_fsopen", "_wfsopen"
|
||||
] and
|
||||
(
|
||||
name = "remove" or
|
||||
name = "unlink" or
|
||||
name = "rmdir" or
|
||||
name = "rename" or
|
||||
name = "chmod" or
|
||||
name = "chown" or
|
||||
name = "fopen" or
|
||||
name = "open" or
|
||||
name = "freopen" or
|
||||
name = "_open" or
|
||||
name = "_wopen" or
|
||||
name = "_wfopen"
|
||||
) and
|
||||
result.getArgument(0) = path
|
||||
or
|
||||
name = ["fopen_s", "wfopen_s", "rename"] and
|
||||
(
|
||||
name = "fopen_s" or
|
||||
name = "wfopen_s"
|
||||
) and
|
||||
result.getArgument(1) = path
|
||||
)
|
||||
or
|
||||
result = sensitiveFilenameOperation(path)
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation on a filename that is likely to modify the security properties
|
||||
* of the corresponding file and may return an indication of success.
|
||||
*/
|
||||
FunctionCall sensitiveFilenameOperation(Expr path) {
|
||||
exists(string name | name = result.getTarget().getName() |
|
||||
name = ["chmod", "chown"] and
|
||||
result.getArgument(0) = path
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation on a filename that returns information in the return value but
|
||||
* does not modify the corresponding file. For example, `access`.
|
||||
* A use of `access` (or similar) on a filename.
|
||||
*/
|
||||
FunctionCall accessCheck(Expr path) {
|
||||
exists(string name | name = result.getTarget().getName() |
|
||||
name = ["access", "_access", "_waccess", "_access_s", "_waccess_s"]
|
||||
name = "access" or
|
||||
name = "_access" or
|
||||
name = "_waccess" or
|
||||
name = "_access_s" or
|
||||
name = "_waccess_s"
|
||||
) and
|
||||
path = result.getArgument(0)
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation on a filename that returns information via a pointer argument
|
||||
* and any return value, but does not modify the corresponding file. For
|
||||
* example, `stat`.
|
||||
* A use of `stat` (or similar) on a filename.
|
||||
*/
|
||||
FunctionCall stat(Expr path, Expr buf) {
|
||||
exists(string name | name = result.getTarget().getName() |
|
||||
name = ["stat", "lstat", "fstat"] or
|
||||
name = "stat" or
|
||||
name = "lstat" or
|
||||
name = "fstat" or
|
||||
name.matches("\\_stat%") or
|
||||
name.matches("\\_wstat%")
|
||||
) and
|
||||
@@ -78,7 +77,7 @@ FunctionCall stat(Expr path, Expr buf) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `use` refers to `source`, either by being the same or by
|
||||
* Holds if `use` points to `source`, either by being the same or by
|
||||
* one step of variable indirection.
|
||||
*/
|
||||
predicate referenceTo(Expr source, Expr use) {
|
||||
@@ -89,45 +88,36 @@ predicate referenceTo(Expr source, Expr use) {
|
||||
)
|
||||
}
|
||||
|
||||
from Expr check, Expr checkPath, FunctionCall use, Expr usePath
|
||||
from FunctionCall fc, Expr check, Expr checkUse, Expr opUse
|
||||
where
|
||||
// `check` looks like a check on a filename
|
||||
// checkUse looks like a check on a filename
|
||||
(
|
||||
(
|
||||
// either:
|
||||
// an access check
|
||||
check = accessCheck(checkPath)
|
||||
or
|
||||
// a stat
|
||||
check = stat(checkPath, _)
|
||||
or
|
||||
// access to a member variable on the stat buf
|
||||
// (morally, this should be a use-use pair, but it seems unlikely
|
||||
// that this variable will get reused in practice)
|
||||
exists(Expr call, Expr e, Variable v |
|
||||
call = stat(checkPath, e) and
|
||||
e.getAChild*().(VariableAccess).getTarget() = v and
|
||||
check.(VariableAccess).getTarget() = v and
|
||||
not e.getAChild*() = check // the call that writes to the pointer is not where the pointer is checked.
|
||||
)
|
||||
) and
|
||||
// `op` looks like an operation on a filename
|
||||
use = filenameOperation(usePath)
|
||||
// either:
|
||||
// an access check
|
||||
check = accessCheck(checkUse)
|
||||
or
|
||||
// a stat
|
||||
check = stat(checkUse, _)
|
||||
or
|
||||
// another filename operation (null pointers can indicate errors)
|
||||
check = filenameOperation(checkPath) and
|
||||
// `op` looks like a sensitive operation on a filename
|
||||
use = sensitiveFilenameOperation(usePath)
|
||||
check = filenameOperation(checkUse)
|
||||
or
|
||||
// access to a member variable on the stat buf
|
||||
// (morally, this should be a use-use pair, but it seems unlikely
|
||||
// that this variable will get reused in practice)
|
||||
exists(Variable buf | exists(stat(checkUse, buf.getAnAccess())) |
|
||||
check.(VariableAccess).getQualifier() = buf.getAnAccess()
|
||||
)
|
||||
) and
|
||||
// `checkPath` and `usePath` refer to the same SSA variable
|
||||
exists(SsaDefinition def, StackVariable v |
|
||||
def.getAUse(v) = checkPath and def.getAUse(v) = usePath
|
||||
) and
|
||||
// the return value of `check` is used (possibly with one step of
|
||||
// variable indirection) in a guard which controls `use`
|
||||
// checkUse and opUse refer to the same SSA variable
|
||||
exists(SsaDefinition def, StackVariable v | def.getAUse(v) = checkUse and def.getAUse(v) = opUse) and
|
||||
// opUse looks like an operation on a filename
|
||||
fc = filenameOperation(opUse) and
|
||||
// the return value of check is used (possibly with one step of
|
||||
// variable indirection) in a guard which controls fc
|
||||
exists(GuardCondition guard | referenceTo(check, guard.getAChild*()) |
|
||||
guard.controls(use.(ControlFlowNode).getBasicBlock(), _)
|
||||
guard.controls(fc.(ControlFlowNode).getBasicBlock(), _)
|
||||
)
|
||||
select use,
|
||||
select fc,
|
||||
"The $@ being operated upon was previously $@, but the underlying file may have been changed since then.",
|
||||
usePath, "filename", check, "checked"
|
||||
opUse, "filename", check, "checked"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.8
|
||||
* @opaque-id SM02313
|
||||
* @id cpp/conditionally-uninitialized-variable
|
||||
* @tags security
|
||||
* external/cwe/cwe-457
|
||||
|
||||
@@ -182,7 +182,7 @@ class ThrowingAllocator extends Function {
|
||||
// 3. the allocator isn't marked with `throw()` or `noexcept`.
|
||||
not exists(this.getBlock()) and
|
||||
not exists(Parameter p | p = this.getAParameter() |
|
||||
p.getUnspecifiedType().stripType() instanceof NoThrowType
|
||||
p.getUnspecifiedType() instanceof NoThrowType
|
||||
) and
|
||||
not this.isNoExcept() and
|
||||
not this.isNoThrow()
|
||||
|
||||
@@ -26,7 +26,7 @@ can use their own storage.</p>
|
||||
<p>Similarly replace calls to <code>localtime</code> with
|
||||
<code>localtime_r</code>, calls to <code>ctime</code> with
|
||||
<code>ctime_r</code> and calls to <code>asctime</code> with
|
||||
<code>asctime_r</code> (if those functions exist on your platform).</p>
|
||||
<code>asctime_r</code>.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 10.0
|
||||
* @precision medium
|
||||
* @precision high
|
||||
* @id cpp/potentially-dangerous-function
|
||||
* @tags reliability
|
||||
* security
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* @description The total number of lines of C/C++ code across all files, including system headers, libraries, and auto-generated files. This is a useful metric of the size of a database. For all files that were seen during the build, this query counts the lines of code, excluding whitespace or comments.
|
||||
* @kind metric
|
||||
* @tags summary
|
||||
* lines-of-code
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
- description: Standard Code Scanning queries for C and C++
|
||||
- queries: .
|
||||
- qlpack: codeql-cpp
|
||||
- apply: code-scanning-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
from: codeql-suite-helpers
|
||||
- apply: codeql-suites/exclude-slow-queries.yml
|
||||
from: codeql/cpp-queries
|
||||
from: codeql-cpp
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
- description: Standard LGTM queries for C/C++, including ones not displayed by default
|
||||
- queries: .
|
||||
- qlpack: codeql-cpp
|
||||
- apply: lgtm-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
from: codeql-suite-helpers
|
||||
- apply: codeql-suites/exclude-slow-queries.yml
|
||||
from: codeql/cpp-queries
|
||||
from: codeql-cpp
|
||||
# These are only for IDE use.
|
||||
- exclude:
|
||||
tags contain:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- description: Standard LGTM queries for C/C++
|
||||
- apply: codeql-suites/cpp-lgtm-full.qls
|
||||
- apply: lgtm-displayed-only.yml
|
||||
from: codeql/suite-helpers
|
||||
from: codeql-suite-helpers
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
- description: Security-and-quality queries for C and C++
|
||||
- queries: .
|
||||
- qlpack: codeql-cpp
|
||||
- apply: security-and-quality-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
from: codeql-suite-helpers
|
||||
- apply: codeql-suites/exclude-slow-queries.yml
|
||||
from: codeql/cpp-queries
|
||||
from: codeql-cpp
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
- description: Security-extended queries for C and C++
|
||||
- queries: .
|
||||
- qlpack: codeql-cpp
|
||||
- apply: security-extended-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
from: codeql-suite-helpers
|
||||
- apply: codeql-suites/exclude-slow-queries.yml
|
||||
from: codeql/cpp-queries
|
||||
from: codeql-cpp
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
...
|
||||
int i1;
|
||||
char c1;
|
||||
...
|
||||
if((c1<50)&&(c>10))
|
||||
switch(c1){
|
||||
case 300: // BAD: the code will not be executed
|
||||
...
|
||||
if((i1<5)&&(i1>0))
|
||||
switch(i1){ // BAD
|
||||
case 21: // BAD: the code will not be executed
|
||||
...
|
||||
switch(c1){
|
||||
...
|
||||
dafault: // BAD: maybe it will be right `default`
|
||||
...
|
||||
}
|
||||
|
||||
...
|
||||
switch(c1){
|
||||
i1=c1*2; // BAD: the code will not be executed
|
||||
case 12:
|
||||
...
|
||||
switch(c1){ // GOOD
|
||||
case 12:
|
||||
break;
|
||||
case 10:
|
||||
break;
|
||||
case 9:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
...
|
||||
@@ -1,24 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>A mismatch between conditionals and <code>switch</code> cases can lead to control-flow violations (CWE-691) where the developer either does not handle all combinations of conditions or unintentionally created dead code (CWE-561).</p>
|
||||
|
||||
|
||||
</overview>
|
||||
|
||||
<example>
|
||||
<p>The following example demonstrates fallacious and fixed ways of using a <code>switch</code> statement.</p>
|
||||
<sample src="FindIncorrectlyUsedSwitch.c" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
CERT C Coding Standard:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/c/MSC12-C.+Detect+and+remove+code+that+has+no+effect+or+is+never+executed">MSC12-C. Detect and remove code that has no effect or is never executed</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,153 +0,0 @@
|
||||
/**
|
||||
* @name Incorrect switch statement
|
||||
* @description --Finding places the dangerous use of a switch.
|
||||
* --For example, when the range of values for a condition does not cover all of the selection values..
|
||||
* @kind problem
|
||||
* @id cpp/operator-find-incorrectly-used-switch
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-561
|
||||
* external/cwe/cwe-691
|
||||
* external/cwe/cwe-478
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
|
||||
/** Holds if the range contains no boundary values. */
|
||||
predicate isRealRange(Expr exp) {
|
||||
upperBound(exp).toString() != "18446744073709551616" and
|
||||
upperBound(exp).toString() != "9223372036854775807" and
|
||||
upperBound(exp).toString() != "4294967295" and
|
||||
upperBound(exp).toString() != "Infinity" and
|
||||
upperBound(exp).toString() != "NaN" and
|
||||
lowerBound(exp).toString() != "-9223372036854775808" and
|
||||
lowerBound(exp).toString() != "-4294967296" and
|
||||
lowerBound(exp).toString() != "-Infinity" and
|
||||
lowerBound(exp).toString() != "NaN" and
|
||||
upperBound(exp) != 2147483647 and
|
||||
upperBound(exp) != 268435455 and
|
||||
upperBound(exp) != 33554431 and
|
||||
upperBound(exp) != 8388607 and
|
||||
upperBound(exp) != 65535 and
|
||||
upperBound(exp) != 32767 and
|
||||
upperBound(exp) != 255 and
|
||||
upperBound(exp) != 127 and
|
||||
upperBound(exp) != 63 and
|
||||
upperBound(exp) != 31 and
|
||||
upperBound(exp) != 15 and
|
||||
upperBound(exp) != 7 and
|
||||
lowerBound(exp) != -2147483648 and
|
||||
lowerBound(exp) != -268435456 and
|
||||
lowerBound(exp) != -33554432 and
|
||||
lowerBound(exp) != -8388608 and
|
||||
lowerBound(exp) != -65536 and
|
||||
lowerBound(exp) != -32768 and
|
||||
lowerBound(exp) != -128
|
||||
}
|
||||
|
||||
/** Holds if the range of values for the condition is less than the choices. */
|
||||
predicate isNotAllSelected(SwitchStmt swtmp) {
|
||||
not swtmp.getExpr().isConstant() and
|
||||
exists(int i |
|
||||
i != 0 and
|
||||
(
|
||||
i = lowerBound(swtmp.getASwitchCase().getExpr()) and
|
||||
upperBound(swtmp.getExpr()) < i
|
||||
or
|
||||
(
|
||||
i = upperBound(swtmp.getASwitchCase().getExpr()) or
|
||||
i = upperBound(swtmp.getASwitchCase().getEndExpr())
|
||||
) and
|
||||
lowerBound(swtmp.getExpr()) > i
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the range of values for the condition is greater than the selection. */
|
||||
predicate isConditionBig(SwitchStmt swtmp) {
|
||||
not swtmp.hasDefaultCase() and
|
||||
not exists(int iu, int il |
|
||||
(
|
||||
iu = upperBound(swtmp.getASwitchCase().getExpr()) or
|
||||
iu = upperBound(swtmp.getASwitchCase().getEndExpr())
|
||||
) and
|
||||
upperBound(swtmp.getExpr()) = iu and
|
||||
(
|
||||
il = lowerBound(swtmp.getASwitchCase().getExpr()) or
|
||||
il = lowerBound(swtmp.getASwitchCase().getEndExpr())
|
||||
) and
|
||||
lowerBound(swtmp.getExpr()) = il
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if there are labels inside the block with names similar to `default` or `case`. */
|
||||
predicate isWrongLableName(SwitchStmt swtmp) {
|
||||
not swtmp.hasDefaultCase() and
|
||||
exists(LabelStmt lb |
|
||||
(
|
||||
(
|
||||
lb.getName().charAt(0) = "d" or
|
||||
lb.getName().charAt(0) = "c"
|
||||
) and
|
||||
(
|
||||
lb.getName().charAt(1) = "e" or
|
||||
lb.getName().charAt(1) = "a"
|
||||
) and
|
||||
(
|
||||
lb.getName().charAt(2) = "f" or
|
||||
lb.getName().charAt(2) = "s"
|
||||
)
|
||||
) and
|
||||
lb.getEnclosingStmt().getParentStmt*() = swtmp.getStmt() and
|
||||
not exists(GotoStmt gs | gs.getName() = lb.getName())
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the block contains code before the first `case`. */
|
||||
predicate isCodeBeforeCase(SwitchStmt swtmp) {
|
||||
exists(Expr exp |
|
||||
exp.getEnclosingStmt().getParentStmt*() = swtmp.getStmt() and
|
||||
not exists(Loop lp |
|
||||
exp.getEnclosingStmt().getParentStmt*() = lp and
|
||||
lp.getEnclosingStmt().getParentStmt*() = swtmp.getStmt()
|
||||
) and
|
||||
not exists(Stmt sttmp, SwitchCase sctmp |
|
||||
sttmp = swtmp.getASwitchCase().getAStmt() and
|
||||
sctmp = swtmp.getASwitchCase() and
|
||||
(
|
||||
exp.getEnclosingStmt().getParentStmt*() = sttmp or
|
||||
exp.getEnclosingStmt() = sctmp
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
from SwitchStmt sw, string msg
|
||||
where
|
||||
isRealRange(sw.getExpr()) and
|
||||
lowerBound(sw.getExpr()) != upperBound(sw.getExpr()) and
|
||||
lowerBound(sw.getExpr()) != 0 and
|
||||
not exists(Expr cexp |
|
||||
cexp = sw.getASwitchCase().getExpr() and not isRealRange(cexp)
|
||||
or
|
||||
cexp = sw.getASwitchCase().getEndExpr() and not isRealRange(cexp)
|
||||
) and
|
||||
not exists(Expr exptmp |
|
||||
exptmp = sw.getExpr().getAChild*() and
|
||||
not exptmp.isConstant() and
|
||||
not isRealRange(exptmp)
|
||||
) and
|
||||
(sw.getASwitchCase().terminatesInBreakStmt() or sw.getASwitchCase().terminatesInReturnStmt()) and
|
||||
(
|
||||
isNotAllSelected(sw) and msg = "The range of condition values is less than the selection."
|
||||
or
|
||||
isConditionBig(sw) and msg = "The range of condition values is wider than the choices."
|
||||
)
|
||||
or
|
||||
isWrongLableName(sw) and msg = "Possibly erroneous label name."
|
||||
or
|
||||
isCodeBeforeCase(sw) and msg = "Code before case will not be executed."
|
||||
select sw, msg
|
||||
@@ -1,9 +0,0 @@
|
||||
...
|
||||
throw ("my exception!",546); // BAD
|
||||
...
|
||||
throw errorFunc("my exception!",546); // GOOD
|
||||
...
|
||||
std::runtime_error("msg error"); // BAD
|
||||
...
|
||||
throw std::runtime_error("msg error"); // GOOD
|
||||
...
|
||||
@@ -1,23 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Finding places for the dangerous use of exceptions.</p>
|
||||
|
||||
</overview>
|
||||
|
||||
<example>
|
||||
<p>The following example demonstrates erroneous and fixed methods for using exceptions.</p>
|
||||
<sample src="FindIncorrectlyUsedExceptions.cpp" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
CERT CPP Coding Standard:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL57-CPP.+Do+not+let+exceptions+escape+from+destructors+or+deallocation+functions">DCL57-CPP. Do not let exceptions escape from destructors or deallocation functions</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* @name Operator Find Incorrectly Used Exceptions
|
||||
* @description --Finding places for the dangerous use of exceptions.
|
||||
* @kind problem
|
||||
* @id cpp/operator-find-incorrectly-used-exceptions
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-703
|
||||
* external/cwe/cwe-248
|
||||
* external/cwe/cwe-390
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from FunctionCall fc, string msg
|
||||
where
|
||||
exists(ThrowExpr texp |
|
||||
texp.getEnclosingFunction() = fc.getTarget() and
|
||||
(
|
||||
fc.getTarget().hasGlobalOrStdName("DllMain") and
|
||||
not exists(TryStmt ts |
|
||||
texp.getEnclosingStmt().getParentStmt*() = ts.getStmt() and
|
||||
not ts.getACatchClause().isEmpty()
|
||||
) and
|
||||
msg = "DllMain contains an exeption not wrapped in a try..catch block."
|
||||
or
|
||||
texp.getExpr().isParenthesised() and
|
||||
texp.getExpr().(CommaExpr).getLeftOperand().isConstant() and
|
||||
texp.getExpr().(CommaExpr).getRightOperand().isConstant() and
|
||||
msg = "There is an exception in the function that requires your attention."
|
||||
)
|
||||
)
|
||||
or
|
||||
fc.getTarget() instanceof Constructor and
|
||||
(
|
||||
fc.getTargetType().(Class).getABaseClass+().hasGlobalOrStdName("exception") or
|
||||
fc.getTargetType().(Class).getABaseClass+().hasGlobalOrStdName("CException")
|
||||
) and
|
||||
not fc.isInMacroExpansion() and
|
||||
not exists(ThrowExpr texp | fc.getEnclosingStmt() = texp.getEnclosingStmt()) and
|
||||
not exists(FunctionCall fctmp | fctmp.getAnArgument() = fc) and
|
||||
not fc instanceof ConstructorDirectInit and
|
||||
not fc.getEnclosingStmt() instanceof DeclStmt and
|
||||
not fc instanceof ConstructorDelegationInit and
|
||||
not fc.getParent() instanceof Initializer and
|
||||
not fc.getParent() instanceof AllocationExpr and
|
||||
msg = "This object does not generate an exception."
|
||||
select fc, msg
|
||||
@@ -1,12 +0,0 @@
|
||||
intA = ++intA + 1; // BAD: undefined behavior when changing variable `intA`
|
||||
...
|
||||
intA++;
|
||||
intA = intA + 1; // GOOD: correct design
|
||||
...
|
||||
char * buff;
|
||||
...
|
||||
if(funcAdd(buff)+fucDel(buff)>0) return 1; // BAD: undefined behavior when calling functions to change the `buff` variable
|
||||
...
|
||||
intA = funcAdd(buff);
|
||||
intB = funcDel(buff);
|
||||
if(intA+intB>0) return 1; // GOOD: correct design
|
||||
@@ -1,28 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>In some situations, the code constructs used may be executed in the wrong order in which the developer designed them. For example, if you call multiple functions as part of a single expression, and the functions have the ability to modify a shared resource, then the sequence in which the resource is changed can be unpredictable. These code snippets look suspicious and require the developer's attention.</p>
|
||||
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>We recommend that you use more guaranteed, in terms of sequence of execution, coding techniques.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>The following example demonstrates sections of code with insufficient execution sequence definition.</p>
|
||||
<sample src="UndefinedOrImplementationDefinedBehavior.c" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
CWE Common Weakness Enumeration:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP10-C.+Do+not+depend+on+the+order+of+evaluation+of+subexpressions+or+the+order+in+which+side+effects+take+place"> EXP10-C. Do not depend on the order of evaluation of subexpressions or the order in which side effects take place</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,167 +0,0 @@
|
||||
/**
|
||||
* @name Errors Of Undefined Program Behavior
|
||||
* @description --In some situations, the code constructs used may be executed in the wrong order in which the developer designed them.
|
||||
* --For example, if you call multiple functions as part of a single expression, and the functions have the ability to modify a shared resource, then the sequence in which the resource is changed can be unpredictable.
|
||||
* --These code snippets look suspicious and require the developer's attention.
|
||||
* @kind problem
|
||||
* @id cpp/errors-of-undefined-program-behavior
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @tags security
|
||||
* external/cwe/cwe-758
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.valuenumbering.HashCons
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
|
||||
/**
|
||||
* Threatening expressions of undefined behavior.
|
||||
*/
|
||||
class ExpressionsOfTheSameLevel extends Expr {
|
||||
Expr exp2;
|
||||
|
||||
ExpressionsOfTheSameLevel() {
|
||||
this != exp2 and
|
||||
this.getParent() = exp2.getParent()
|
||||
}
|
||||
|
||||
/** Holds if the underlying expression is a function call. */
|
||||
predicate expressionCall() {
|
||||
this instanceof FunctionCall and
|
||||
exp2.getAChild*() instanceof FunctionCall and
|
||||
not this.getParent() instanceof Operator and
|
||||
not this.(FunctionCall).hasQualifier()
|
||||
}
|
||||
|
||||
/** Holds if the underlying expression is a call to a function to free resources. */
|
||||
predicate existsCloseOrFreeCall() {
|
||||
(
|
||||
globalValueNumber(this.(FunctionCall).getAnArgument()) =
|
||||
globalValueNumber(exp2.getAChild*().(FunctionCall).getAnArgument()) or
|
||||
hashCons(this.(FunctionCall).getAnArgument()) =
|
||||
hashCons(exp2.getAChild*().(FunctionCall).getAnArgument())
|
||||
) and
|
||||
(
|
||||
this.(FunctionCall).getTarget().hasGlobalOrStdName("close") or
|
||||
this.(FunctionCall).getTarget().hasGlobalOrStdName("free") or
|
||||
this.(FunctionCall).getTarget().hasGlobalOrStdName("fclose")
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the arguments in the function can be changed. */
|
||||
predicate generalArgumentDerivedType() {
|
||||
exists(Parameter prt1, Parameter prt2, AssignExpr aet1, AssignExpr aet2, int i, int j |
|
||||
not this.(FunctionCall).getArgument(i).isConstant() and
|
||||
hashCons(this.(FunctionCall).getArgument(i)) =
|
||||
hashCons(exp2.getAChild*().(FunctionCall).getArgument(j)) and
|
||||
prt1 = this.(FunctionCall).getTarget().getParameter(i) and
|
||||
prt2 = exp2.getAChild*().(FunctionCall).getTarget().getParameter(j) and
|
||||
prt1.getType() instanceof DerivedType and
|
||||
(
|
||||
aet1 = this.(FunctionCall).getTarget().getEntryPoint().getASuccessor*() and
|
||||
(
|
||||
aet1.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() =
|
||||
prt1.getAnAccess().getTarget() or
|
||||
aet1.getLValue().(VariableAccess).getTarget() = prt1.getAnAccess().getTarget()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc1 |
|
||||
fc1.getTarget().hasGlobalName("memcpy") and
|
||||
fc1.getArgument(0).(VariableAccess).getTarget() = prt1.getAnAccess().getTarget() and
|
||||
fc1 = this.(FunctionCall).getTarget().getEntryPoint().getASuccessor*()
|
||||
)
|
||||
) and
|
||||
(
|
||||
aet2 = exp2.getAChild*().(FunctionCall).getTarget().getEntryPoint().getASuccessor*() and
|
||||
(
|
||||
aet2.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() =
|
||||
prt2.getAnAccess().getTarget() or
|
||||
aet2.getLValue().(VariableAccess).getTarget() = prt2.getAnAccess().getTarget()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc1 |
|
||||
fc1.getTarget().hasGlobalName("memcpy") and
|
||||
fc1.getArgument(0).(VariableAccess).getTarget() = prt2.getAnAccess().getTarget() and
|
||||
fc1 = exp2.(FunctionCall).getTarget().getEntryPoint().getASuccessor*()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if functions have a common global argument. */
|
||||
predicate generalGlobalArgument() {
|
||||
exists(Declaration dl, AssignExpr aet1, AssignExpr aet2 |
|
||||
dl instanceof GlobalVariable and
|
||||
(
|
||||
(
|
||||
aet1.getLValue().(Access).getTarget() = dl or
|
||||
aet1.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() = dl
|
||||
) and
|
||||
aet1 = this.(FunctionCall).getTarget().getEntryPoint().getASuccessor*() and
|
||||
not aet1.getRValue().isConstant()
|
||||
or
|
||||
exists(FunctionCall fc1 |
|
||||
fc1.getTarget().hasGlobalName("memcpy") and
|
||||
fc1.getArgument(0).(VariableAccess).getTarget() = dl and
|
||||
fc1 = this.(FunctionCall).getTarget().getEntryPoint().getASuccessor*()
|
||||
)
|
||||
) and
|
||||
(
|
||||
(
|
||||
aet2.getLValue().(Access).getTarget() = dl or
|
||||
aet2.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() = dl
|
||||
) and
|
||||
aet2 = exp2.(FunctionCall).getTarget().getEntryPoint().getASuccessor*()
|
||||
or
|
||||
exists(FunctionCall fc1 |
|
||||
fc1.getTarget().hasGlobalName("memcpy") and
|
||||
fc1.getArgument(0).(VariableAccess).getTarget() = dl and
|
||||
fc1 = exp2.(FunctionCall).getTarget().getEntryPoint().getASuccessor*()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if sequence point is not present in expression. */
|
||||
predicate orderOfActionExpressions() {
|
||||
not this.getParent() instanceof BinaryLogicalOperation and
|
||||
not this.getParent() instanceof ConditionalExpr and
|
||||
not this.getParent() instanceof Loop and
|
||||
not this.getParent() instanceof CommaExpr
|
||||
}
|
||||
|
||||
/** Holds if expression is crement. */
|
||||
predicate dangerousCrementChanges() {
|
||||
hashCons(this.(CrementOperation).getOperand()) = hashCons(exp2.(CrementOperation).getOperand())
|
||||
or
|
||||
hashCons(this.(CrementOperation).getOperand()) = hashCons(exp2)
|
||||
or
|
||||
hashCons(this.(CrementOperation).getOperand()) = hashCons(exp2.(ArrayExpr).getArrayOffset())
|
||||
or
|
||||
hashCons(this.(Assignment).getLValue()) = hashCons(exp2.(Assignment).getLValue())
|
||||
or
|
||||
not this.getAChild*() instanceof Call and
|
||||
(
|
||||
hashCons(this.getAChild*().(CrementOperation).getOperand()) = hashCons(exp2) or
|
||||
hashCons(this.getAChild*().(CrementOperation).getOperand()) =
|
||||
hashCons(exp2.(Assignment).getLValue())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from ExpressionsOfTheSameLevel eots
|
||||
where
|
||||
eots.orderOfActionExpressions() and
|
||||
(
|
||||
eots.expressionCall() and
|
||||
(
|
||||
eots.generalArgumentDerivedType() or
|
||||
eots.generalGlobalArgument() or
|
||||
eots.existsCloseOrFreeCall()
|
||||
)
|
||||
or
|
||||
eots.dangerousCrementChanges()
|
||||
)
|
||||
select eots,
|
||||
"This expression may have undefined behavior, because the order of evaluation is not specified."
|
||||
@@ -1,7 +0,0 @@
|
||||
bool a=1,b=0,c=1,res;
|
||||
...
|
||||
res = a||b^c; // BAD: possible priority error `res==1`
|
||||
...
|
||||
res = a||(b^c); // GOOD: `res==1`
|
||||
...
|
||||
res = (a||b)^c; // GOOD: `res==0`
|
||||
@@ -1,28 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Find places of confusing use of logical and bitwise operations.</p>
|
||||
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>We recommend using parentheses to explicitly emphasize priority.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>The following example demonstrates fallacious and fixed methods of using logical and bitwise operations.</p>
|
||||
<sample src="OperatorPrecedenceLogicErrorWhenUseBitwiseOrLogicalOperations.c" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
CERT C Coding Standard:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP00-C.+Use+parentheses+for+precedence+of+operation">EXP00-C. Use parentheses for precedence of operation</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,195 +0,0 @@
|
||||
/**
|
||||
* @name Operator Precedence Logic Error When Use Bitwise Or Logical Operations
|
||||
* @description --Finding places to use bit and logical operations, without explicit priority allocation.
|
||||
* --For example, `a || b ^ c` and `(a || b) ^ c` give different results when `b` is zero.
|
||||
* @kind problem
|
||||
* @id cpp/operator-precedence-logic-error-when-use-bitwise-logical-operations
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @tags maintainability
|
||||
* readability
|
||||
* external/cwe/cwe-783
|
||||
* external/cwe/cwe-480
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
|
||||
/** Holds if `exptmp` equals expression logical or followed by logical and. */
|
||||
predicate isLogicalOrAndExpr(LogicalOrExpr exptmp) {
|
||||
not exptmp.getLeftOperand() instanceof BinaryOperation and
|
||||
not exptmp.getRightOperand().isParenthesised() and
|
||||
exptmp.getRightOperand() instanceof LogicalAndExpr
|
||||
}
|
||||
|
||||
/** Holds if `exptmp` equals expression logical or followed by bit operation. */
|
||||
predicate isLogicalOrandBitwise(Expr exptmp) {
|
||||
not exptmp.(LogicalOrExpr).getLeftOperand() instanceof BinaryOperation and
|
||||
not exptmp.(LogicalOrExpr).getRightOperand().isParenthesised() and
|
||||
(
|
||||
exptmp.(LogicalOrExpr).getRightOperand().(BinaryBitwiseOperation).getLeftOperand().getType()
|
||||
instanceof BoolType and
|
||||
// The essence of these lines is to improve the quality of detection by eliminating the situation
|
||||
// of processing a logical type by bit operations. In fact, the predicate looks for a situation
|
||||
// when the left operand of a bit operation has a boolean type, which already suggests that the priority is not correct.
|
||||
// But if the right-hand operand is 0 or 1, then there is a possibility that the author intended so.
|
||||
not exptmp
|
||||
.(LogicalOrExpr)
|
||||
.getRightOperand()
|
||||
.(BinaryBitwiseOperation)
|
||||
.getRightOperand()
|
||||
.getValue() = "0" and
|
||||
not exptmp
|
||||
.(LogicalOrExpr)
|
||||
.getRightOperand()
|
||||
.(BinaryBitwiseOperation)
|
||||
.getRightOperand()
|
||||
.getValue() = "1"
|
||||
)
|
||||
or
|
||||
not exptmp.(LogicalAndExpr).getLeftOperand() instanceof BinaryOperation and
|
||||
not exptmp.(LogicalAndExpr).getRightOperand().isParenthesised() and
|
||||
(
|
||||
exptmp.(LogicalAndExpr).getRightOperand().(BinaryBitwiseOperation).getLeftOperand().getType()
|
||||
instanceof BoolType and
|
||||
// Looking for a situation in which the right-hand operand of a bit operation is not limited to 0 or 1.
|
||||
// In this case, the logical operation will be performed with the result of a binary operation that is not a Boolean type.
|
||||
// In my opinion this indicates a priority error. after all, it will be quite difficult for a developer
|
||||
// to evaluate the conversion of the results of a bit operation to a boolean type.
|
||||
not exptmp
|
||||
.(LogicalAndExpr)
|
||||
.getRightOperand()
|
||||
.(BinaryBitwiseOperation)
|
||||
.getRightOperand()
|
||||
.getValue() = "0" and
|
||||
not exptmp
|
||||
.(LogicalAndExpr)
|
||||
.getRightOperand()
|
||||
.(BinaryBitwiseOperation)
|
||||
.getRightOperand()
|
||||
.getValue() = "1"
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `exptmp` equals expression bit operations in reverse priority order. */
|
||||
predicate isBitwiseandBitwise(Expr exptmp) {
|
||||
not exptmp.(BitwiseOrExpr).getLeftOperand() instanceof BinaryOperation and
|
||||
not exptmp.(BitwiseOrExpr).getRightOperand().isParenthesised() and
|
||||
(
|
||||
exptmp.(BitwiseOrExpr).getRightOperand() instanceof BitwiseAndExpr or
|
||||
exptmp.(BitwiseOrExpr).getRightOperand() instanceof BitwiseXorExpr
|
||||
)
|
||||
or
|
||||
not exptmp.(BitwiseXorExpr).getLeftOperand() instanceof BinaryOperation and
|
||||
not exptmp.(BitwiseXorExpr).getRightOperand().isParenthesised() and
|
||||
exptmp.(BitwiseXorExpr).getRightOperand() instanceof BitwiseAndExpr
|
||||
}
|
||||
|
||||
/** Holds if the range contains no boundary values. */
|
||||
predicate isRealRange(Expr exp) {
|
||||
upperBound(exp).toString() != "18446744073709551616" and
|
||||
upperBound(exp).toString() != "9223372036854775807" and
|
||||
upperBound(exp).toString() != "4294967295" and
|
||||
upperBound(exp).toString() != "Infinity" and
|
||||
upperBound(exp).toString() != "NaN" and
|
||||
lowerBound(exp).toString() != "-9223372036854775808" and
|
||||
lowerBound(exp).toString() != "-4294967296" and
|
||||
lowerBound(exp).toString() != "-Infinity" and
|
||||
lowerBound(exp).toString() != "NaN" and
|
||||
upperBound(exp) != 2147483647 and
|
||||
upperBound(exp) != 268435455 and
|
||||
upperBound(exp) != 33554431 and
|
||||
upperBound(exp) != 8388607 and
|
||||
upperBound(exp) != 65535 and
|
||||
upperBound(exp) != 32767 and
|
||||
upperBound(exp) != 255 and
|
||||
upperBound(exp) != 127 and
|
||||
lowerBound(exp) != -2147483648 and
|
||||
lowerBound(exp) != -268435456 and
|
||||
lowerBound(exp) != -33554432 and
|
||||
lowerBound(exp) != -8388608 and
|
||||
lowerBound(exp) != -65536 and
|
||||
lowerBound(exp) != -32768 and
|
||||
lowerBound(exp) != -128
|
||||
or
|
||||
lowerBound(exp) = 0 and
|
||||
upperBound(exp) = 1
|
||||
}
|
||||
|
||||
/** Holds if expressions are of different size or range */
|
||||
pragma[inline]
|
||||
predicate isDifferentSize(Expr exp1, Expr exp2, Expr exp3) {
|
||||
exp1.getType().getSize() = exp2.getType().getSize() and
|
||||
exp1.getType().getSize() != exp3.getType().getSize()
|
||||
or
|
||||
(
|
||||
isRealRange(exp1) and
|
||||
isRealRange(exp2) and
|
||||
isRealRange(exp3)
|
||||
) and
|
||||
upperBound(exp1).maximum(upperBound(exp2)) - upperBound(exp1).minimum(upperBound(exp2)) < 16 and
|
||||
lowerBound(exp1).maximum(lowerBound(exp2)) - lowerBound(exp1).minimum(lowerBound(exp2)) < 16 and
|
||||
(
|
||||
upperBound(exp1).maximum(upperBound(exp3)) - upperBound(exp1).minimum(upperBound(exp3)) > 256 or
|
||||
lowerBound(exp1).maximum(lowerBound(exp2)) - lowerBound(exp1).minimum(lowerBound(exp2)) > 256
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if different values of the expression obtained from the parameters of the predicate can be obtained. */
|
||||
pragma[inline]
|
||||
predicate isDifferentResults(
|
||||
Expr exp1, Expr exp2, Expr exp3, BinaryBitwiseOperation op1, BinaryBitwiseOperation op2
|
||||
) {
|
||||
(
|
||||
isRealRange(exp1) and
|
||||
isRealRange(exp2) and
|
||||
isRealRange(exp3)
|
||||
) and
|
||||
exists(int i1, int i2, int i3 |
|
||||
i1 in [lowerBound(exp1).floor() .. upperBound(exp1).floor()] and
|
||||
i2 in [lowerBound(exp2).floor() .. upperBound(exp2).floor()] and
|
||||
i3 in [lowerBound(exp3).floor() .. upperBound(exp3).floor()] and
|
||||
(
|
||||
op1 instanceof BitwiseOrExpr and
|
||||
op2 instanceof BitwiseAndExpr and
|
||||
i1.bitOr(i2).bitAnd(i3) != i2.bitAnd(i3).bitOr(i1)
|
||||
or
|
||||
op1 instanceof BitwiseOrExpr and
|
||||
op2 instanceof BitwiseXorExpr and
|
||||
i1.bitOr(i2).bitXor(i3) != i2.bitXor(i3).bitOr(i1)
|
||||
or
|
||||
op1 instanceof BitwiseXorExpr and
|
||||
op2 instanceof BitwiseAndExpr and
|
||||
i1.bitXor(i2).bitAnd(i3) != i2.bitAnd(i3).bitXor(i1)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
from Expr exp, string msg
|
||||
where
|
||||
isLogicalOrAndExpr(exp) and
|
||||
msg = "Logical AND has a higher priority."
|
||||
or
|
||||
isLogicalOrandBitwise(exp) and
|
||||
msg = "Binary operations have higher priority."
|
||||
or
|
||||
// Looking for a situation where the equality of the sizes of the first operands
|
||||
// might indicate that the developer planned to perform an operation between them.
|
||||
// However, the absence of parentheses means that the rightmost operation will be performed initially.
|
||||
isBitwiseandBitwise(exp) and
|
||||
isDifferentSize(exp.(BinaryBitwiseOperation).getLeftOperand(),
|
||||
exp.(BinaryBitwiseOperation).getRightOperand().(BinaryBitwiseOperation).getLeftOperand(),
|
||||
exp.(BinaryBitwiseOperation).getRightOperand().(BinaryBitwiseOperation).getRightOperand()) and
|
||||
msg = "Expression ranges do not match operation precedence."
|
||||
or
|
||||
// Looking for a out those expressions that, as a result of identifying the priority with parentheses,
|
||||
// will give different values. As a consequence, this piece of code was supposed to find errors associated
|
||||
// with possible outcomes of operations.
|
||||
isBitwiseandBitwise(exp) and
|
||||
isDifferentResults(exp.(BinaryBitwiseOperation).getLeftOperand(),
|
||||
exp.(BinaryBitwiseOperation).getRightOperand().(BinaryBitwiseOperation).getLeftOperand(),
|
||||
exp.(BinaryBitwiseOperation).getRightOperand().(BinaryBitwiseOperation).getRightOperand(),
|
||||
exp.(BinaryBitwiseOperation),
|
||||
exp.(BinaryBitwiseOperation).getRightOperand().(BinaryBitwiseOperation)) and
|
||||
msg = "specify the priority with parentheses."
|
||||
select exp, msg
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
dependencies: {}
|
||||
compiled: false
|
||||
lockVersion: 1.0.0
|
||||
@@ -1,8 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.0.2
|
||||
dependencies:
|
||||
codeql/cpp-all: "*"
|
||||
codeql/suite-helpers: "*"
|
||||
name: codeql-cpp
|
||||
version: 0.0.0
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
suites: codeql-suites
|
||||
extractor: cpp
|
||||
defaultSuiteFile: codeql-suites/cpp-code-scanning.qls
|
||||
|
||||
@@ -58,11 +58,6 @@ class ElementBase extends @element {
|
||||
/** DEPRECATED: use `getAPrimaryQlClass` instead. */
|
||||
deprecated string getCanonicalQLClass() { result = this.getAPrimaryQlClass() }
|
||||
|
||||
/**
|
||||
* Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
|
||||
*/
|
||||
final string getPrimaryQlClasses() { result = concat(getAPrimaryQlClass(), ",") }
|
||||
|
||||
/**
|
||||
* Gets the name of a primary CodeQL class to which this element belongs.
|
||||
*
|
||||
@@ -272,16 +272,20 @@ class File extends Container, @file {
|
||||
* are compiled by a Microsoft compiler are detected by this predicate.
|
||||
*/
|
||||
predicate compiledAsMicrosoft() {
|
||||
exists(File f, Compilation c |
|
||||
c.getAFileCompiled() = f and
|
||||
exists(Compilation c |
|
||||
c.getAFileCompiled() = this and
|
||||
(
|
||||
c.getAnArgument() = "--microsoft" or
|
||||
c.getAnArgument()
|
||||
.toLowerCase()
|
||||
.replaceAll("\\", "/")
|
||||
.matches(["%/cl.exe", "%/clang-cl.exe"])
|
||||
) and
|
||||
f.getAnIncludedFile*() = this
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(File parent |
|
||||
parent.compiledAsMicrosoft() and
|
||||
parent.getAnIncludedFile() = this
|
||||
)
|
||||
}
|
||||
|
||||
@@ -354,11 +358,6 @@ class File extends Container, @file {
|
||||
string getShortName() { files(underlyingElement(this), _, result, _, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if any file was compiled by a Microsoft compiler.
|
||||
*/
|
||||
predicate anyFileCompiledAsMicrosoft() { any(File f).compiledAsMicrosoft() }
|
||||
|
||||
/**
|
||||
* A C/C++ header file, as determined (mainly) by file extension.
|
||||
*
|
||||
@@ -82,23 +82,9 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
/** Holds if this function is inline. */
|
||||
predicate isInline() { this.hasSpecifier("inline") }
|
||||
|
||||
/**
|
||||
* Holds if this function is virtual.
|
||||
*
|
||||
* Unlike `isDeclaredVirtual()`, `isVirtual()` holds even if the function
|
||||
* is not explicitly declared with the `virtual` specifier.
|
||||
*/
|
||||
/** Holds if this function is virtual. */
|
||||
predicate isVirtual() { this.hasSpecifier("virtual") }
|
||||
|
||||
/** Holds if this function is declared with the `virtual` specifier. */
|
||||
predicate isDeclaredVirtual() { this.hasSpecifier("declared_virtual") }
|
||||
|
||||
/** Holds if this function is declared with the `override` specifier. */
|
||||
predicate isOverride() { this.hasSpecifier("override") }
|
||||
|
||||
/** Holds if this function is declared with the `final` specifier. */
|
||||
predicate isFinal() { this.hasSpecifier("final") }
|
||||
|
||||
/**
|
||||
* Holds if this function is deleted.
|
||||
* This may be because it was explicitly deleted with an `= delete`
|
||||
@@ -151,20 +137,6 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
*/
|
||||
predicate isNaked() { getAnAttribute().hasName("naked") }
|
||||
|
||||
/**
|
||||
* Holds if this function has a trailing return type.
|
||||
*
|
||||
* Note that this is true whether or not deduction took place. For example,
|
||||
* this holds for both `e` and `f`, but not `g` or `h`:
|
||||
* ```
|
||||
* auto e() -> int { return 0; }
|
||||
* auto f() -> auto { return 0; }
|
||||
* auto g() { return 0; }
|
||||
* int h() { return 0; }
|
||||
* ```
|
||||
*/
|
||||
predicate hasTrailingReturnType() { this.hasSpecifier("has_trailing_return_type") }
|
||||
|
||||
/** Gets the return type of this function. */
|
||||
Type getType() { function_return_type(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
@@ -18,12 +18,6 @@ import semmle.code.cpp.controlflow.ControlFlowGraph
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
* But _not_ `4` in the following code:
|
||||
* ```
|
||||
* int myUninitializedVariable;
|
||||
* myUninitializedVariable = 4;
|
||||
* ```
|
||||
* Instead, this is an `Assignment`.
|
||||
*/
|
||||
class Initializer extends ControlFlowNode, @initialiser {
|
||||
override Location getLocation() { initialisers(underlyingElement(this), _, _, result) }
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user