mirror of
https://github.com/github/codeql.git
synced 2026-07-05 11:35:30 +02:00
Compare commits
1 Commits
codeql-cli
...
esbena-pat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22c77ebb87 |
@@ -1,27 +1,11 @@
|
|||||||
{
|
{ "provide": [ "ruby/.codeqlmanifest.json",
|
||||||
"provide": [
|
|
||||||
"*/ql/src/qlpack.yml",
|
"*/ql/src/qlpack.yml",
|
||||||
"*/ql/lib/qlpack.yml",
|
"*/ql/lib/qlpack.yml",
|
||||||
"*/ql/test/qlpack.yml",
|
"*/ql/test/qlpack.yml",
|
||||||
"*/ql/examples/qlpack.yml",
|
|
||||||
"*/ql/consistency-queries/qlpack.yml",
|
|
||||||
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
|
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
|
||||||
|
"*/ql/examples/qlpack.yml",
|
||||||
|
"*/upgrades/qlpack.yml",
|
||||||
"javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml",
|
"javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml",
|
||||||
"javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml",
|
|
||||||
"javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
|
"javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
|
||||||
"csharp/ql/campaigns/Solorigate/lib/qlpack.yml",
|
|
||||||
"csharp/ql/campaigns/Solorigate/src/qlpack.yml",
|
|
||||||
"csharp/ql/campaigns/Solorigate/test/qlpack.yml",
|
|
||||||
"misc/legacy-support/*/qlpack.yml",
|
"misc/legacy-support/*/qlpack.yml",
|
||||||
"misc/suite-helpers/qlpack.yml",
|
"misc/suite-helpers/qlpack.yml" ] }
|
||||||
"ruby/extractor-pack/codeql-extractor.yml",
|
|
||||||
"ql/extractor-pack/codeql-extractor.yml"
|
|
||||||
],
|
|
||||||
"versionPolicies": {
|
|
||||||
"default": {
|
|
||||||
"requireChangeNotes": true,
|
|
||||||
"committedPrereleaseSuffix": "dev",
|
|
||||||
"committedVersion": "nextPatchRelease"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -51,8 +51,3 @@
|
|||||||
|
|
||||||
java/ql/test/stubs/**/*.java linguist-generated=true
|
java/ql/test/stubs/**/*.java linguist-generated=true
|
||||||
java/ql/test/experimental/stubs/**/*.java linguist-generated=true
|
java/ql/test/experimental/stubs/**/*.java linguist-generated=true
|
||||||
|
|
||||||
# Generated test files - these are synced from the standard JavaScript libraries using
|
|
||||||
# `javascript/ql/experimental/adaptivethreatmodeling/test/update_endpoint_test_files.py`.
|
|
||||||
javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/**/*.js linguist-generated=true -merge
|
|
||||||
javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/**/*.ts linguist-generated=true -merge
|
|
||||||
|
|||||||
4
.github/actions/fetch-codeql/action.yml
vendored
4
.github/actions/fetch-codeql/action.yml
vendored
@@ -8,7 +8,7 @@ runs:
|
|||||||
run: |
|
run: |
|
||||||
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1)
|
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1)
|
||||||
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST"
|
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST"
|
||||||
unzip -q -d "${RUNNER_TEMP}" codeql-linux64.zip
|
unzip -q codeql-linux64.zip
|
||||||
echo "${RUNNER_TEMP}/codeql" >> "${GITHUB_PATH}"
|
echo "${{ github.workspace }}/codeql" >> $GITHUB_PATH
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
|||||||
3
.github/labeler.yml
vendored
3
.github/labeler.yml
vendored
@@ -26,6 +26,3 @@ documentation:
|
|||||||
- "**/*.qhelp"
|
- "**/*.qhelp"
|
||||||
- "**/*.md"
|
- "**/*.md"
|
||||||
- docs/**/*
|
- docs/**/*
|
||||||
|
|
||||||
"QL-for-QL":
|
|
||||||
- ql/**/*
|
|
||||||
1
.github/workflows/check-change-note.yml
vendored
1
.github/workflows/check-change-note.yml
vendored
@@ -7,7 +7,6 @@ on:
|
|||||||
- "*/ql/src/**/*.ql"
|
- "*/ql/src/**/*.ql"
|
||||||
- "*/ql/src/**/*.qll"
|
- "*/ql/src/**/*.qll"
|
||||||
- "!**/experimental/**"
|
- "!**/experimental/**"
|
||||||
- "!ql/**"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-change-note:
|
check-change-note:
|
||||||
|
|||||||
7
.github/workflows/codeql-analysis.yml
vendored
7
.github/workflows/codeql-analysis.yml
vendored
@@ -27,11 +27,6 @@ jobs:
|
|||||||
pull-requests: read
|
pull-requests: read
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup dotnet
|
|
||||||
uses: actions/setup-dotnet@v1
|
|
||||||
with:
|
|
||||||
dotnet-version: 6.0.101
|
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
@@ -56,7 +51,7 @@ jobs:
|
|||||||
# uses a compiled language
|
# uses a compiled language
|
||||||
|
|
||||||
- run: |
|
- run: |
|
||||||
dotnet build csharp /p:UseSharedCompilation=false
|
dotnet build csharp
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@main
|
uses: github/codeql-action/analyze@main
|
||||||
|
|||||||
43
.github/workflows/csv-coverage-metrics.yml
vendored
43
.github/workflows/csv-coverage-metrics.yml
vendored
@@ -1,43 +0,0 @@
|
|||||||
name: "Publish framework coverage as metrics"
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '5 0 * * *'
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
workflow_dispatch:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths:
|
|
||||||
- ".github/workflows/csv-coverage-metrics.yml"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Setup CodeQL
|
|
||||||
uses: ./.github/actions/fetch-codeql
|
|
||||||
- name: Create empty database
|
|
||||||
run: |
|
|
||||||
DATABASE="${{ runner.temp }}/java-database"
|
|
||||||
PROJECT="${{ runner.temp }}/java-project"
|
|
||||||
mkdir -p "$PROJECT/src/tmp/empty"
|
|
||||||
echo "class Empty {}" >> "$PROJECT/src/tmp/empty/Empty.java"
|
|
||||||
codeql database create "$DATABASE" --language=java --source-root="$PROJECT" --command 'javac src/tmp/empty/Empty.java'
|
|
||||||
- name: Capture coverage information
|
|
||||||
run: |
|
|
||||||
DATABASE="${{ runner.temp }}/java-database"
|
|
||||||
codeql database analyze --format=sarif-latest --output=metrics.sarif -- "$DATABASE" ./java/ql/src/Metrics/Summaries/FrameworkCoverage.ql
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: metrics.sarif
|
|
||||||
path: metrics.sarif
|
|
||||||
retention-days: 20
|
|
||||||
- name: Upload SARIF file
|
|
||||||
uses: github/codeql-action/upload-sarif@v1
|
|
||||||
with:
|
|
||||||
sarif_file: metrics.sarif
|
|
||||||
67
.github/workflows/js-ml-tests.yml
vendored
67
.github/workflows/js-ml-tests.yml
vendored
@@ -1,67 +0,0 @@
|
|||||||
name: JS ML-powered queries tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- "javascript/ql/experimental/adaptivethreatmodeling/**"
|
|
||||||
- .github/workflows/js-ml-tests.yml
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- "rc/*"
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- "javascript/ql/experimental/adaptivethreatmodeling/**"
|
|
||||||
- .github/workflows/js-ml-tests.yml
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: javascript/ql/experimental/adaptivethreatmodeling
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
qlformat:
|
|
||||||
name: Check QL formatting
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- uses: ./.github/actions/fetch-codeql
|
|
||||||
|
|
||||||
- name: Check QL formatting
|
|
||||||
run: |
|
|
||||||
find . "(" -name "*.ql" -or -name "*.qll" ")" -print0 | \
|
|
||||||
xargs -0 codeql query format --check-only
|
|
||||||
|
|
||||||
qlcompile:
|
|
||||||
name: Check QL compilation
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- uses: ./.github/actions/fetch-codeql
|
|
||||||
|
|
||||||
- name: Check QL compilation
|
|
||||||
run: |
|
|
||||||
codeql query compile \
|
|
||||||
--check-only \
|
|
||||||
--ram 5120 \
|
|
||||||
--additional-packs "${{ github.workspace }}" \
|
|
||||||
--threads=0 \
|
|
||||||
-- \
|
|
||||||
lib modelbuilding src
|
|
||||||
|
|
||||||
qltest:
|
|
||||||
name: Run QL tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- uses: ./.github/actions/fetch-codeql
|
|
||||||
|
|
||||||
- name: Run QL tests
|
|
||||||
run: |
|
|
||||||
codeql test run \
|
|
||||||
--threads=0 \
|
|
||||||
--ram 5120 \
|
|
||||||
--additional-packs "${{ github.workspace }}" \
|
|
||||||
-- \
|
|
||||||
test
|
|
||||||
103
.github/workflows/mad_modelDiff.yml
vendored
103
.github/workflows/mad_modelDiff.yml
vendored
@@ -1,103 +0,0 @@
|
|||||||
name: Models as Data - Diff
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
projects:
|
|
||||||
description: "The projects to generate models for"
|
|
||||||
required: true
|
|
||||||
default: '["netty/netty"]'
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths:
|
|
||||||
- "java/ql/src/utils/model-generator/**/*.*"
|
|
||||||
- ".github/workflows/mad_modelDiff.yml"
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
model-diff:
|
|
||||||
name: Model Difference
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.repository == 'github/codeql'
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
slug: ${{fromJson(github.event.inputs.projects || '["apache/commons-codec", "apache/commons-io", "apache/commons-beanutils", "apache/commons-logging", "apache/commons-fileupload", "apache/commons-lang", "apache/commons-validator", "apache/commons-csv", "apache/dubbo"]' )}}
|
|
||||||
steps:
|
|
||||||
- name: Clone github/codeql from PR
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
if: github.event.pull_request
|
|
||||||
with:
|
|
||||||
path: codeql-pr
|
|
||||||
- name: Clone github/codeql from main
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
path: codeql-main
|
|
||||||
ref: main
|
|
||||||
- uses: ./codeql-main/.github/actions/fetch-codeql
|
|
||||||
- name: Download database
|
|
||||||
env:
|
|
||||||
SLUG: ${{ matrix.slug }}
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
mkdir lib-dbs
|
|
||||||
SHORTNAME=${SLUG//[^a-zA-Z0-9_]/}
|
|
||||||
projectId=`curl -s https://lgtm.com/api/v1.0/projects/g/${SLUG} | jq .id`
|
|
||||||
curl -L "https://lgtm.com/api/v1.0/snapshots/$projectId/java" -o "$SHORTNAME.zip"
|
|
||||||
unzip -q -d "${SHORTNAME}-db" "${SHORTNAME}.zip"
|
|
||||||
mkdir "lib-dbs/$SHORTNAME/"
|
|
||||||
mv "${SHORTNAME}-db/"$(ls -1 "${SHORTNAME}"-db)/* "lib-dbs/${SHORTNAME}/"
|
|
||||||
- name: Generate Models (PR and main)
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
mkdir tmp-models
|
|
||||||
MODELS=`pwd`/tmp-models
|
|
||||||
DATABASES=`pwd`/lib-dbs
|
|
||||||
|
|
||||||
analyzeDatabaseWithCheckout() {
|
|
||||||
QL_VARIANT=$1
|
|
||||||
DATABASE=$2
|
|
||||||
cd codeql-$QL_VARIANT
|
|
||||||
SHORTNAME=`basename $DATABASE`
|
|
||||||
python java/ql/src/utils/model-generator/GenerateFlowModel.py $DATABASE $MODELS/${SHORTNAME}.qll
|
|
||||||
mv $MODELS/${SHORTNAME}.qll $MODELS/${SHORTNAME}Generated_${QL_VARIANT}.qll
|
|
||||||
cd ..
|
|
||||||
}
|
|
||||||
|
|
||||||
for d in $DATABASES/*/ ; do
|
|
||||||
ls -1 "$d"
|
|
||||||
|
|
||||||
analyzeDatabaseWithCheckout "main" $d
|
|
||||||
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]
|
|
||||||
then
|
|
||||||
analyzeDatabaseWithCheckout "pr" $d
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
- name: Install diff2html
|
|
||||||
if: github.event.pull_request
|
|
||||||
run: |
|
|
||||||
npm install -g diff2html-cli
|
|
||||||
- name: Generate Model Diff
|
|
||||||
if: github.event.pull_request
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
MODELS=`pwd`/tmp-models
|
|
||||||
ls -1 tmp-models/
|
|
||||||
for m in $MODELS/*_main.qll ; do
|
|
||||||
t="${m/main/"pr"}"
|
|
||||||
basename=`basename $m`
|
|
||||||
name="diff_${basename/_main.qll/""}"
|
|
||||||
(diff -w -u $m $t | diff2html -i stdin -F $MODELS/$name.html) || true
|
|
||||||
done
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: models
|
|
||||||
path: tmp-models/*.qll
|
|
||||||
retention-days: 20
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: diffs
|
|
||||||
path: tmp-models/*.html
|
|
||||||
retention-days: 20
|
|
||||||
62
.github/workflows/mad_regenerate-models.yml
vendored
62
.github/workflows/mad_regenerate-models.yml
vendored
@@ -1,62 +0,0 @@
|
|||||||
name: Regenerate framework models
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: "30 2 * * *"
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths:
|
|
||||||
- ".github/workflows/mad_regenerate-models.yml"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
regenerate-models:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
# placeholder required for each axis, excluded below, replaced by the actual combinations (see include)
|
|
||||||
slug: ["placeholder"]
|
|
||||||
ref: ["placeholder"]
|
|
||||||
include:
|
|
||||||
- slug: "apache/commons-io"
|
|
||||||
ref: "8985de8fe74f6622a419b37a6eed0dbc484dc128"
|
|
||||||
exclude:
|
|
||||||
- slug: "placeholder"
|
|
||||||
ref: "placeholder"
|
|
||||||
steps:
|
|
||||||
- name: Clone self (github/codeql)
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Setup CodeQL binaries
|
|
||||||
uses: ./.github/actions/fetch-codeql
|
|
||||||
- name: Clone repositories
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
path: repos/${{ matrix.ref }}
|
|
||||||
ref: ${{ matrix.ref }}
|
|
||||||
repository: ${{ matrix.slug }}
|
|
||||||
- name: Build database
|
|
||||||
env:
|
|
||||||
SLUG: ${{ matrix.slug }}
|
|
||||||
REF: ${{ matrix.ref }}
|
|
||||||
run: |
|
|
||||||
mkdir dbs
|
|
||||||
cd repos/${REF}
|
|
||||||
SHORTNAME=${SLUG//[^a-zA-Z0-9_]/}
|
|
||||||
codeql database create --language=java ../../dbs/${SHORTNAME}
|
|
||||||
- name: Regenerate models in-place
|
|
||||||
env:
|
|
||||||
SLUG: ${{ matrix.slug }}
|
|
||||||
run: |
|
|
||||||
SHORTNAME=${SLUG//[^a-zA-Z0-9_]/}
|
|
||||||
java/ql/src/utils/model-generator/RegenerateModels.py "${SLUG}" dbs/${SHORTNAME}
|
|
||||||
- name: Stage changes
|
|
||||||
run: |
|
|
||||||
find java -name "*.qll" -print0 | xargs -0 git add
|
|
||||||
git status
|
|
||||||
git diff --cached > models.patch
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: patch
|
|
||||||
path: models.patch
|
|
||||||
retention-days: 7
|
|
||||||
31
.github/workflows/post-pr-comment.yml
vendored
31
.github/workflows/post-pr-comment.yml
vendored
@@ -1,31 +0,0 @@
|
|||||||
name: Post pull-request comment
|
|
||||||
on:
|
|
||||||
workflow_run:
|
|
||||||
workflows: ["Query help preview"]
|
|
||||||
types:
|
|
||||||
- completed
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
post_comment:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Download artifact
|
|
||||||
run: gh run download "${WORKFLOW_RUN_ID}" --repo "${GITHUB_REPOSITORY}" --name "comment"
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }}
|
|
||||||
- run: |
|
|
||||||
PR="$(grep -o '^[0-9]\+$' pr.txt)"
|
|
||||||
PR_HEAD_SHA="$(gh api "/repos/${GITHUB_REPOSITORY}/pulls/${PR}" --jq .head.sha)"
|
|
||||||
# Check that the pull-request head SHA matches the head SHA of the workflow run
|
|
||||||
if [ "${WORKFLOW_RUN_HEAD_SHA}" != "${PR_HEAD_SHA}" ]; then
|
|
||||||
echo "PR head SHA ${PR_HEAD_SHA} does not match workflow_run event SHA ${WORKFLOW_RUN_HEAD_SHA}. Stopping." 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
gh pr comment "${PR}" --repo "${GITHUB_REPOSITORY}" -F comment.txt
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
WORKFLOW_RUN_HEAD_SHA: ${{ github.event.workflow_run.head_commit.id }}
|
|
||||||
52
.github/workflows/qhelp-pr-preview.yml
vendored
52
.github/workflows/qhelp-pr-preview.yml
vendored
@@ -1,13 +1,10 @@
|
|||||||
name: Query help preview
|
name: Query help preview
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- "rc/*"
|
- 'rc/*'
|
||||||
paths:
|
paths:
|
||||||
- "ruby/**/*.qhelp"
|
- "ruby/**/*.qhelp"
|
||||||
|
|
||||||
@@ -15,49 +12,28 @@ jobs:
|
|||||||
qhelp:
|
qhelp:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- run: echo "${{ github.event.number }}" > pr.txt
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: comment
|
|
||||||
path: pr.txt
|
|
||||||
retention-days: 1
|
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
persist-credentials: false
|
|
||||||
- uses: ./.github/actions/fetch-codeql
|
|
||||||
- name: Determine changed files
|
- name: Determine changed files
|
||||||
id: changes
|
id: changes
|
||||||
run: |
|
run: |
|
||||||
(git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.qhelp$' | grep -z -v '.inc.qhelp';
|
echo -n "::set-output name=qhelp_files::"
|
||||||
git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.inc.qhelp$' | xargs --null -rn1 basename | xargs --null -rn1 git grep -z -l) |
|
(git diff --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep .qhelp$ | grep -v .inc.qhelp;
|
||||||
grep -z '.qhelp$' | grep -z -v '^-' | sort -z -u > "${RUNNER_TEMP}/paths.txt"
|
git diff --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep .inc.qhelp$ | xargs -d '\n' -rn1 basename | xargs -d '\n' -rn1 git grep -l) |
|
||||||
|
sort -u | xargs -d '\n' -n1 printf "'%s' "
|
||||||
|
|
||||||
|
- uses: ./.github/actions/fetch-codeql
|
||||||
|
|
||||||
- name: QHelp preview
|
- name: QHelp preview
|
||||||
|
if: ${{ steps.changes.outputs.qhelp_files }}
|
||||||
run: |
|
run: |
|
||||||
EXIT_CODE=0
|
( echo "QHelp previews:";
|
||||||
echo "QHelp previews:" > comment.txt
|
for path in ${{ steps.changes.outputs.qhelp_files }} ; do
|
||||||
while read -r -d $'\0' path; do
|
|
||||||
if [ ! -f "${path}" ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "<details> <summary>${path}</summary>"
|
echo "<details> <summary>${path}</summary>"
|
||||||
echo
|
echo
|
||||||
codeql generate query-help --format=markdown -- "./${path}" 2> errors.txt || EXIT_CODE="$?"
|
codeql generate query-help --format=markdown ${path}
|
||||||
if [ -s errors.txt ]; then
|
|
||||||
echo "# errors/warnings:"
|
|
||||||
echo '```'
|
|
||||||
cat errors.txt
|
|
||||||
cat errors.txt 1>&2
|
|
||||||
echo '```'
|
|
||||||
fi
|
|
||||||
echo "</details>"
|
echo "</details>"
|
||||||
done < "${RUNNER_TEMP}/paths.txt" >> comment.txt
|
done) | gh pr comment "${{ github.event.pull_request.number }}" -F -
|
||||||
exit "${EXIT_CODE}"
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
- if: always()
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: comment
|
|
||||||
path: comment.txt
|
|
||||||
retention-days: 1
|
|
||||||
|
|||||||
199
.github/workflows/ql-for-ql-build.yml
vendored
199
.github/workflows/ql-for-ql-build.yml
vendored
@@ -1,199 +0,0 @@
|
|||||||
name: Run QL for QL
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
queries:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Find codeql
|
|
||||||
id: find-codeql
|
|
||||||
uses: github/codeql-action/init@erik-krogh/ql
|
|
||||||
with:
|
|
||||||
languages: javascript # does not matter
|
|
||||||
- name: Get CodeQL version
|
|
||||||
id: get-codeql-version
|
|
||||||
run: |
|
|
||||||
echo "::set-output name=version::$("${CODEQL}" --version | head -n 1 | rev | cut -d " " -f 1 | rev)"
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
|
||||||
- name: Cache queries
|
|
||||||
id: cache-queries
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: ${{ runner.temp }}/query-pack.zip
|
|
||||||
key: queries-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}
|
|
||||||
- name: Build query pack
|
|
||||||
if: steps.cache-queries.outputs.cache-hit != 'true'
|
|
||||||
run: |
|
|
||||||
cd ql/ql/src
|
|
||||||
"${CODEQL}" pack create
|
|
||||||
cd .codeql/pack/codeql/ql-all/0.0.0
|
|
||||||
zip "${PACKZIP}" -r .
|
|
||||||
env:
|
|
||||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
|
||||||
PACKZIP: ${{ runner.temp }}/query-pack.zip
|
|
||||||
- name: Upload query pack
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: query-pack-zip
|
|
||||||
path: ${{ runner.temp }}/query-pack.zip
|
|
||||||
|
|
||||||
extractors:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Cache entire extractor
|
|
||||||
id: cache-extractor
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
ql/target/release/ql-autobuilder
|
|
||||||
ql/target/release/ql-autobuilder.exe
|
|
||||||
ql/target/release/ql-extractor
|
|
||||||
ql/target/release/ql-extractor.exe
|
|
||||||
key: ${{ runner.os }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('ql/**/*.rs') }}
|
|
||||||
- name: Cache cargo
|
|
||||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
~/.cargo/registry
|
|
||||||
~/.cargo/git
|
|
||||||
ql/target
|
|
||||||
key: ${{ runner.os }}-rust-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
|
|
||||||
- name: Check formatting
|
|
||||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
|
||||||
run: cd ql; cargo fmt --all -- --check
|
|
||||||
- name: Build
|
|
||||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
|
||||||
run: cd ql; cargo build --verbose
|
|
||||||
- name: Run tests
|
|
||||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
|
||||||
run: cd ql; cargo test --verbose
|
|
||||||
- name: Release build
|
|
||||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
|
||||||
run: cd ql; cargo build --release
|
|
||||||
- name: Generate dbscheme
|
|
||||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
|
||||||
run: ql/target/release/ql-generator --dbscheme ql/ql/src/ql.dbscheme --library ql/ql/src/codeql_ql/ast/internal/TreeSitter.qll
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: extractor-ubuntu-latest
|
|
||||||
path: |
|
|
||||||
ql/target/release/ql-autobuilder
|
|
||||||
ql/target/release/ql-autobuilder.exe
|
|
||||||
ql/target/release/ql-extractor
|
|
||||||
ql/target/release/ql-extractor.exe
|
|
||||||
retention-days: 1
|
|
||||||
package:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
needs:
|
|
||||||
- extractors
|
|
||||||
- queries
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: query-pack-zip
|
|
||||||
path: query-pack-zip
|
|
||||||
- uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: extractor-ubuntu-latest
|
|
||||||
path: linux64
|
|
||||||
- run: |
|
|
||||||
unzip query-pack-zip/*.zip -d pack
|
|
||||||
cp -r ql/codeql-extractor.yml ql/tools ql/ql/src/ql.dbscheme.stats pack/
|
|
||||||
mkdir -p pack/tools/linux64
|
|
||||||
if [[ -f linux64/ql-autobuilder ]]; then
|
|
||||||
cp linux64/ql-autobuilder pack/tools/linux64/autobuilder
|
|
||||||
chmod +x pack/tools/linux64/autobuilder
|
|
||||||
fi
|
|
||||||
if [[ -f linux64/ql-extractor ]]; then
|
|
||||||
cp linux64/ql-extractor pack/tools/linux64/extractor
|
|
||||||
chmod +x pack/tools/linux64/extractor
|
|
||||||
fi
|
|
||||||
cd pack
|
|
||||||
zip -rq ../codeql-ql.zip .
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: codeql-ql-pack
|
|
||||||
path: codeql-ql.zip
|
|
||||||
retention-days: 1
|
|
||||||
analyze:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
folder: [cpp, csharp, java, javascript, python, ql, ruby]
|
|
||||||
|
|
||||||
needs:
|
|
||||||
- package
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Download pack
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: codeql-ql-pack
|
|
||||||
path: ${{ runner.temp }}/codeql-ql-pack-artifact
|
|
||||||
|
|
||||||
- name: Prepare pack
|
|
||||||
run: |
|
|
||||||
unzip "${PACK_ARTIFACT}/*.zip" -d "${PACK}"
|
|
||||||
env:
|
|
||||||
PACK_ARTIFACT: ${{ runner.temp }}/codeql-ql-pack-artifact
|
|
||||||
PACK: ${{ runner.temp }}/pack
|
|
||||||
- name: Hack codeql-action options
|
|
||||||
run: |
|
|
||||||
JSON=$(jq -nc --arg pack "${PACK}" '.resolve.queries=["--search-path", $pack] | .resolve.extractor=["--search-path", $pack] | .database.init=["--search-path", $pack]')
|
|
||||||
echo "CODEQL_ACTION_EXTRA_OPTIONS=${JSON}" >> ${GITHUB_ENV}
|
|
||||||
env:
|
|
||||||
PACK: ${{ runner.temp }}/pack
|
|
||||||
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Create CodeQL config file
|
|
||||||
run: |
|
|
||||||
echo "paths:" > ${CONF}
|
|
||||||
echo " - ${FOLDER}" >> ${CONF}
|
|
||||||
echo "paths-ignore:" >> ${CONF}
|
|
||||||
echo " - ql/ql/test" >> ${CONF}
|
|
||||||
echo "Config file: "
|
|
||||||
cat ${CONF}
|
|
||||||
env:
|
|
||||||
CONF: ./ql-for-ql-config.yml
|
|
||||||
FOLDER: ${{ matrix.folder }}
|
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@erik-krogh/ql
|
|
||||||
with:
|
|
||||||
languages: ql
|
|
||||||
db-location: ${{ runner.temp }}/db
|
|
||||||
config-file: ./ql-for-ql-config.yml
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@erik-krogh/ql
|
|
||||||
with:
|
|
||||||
category: "ql-for-ql-${{ matrix.folder }}"
|
|
||||||
- name: Copy sarif file to CWD
|
|
||||||
run: cp ../results/ql.sarif ./${{ matrix.folder }}.sarif
|
|
||||||
- name: Sarif as artifact
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.folder }}.sarif
|
|
||||||
path: ${{ matrix.folder }}.sarif
|
|
||||||
|
|
||||||
84
.github/workflows/ql-for-ql-dataset_measure.yml
vendored
84
.github/workflows/ql-for-ql-dataset_measure.yml
vendored
@@ -1,84 +0,0 @@
|
|||||||
name: Collect database stats for QL for QL
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
paths:
|
|
||||||
- ql/ql/src/ql.dbscheme
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
paths:
|
|
||||||
- ql/ql/src/ql.dbscheme
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
measure:
|
|
||||||
env:
|
|
||||||
CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
repo:
|
|
||||||
- github/codeql
|
|
||||||
- github/codeql-go
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Find codeql
|
|
||||||
id: find-codeql
|
|
||||||
uses: github/codeql-action/init@erik-krogh/ql
|
|
||||||
with:
|
|
||||||
languages: javascript # does not matter
|
|
||||||
- uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
~/.cargo/registry
|
|
||||||
~/.cargo/git
|
|
||||||
ql/target
|
|
||||||
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
|
|
||||||
- name: Build Extractor
|
|
||||||
run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./create-extractor-pack.sh
|
|
||||||
env:
|
|
||||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
|
||||||
- name: Checkout ${{ matrix.repo }}
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
repository: ${{ matrix.repo }}
|
|
||||||
path: ${{ github.workspace }}/repo
|
|
||||||
- name: Create database
|
|
||||||
run: |
|
|
||||||
"${CODEQL}" database create \
|
|
||||||
--search-path "ql/extractor-pack" \
|
|
||||||
--threads 4 \
|
|
||||||
--language ql --source-root "${{ github.workspace }}/repo" \
|
|
||||||
"${{ runner.temp }}/database"
|
|
||||||
env:
|
|
||||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
|
||||||
- name: Measure database
|
|
||||||
run: |
|
|
||||||
mkdir -p "stats/${{ matrix.repo }}"
|
|
||||||
"${CODEQL}" dataset measure --threads 4 --output "stats/${{ matrix.repo }}/stats.xml" "${{ runner.temp }}/database/db-ql"
|
|
||||||
env:
|
|
||||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: measurements
|
|
||||||
path: stats
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
merge:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: measure
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: measurements
|
|
||||||
path: stats
|
|
||||||
- run: |
|
|
||||||
python -m pip install --user lxml
|
|
||||||
find stats -name 'stats.xml' -print0 | sort -z | xargs -0 python ql/scripts/merge_stats.py --output ql/ql/src/ql.dbscheme.stats --normalise ql_tokeninfo
|
|
||||||
- uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: ql.dbscheme.stats
|
|
||||||
path: ql/ql/src/ql.dbscheme.stats
|
|
||||||
52
.github/workflows/ql-for-ql-tests.yml
vendored
52
.github/workflows/ql-for-ql-tests.yml
vendored
@@ -1,52 +0,0 @@
|
|||||||
name: Run QL for QL Tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
paths:
|
|
||||||
- "ql/**"
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
paths:
|
|
||||||
- "ql/**"
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
qltest:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Find codeql
|
|
||||||
id: find-codeql
|
|
||||||
uses: github/codeql-action/init@erik-krogh/ql
|
|
||||||
with:
|
|
||||||
languages: javascript # does not matter
|
|
||||||
- uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
~/.cargo/registry
|
|
||||||
~/.cargo/git
|
|
||||||
ql/target
|
|
||||||
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
|
|
||||||
- name: Build extractor
|
|
||||||
run: |
|
|
||||||
cd ql;
|
|
||||||
codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }});
|
|
||||||
env "PATH=$PATH:$codeqlpath" ./create-extractor-pack.sh
|
|
||||||
- name: Run QL tests
|
|
||||||
run: |
|
|
||||||
"${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ql/extractor-pack" --consistency-queries ql/ql/consistency-queries ql/ql/test
|
|
||||||
env:
|
|
||||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
|
||||||
- name: Check QL formatting
|
|
||||||
run: |
|
|
||||||
find ql/ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 "${CODEQL}" query format --check-only
|
|
||||||
env:
|
|
||||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
|
||||||
- name: Check QL compilation
|
|
||||||
run: |
|
|
||||||
"${CODEQL}" query compile --check-only --threads=4 --warnings=error --search-path "${{ github.workspace }}/ql/extractor-pack" "ql/ql/src" "ql/ql/examples"
|
|
||||||
env:
|
|
||||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
|
||||||
22
.github/workflows/ruby-build.yml
vendored
22
.github/workflows/ruby-build.yml
vendored
@@ -3,18 +3,16 @@ name: "Ruby: Build"
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- "ruby/**"
|
- 'ruby/**'
|
||||||
- .github/workflows/ruby-build.yml
|
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- "rc/*"
|
- 'rc/*'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- "ruby/**"
|
- 'ruby/**'
|
||||||
- .github/workflows/ruby-build.yml
|
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- "rc/*"
|
- 'rc/*'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
tag:
|
tag:
|
||||||
@@ -50,7 +48,7 @@ jobs:
|
|||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
~/.cargo/git
|
~/.cargo/git
|
||||||
ruby/target
|
ruby/target
|
||||||
key: ${{ runner.os }}-ruby-rust-cargo-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }}
|
key: ${{ runner.os }}-rust-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
- name: Check formatting
|
- name: Check formatting
|
||||||
run: cargo fmt --all -- --check
|
run: cargo fmt --all -- --check
|
||||||
- name: Build
|
- name: Build
|
||||||
@@ -102,6 +100,16 @@ jobs:
|
|||||||
PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*)
|
PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*)
|
||||||
codeql/codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
|
codeql/codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
|
||||||
(cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;)
|
(cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;)
|
||||||
|
- name: Compile with previous CodeQL versions
|
||||||
|
run: |
|
||||||
|
for version in $(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | tail -3 | head -2); do
|
||||||
|
rm -f codeql-linux64.zip
|
||||||
|
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$version"
|
||||||
|
rm -rf codeql; unzip -q codeql-linux64.zip
|
||||||
|
codeql/codeql query compile target/packs/*
|
||||||
|
done
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: codeql-ruby-queries
|
name: codeql-ruby-queries
|
||||||
|
|||||||
10
.github/workflows/ruby-dataset-measure.yml
vendored
10
.github/workflows/ruby-dataset-measure.yml
vendored
@@ -4,17 +4,15 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- "rc/*"
|
- 'rc/*'
|
||||||
paths:
|
paths:
|
||||||
- ruby/ql/lib/ruby.dbscheme
|
- ruby/ql/lib/ruby.dbscheme
|
||||||
- .github/workflows/ruby-dataset-measure.yml
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- "rc/*"
|
- 'rc/*'
|
||||||
paths:
|
paths:
|
||||||
- ruby/ql/lib/ruby.dbscheme
|
- ruby/ql/lib/ruby.dbscheme
|
||||||
- .github/workflows/ruby-dataset-measure.yml
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -24,7 +22,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
repo: [rails/rails, discourse/discourse, spree/spree, ruby/ruby]
|
repo: [rails/rails, discourse/discourse, spree/spree]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -41,7 +39,7 @@ jobs:
|
|||||||
- name: Create database
|
- name: Create database
|
||||||
run: |
|
run: |
|
||||||
codeql database create \
|
codeql database create \
|
||||||
--search-path "${{ github.workspace }}/ruby/extractor-pack" \
|
--search-path "${{ github.workspace }}/ruby" \
|
||||||
--threads 4 \
|
--threads 4 \
|
||||||
--language ruby --source-root "${{ github.workspace }}/repo" \
|
--language ruby --source-root "${{ github.workspace }}/repo" \
|
||||||
"${{ runner.temp }}/database"
|
"${{ runner.temp }}/database"
|
||||||
|
|||||||
64
.github/workflows/ruby-qltest.yml
vendored
64
.github/workflows/ruby-qltest.yml
vendored
@@ -3,18 +3,16 @@ name: "Ruby: Run QL Tests"
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- "ruby/**"
|
- 'ruby/**'
|
||||||
- .github/workflows/ruby-qltest.yml
|
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- "rc/*"
|
- 'rc/*'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- "ruby/**"
|
- 'ruby/**'
|
||||||
- .github/workflows/ruby-qltest.yml
|
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- "rc/*"
|
- 'rc/*'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
@@ -24,53 +22,27 @@ defaults:
|
|||||||
working-directory: ruby
|
working-directory: ruby
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
qlformat:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: ./.github/actions/fetch-codeql
|
|
||||||
- name: Check QL formatting
|
|
||||||
run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
|
|
||||||
qlcompile:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: ./.github/actions/fetch-codeql
|
|
||||||
- name: Check QL compilation
|
|
||||||
run: |
|
|
||||||
codeql query compile --check-only --threads=0 --ram 5000 --warnings=error "ql/src" "ql/examples"
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
qlupgrade:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: ./.github/actions/fetch-codeql
|
|
||||||
- name: Check DB upgrade scripts
|
|
||||||
run: |
|
|
||||||
echo >empty.trap
|
|
||||||
codeql dataset import -S ql/lib/upgrades/initial/ruby.dbscheme testdb empty.trap
|
|
||||||
codeql dataset upgrade testdb --additional-packs ql/lib
|
|
||||||
diff -q testdb/ruby.dbscheme ql/lib/ruby.dbscheme
|
|
||||||
- name: Check DB downgrade scripts
|
|
||||||
run: |
|
|
||||||
echo >empty.trap
|
|
||||||
rm -rf testdb; codeql dataset import -S ql/lib/ruby.dbscheme testdb empty.trap
|
|
||||||
codeql resolve upgrades --format=lines --allow-downgrades --additional-packs downgrades \
|
|
||||||
--dbscheme=ql/lib/ruby.dbscheme --target-dbscheme=downgrades/initial/ruby.dbscheme |
|
|
||||||
xargs codeql execute upgrades testdb
|
|
||||||
diff -q testdb/ruby.dbscheme downgrades/initial/ruby.dbscheme
|
|
||||||
qltest:
|
qltest:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
slice: ["1/2", "2/2"]
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/fetch-codeql
|
- uses: ./.github/actions/fetch-codeql
|
||||||
- uses: ./ruby/actions/create-extractor-pack
|
- uses: ./ruby/actions/create-extractor-pack
|
||||||
- name: Run QL tests
|
- name: Run QL tests
|
||||||
run: |
|
run: |
|
||||||
codeql test run --threads=0 --ram 5000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test
|
codeql test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ruby" --additional-packs "${{ github.workspace }}" --consistency-queries ql/consistency-queries ql/test
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
- name: Check QL formatting
|
||||||
|
run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
|
||||||
|
- name: Check QL compilation
|
||||||
|
run: |
|
||||||
|
codeql query compile --check-only --threads=4 --warnings=error --search-path "${{ github.workspace }}/ruby" --additional-packs "${{ github.workspace }}" "ql/src" "ql/examples"
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
- name: Check DB upgrade scripts
|
||||||
|
run: |
|
||||||
|
echo >empty.trap
|
||||||
|
codeql dataset import -S ql/lib/upgrades/initial/ruby.dbscheme testdb empty.trap
|
||||||
|
codeql dataset upgrade testdb --additional-packs ql/lib/upgrades
|
||||||
|
diff -q testdb/ruby.dbscheme ql/lib/ruby.dbscheme
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -27,6 +27,3 @@ csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
|
|||||||
|
|
||||||
# Avoid committing cached package components
|
# Avoid committing cached package components
|
||||||
.codeql
|
.codeql
|
||||||
|
|
||||||
# Compiled class file
|
|
||||||
*.class
|
|
||||||
@@ -13,9 +13,6 @@
|
|||||||
/python/**/experimental/**/* @github/codeql-python @xcorail
|
/python/**/experimental/**/* @github/codeql-python @xcorail
|
||||||
/ruby/**/experimental/**/* @github/codeql-ruby @xcorail
|
/ruby/**/experimental/**/* @github/codeql-ruby @xcorail
|
||||||
|
|
||||||
# ML-powered queries
|
|
||||||
/javascript/ql/experimental/adaptivethreatmodeling/ @github/codeql-ml-powered-queries-reviewers
|
|
||||||
|
|
||||||
# Notify members of codeql-go about PRs to the shared data-flow library files
|
# Notify members of codeql-go about PRs to the shared data-flow library files
|
||||||
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @github/codeql-java @github/codeql-go
|
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @github/codeql-java @github/codeql-go
|
||||||
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @github/codeql-java @github/codeql-go
|
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @github/codeql-java @github/codeql-go
|
||||||
@@ -28,6 +25,3 @@
|
|||||||
/docs/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
|
/docs/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
|
||||||
/docs/ql-language-reference/ @github/codeql-frontend-reviewers
|
/docs/ql-language-reference/ @github/codeql-frontend-reviewers
|
||||||
/docs/query-*-style-guide.md @github/codeql-analysis-reviewers
|
/docs/query-*-style-guide.md @github/codeql-analysis-reviewers
|
||||||
|
|
||||||
# QL for QL reviewers
|
|
||||||
/ql/ @github/codeql-ql-for-ql-reviewers
|
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ We welcome contributions to our CodeQL libraries and queries. Got an idea for a
|
|||||||
|
|
||||||
There is lots of useful documentation to help you write queries, ranging from information about query file structure to tutorials for specific target languages. For more information on the documentation available, see [CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com).
|
There is lots of useful documentation to help you write queries, ranging from information about query file structure to tutorials for specific target languages. For more information on the documentation available, see [CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com).
|
||||||
|
|
||||||
## Change notes
|
|
||||||
|
|
||||||
Any nontrivial user-visible change to a query pack or library pack should have a change note. For details on how to add a change note for your change, see [this guide](docs/change-notes.md).
|
|
||||||
|
|
||||||
## Submitting a new experimental query
|
## Submitting a new experimental query
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# CodeQL
|
# CodeQL
|
||||||
|
|
||||||
This open source repository contains the standard CodeQL libraries and queries that power [GitHub Advanced Security](https://github.com/features/security/code) and the other application security products that [GitHub](https://github.com/features/security/) makes available to its customers worldwide. For the queries, libraries, and extractor that power Go analysis, visit the [CodeQL for Go repository](https://github.com/github/codeql-go).
|
This open source repository contains the standard CodeQL libraries and queries that power [LGTM](https://lgtm.com) and the other CodeQL products that [GitHub](https://github.com) makes available to its customers worldwide. For the queries, libraries, and extractor that power Go analysis, visit the [CodeQL for Go repository](https://github.com/github/codeql-go).
|
||||||
|
|
||||||
## How do I learn CodeQL and run queries?
|
## How do I learn CodeQL and run queries?
|
||||||
|
|
||||||
There is [extensive documentation](https://codeql.github.com/docs/) on getting started with writing CodeQL.
|
There is [extensive documentation](https://codeql.github.com/docs/) on getting started with writing CodeQL.
|
||||||
You can use the [CodeQL for Visual Studio Code](https://codeql.github.com/docs/codeql-for-visual-studio-code/) extension or the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com (Semmle Legacy product) to try out your queries on any open source project that's currently being analyzed.
|
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://codeql.github.com/docs/codeql-for-visual-studio-code/) extension to try out your queries on any open source project that's currently being analyzed.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ We welcome contributions to our standard library and standard checks. Do you hav
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
The code in this repository is licensed under the [MIT License](LICENSE) by [GitHub](https://github.com). The use of CodeQL on open source code is licensed under specific [Terms & Conditions](https://securitylab.github.com/tools/codeql/license/) UNLESS you have a commercial license in place. If you'd like to use CodeQL with a commercial codebase, please [contact us](https://github.com/enterprise/contact) for further help.
|
The code in this repository is licensed under the [MIT License](LICENSE) by [GitHub](https://github.com).
|
||||||
|
|
||||||
## Visual Studio Code integration
|
## Visual Studio Code integration
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.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/DataFlowImpl6.qll",
|
||||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll",
|
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll",
|
||||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll",
|
|
||||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.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/DataFlowImpl2.qll",
|
||||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll",
|
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll",
|
||||||
@@ -450,27 +449,19 @@
|
|||||||
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/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/csharp/dataflow/internal/basessa/SsaImplCommon.qll",
|
||||||
"csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll",
|
"csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll",
|
||||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImplCommon.qll",
|
"ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImplCommon.qll"
|
||||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll"
|
|
||||||
],
|
],
|
||||||
"CryptoAlgorithms Python/JS/Ruby": [
|
"CryptoAlgorithms Python/JS": [
|
||||||
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",
|
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",
|
||||||
"python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll",
|
"python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll"
|
||||||
"ruby/ql/lib/codeql/ruby/security/CryptoAlgorithms.qll"
|
|
||||||
],
|
|
||||||
"CryptoAlgorithmNames Python/JS/Ruby": [
|
|
||||||
"javascript/ql/lib/semmle/javascript/security/internal/CryptoAlgorithmNames.qll",
|
|
||||||
"python/ql/lib/semmle/python/concepts/internal/CryptoAlgorithmNames.qll",
|
|
||||||
"ruby/ql/lib/codeql/ruby/security/internal/CryptoAlgorithmNames.qll"
|
|
||||||
],
|
],
|
||||||
"SensitiveDataHeuristics Python/JS": [
|
"SensitiveDataHeuristics Python/JS": [
|
||||||
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
|
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
|
||||||
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll"
|
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll"
|
||||||
],
|
],
|
||||||
"ReDoS Util Python/JS/Ruby": [
|
"ReDoS Util Python/JS": [
|
||||||
"javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll",
|
"javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll",
|
||||||
"python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll",
|
"python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll"
|
||||||
"ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll"
|
|
||||||
],
|
],
|
||||||
"ReDoS Exponential Python/JS": [
|
"ReDoS Exponential Python/JS": [
|
||||||
"javascript/ql/lib/semmle/javascript/security/performance/ExponentialBackTracking.qll",
|
"javascript/ql/lib/semmle/javascript/security/performance/ExponentialBackTracking.qll",
|
||||||
@@ -479,12 +470,7 @@
|
|||||||
"ReDoS Polynomial Python/JS": [
|
"ReDoS Polynomial Python/JS": [
|
||||||
"javascript/ql/lib/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
|
"javascript/ql/lib/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
|
||||||
"python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll",
|
"python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll",
|
||||||
"ruby/ql/lib/codeql/ruby/security/performance/SuperlinearBackTracking.qll"
|
"ruby/ql/lib/codeql/ruby/regexp/SuperlinearBackTracking.qll"
|
||||||
],
|
|
||||||
"BadTagFilterQuery Python/JS/Ruby": [
|
|
||||||
"javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll",
|
|
||||||
"python/ql/lib/semmle/python/security/BadTagFilterQuery.qll",
|
|
||||||
"ruby/ql/lib/codeql/ruby/security/BadTagFilterQuery.qll"
|
|
||||||
],
|
],
|
||||||
"CFG": [
|
"CFG": [
|
||||||
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
|
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<AssemblyName>Semmle.Autobuild.Cpp</AssemblyName>
|
<AssemblyName>Semmle.Autobuild.Cpp</AssemblyName>
|
||||||
<RootNamespace>Semmle.Autobuild.Cpp</RootNamespace>
|
<RootNamespace>Semmle.Autobuild.Cpp</RootNamespace>
|
||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Build" Version="16.11.0" />
|
<PackageReference Include="Microsoft.Build" Version="16.9.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
## 0.0.4
|
lgtm,codescanning
|
||||||
|
|
||||||
### New Features
|
|
||||||
|
|
||||||
* The QL library `semmle.code.cpp.commons.Exclusions` now contains a predicate
|
* The QL library `semmle.code.cpp.commons.Exclusions` now contains a predicate
|
||||||
`isFromSystemMacroDefinition` for identifying code that originates from a
|
`isFromSystemMacroDefinition` for identifying code that originates from a
|
||||||
macro outside the project being analyzed.
|
macro outside the project being analyzed.
|
||||||
@@ -5,8 +5,6 @@
|
|||||||
@name Badly bounded write (CWE-120)
|
@name Badly bounded write (CWE-120)
|
||||||
+ semmlecode-cpp-queries/Security/CWE/CWE-120/OverrunWrite.ql: /CWE/CWE-120
|
+ semmlecode-cpp-queries/Security/CWE/CWE-120/OverrunWrite.ql: /CWE/CWE-120
|
||||||
@name Potentially overrunning write (CWE-120)
|
@name Potentially overrunning write (CWE-120)
|
||||||
+ semmlecode-cpp-queries/Security/CWE/CWE-120/VeryLikelyOverrunWrite.ql: /CWE/CWE-120
|
|
||||||
@name Likely overrunning write
|
|
||||||
+ semmlecode-cpp-queries/Security/CWE/CWE-120/OverrunWriteFloat.ql: /CWE/CWE-120
|
+ semmlecode-cpp-queries/Security/CWE/CWE-120/OverrunWriteFloat.ql: /CWE/CWE-120
|
||||||
@name Potentially overrunning write with float to string conversion (CWE-120)
|
@name Potentially overrunning write with float to string conversion (CWE-120)
|
||||||
+ semmlecode-cpp-queries/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql: /CWE/CWE-120
|
+ semmlecode-cpp-queries/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql: /CWE/CWE-120
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
lgtm,codescanning
|
|
||||||
* The "Cleartext transmission of sensitive information" (`cpp/cleartext-transmission`) query has been improved, reducing the number of false positive results when encryption is present.
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
name: codeql/cpp-examples
|
name: codeql/cpp-examples
|
||||||
groups:
|
version: 0.0.2
|
||||||
- cpp
|
|
||||||
- examples
|
|
||||||
dependencies:
|
dependencies:
|
||||||
codeql/cpp-all: "*"
|
codeql/cpp-all: "*"
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
## 0.0.9
|
|
||||||
|
|
||||||
## 0.0.8
|
|
||||||
|
|
||||||
### Deprecated APIs
|
|
||||||
|
|
||||||
* The `codeql/cpp-upgrades` CodeQL pack has been removed. All upgrades scripts have been merged into the `codeql/cpp-all` CodeQL pack.
|
|
||||||
|
|
||||||
### Minor Analysis Improvements
|
|
||||||
|
|
||||||
* `FormatLiteral::getMaxConvertedLength` now uses range analysis to provide a
|
|
||||||
more accurate length for integers formatted with `%x`
|
|
||||||
|
|
||||||
## 0.0.7
|
|
||||||
|
|
||||||
## 0.0.6
|
|
||||||
|
|
||||||
## 0.0.5
|
|
||||||
|
|
||||||
## 0.0.4
|
|
||||||
|
|
||||||
### New Features
|
|
||||||
|
|
||||||
* The QL library `semmle.code.cpp.commons.Exclusions` now contains a predicate
|
|
||||||
`isFromSystemMacroDefinition` for identifying code that originates from a
|
|
||||||
macro outside the project being analyzed.
|
|
||||||
@@ -73,7 +73,7 @@ class Options extends string {
|
|||||||
* __assume(0);
|
* __assume(0);
|
||||||
* ```
|
* ```
|
||||||
* (note that in this case if the hint is wrong and the expression is reached at
|
* (note that in this case if the hint is wrong and the expression is reached at
|
||||||
* runtime, the program's behavior is undefined)
|
* runtime, the program's behaviour is undefined)
|
||||||
*/
|
*/
|
||||||
predicate exprExits(Expr e) {
|
predicate exprExits(Expr e) {
|
||||||
e.(AssumeExpr).getChild(0).(CompileTimeConstantInt).getIntValue() = 0 or
|
e.(AssumeExpr).getChild(0).(CompileTimeConstantInt).getIntValue() = 0 or
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class CustomOptions extends Options {
|
|||||||
* __assume(0);
|
* __assume(0);
|
||||||
* ```
|
* ```
|
||||||
* (note that in this case if the hint is wrong and the expression is reached at
|
* (note that in this case if the hint is wrong and the expression is reached at
|
||||||
* runtime, the program's behavior is undefined)
|
* runtime, the program's behaviour is undefined)
|
||||||
*/
|
*/
|
||||||
override predicate exprExits(Expr e) { Options.super.exprExits(e) }
|
override predicate exprExits(Expr e) { Options.super.exprExits(e) }
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
## 0.0.5
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
## 0.0.6
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
## 0.0.7
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
## 0.0.8
|
|
||||||
|
|
||||||
### Deprecated APIs
|
|
||||||
|
|
||||||
* The `codeql/cpp-upgrades` CodeQL pack has been removed. All upgrades scripts have been merged into the `codeql/cpp-all` CodeQL pack.
|
|
||||||
|
|
||||||
### Minor Analysis Improvements
|
|
||||||
|
|
||||||
* `FormatLiteral::getMaxConvertedLength` now uses range analysis to provide a
|
|
||||||
more accurate length for integers formatted with `%x`
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
## 0.0.9
|
|
||||||
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
---
|
|
||||||
lastReleaseVersion: 0.0.9
|
|
||||||
@@ -37,7 +37,7 @@ abstract class SimpleRangeAnalysisDefinition extends RangeSsaDefinition {
|
|||||||
* dependencies. Without this information, range analysis might work for
|
* dependencies. Without this information, range analysis might work for
|
||||||
* simple cases but will go into infinite loops on complex code.
|
* simple cases but will go into infinite loops on complex code.
|
||||||
*
|
*
|
||||||
* For example, when modeling the definition by reference in a call to an
|
* For example, when modelling the definition by reference in a call to an
|
||||||
* overloaded `operator=`, written as `v = e`, the definition of `(this, v)`
|
* overloaded `operator=`, written as `v = e`, the definition of `(this, v)`
|
||||||
* depends on `e`.
|
* depends on `e`.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* `Instruction` level), and then using the array length analysis and the range
|
* `Instruction` level), and then using the array length analysis and the range
|
||||||
* analysis together to prove that some of these pointer dereferences are safe.
|
* analysis together to prove that some of these pointer dereferences are safe.
|
||||||
*
|
*
|
||||||
* The analysis is soundy, i.e. it is sound if no undefined behavior is present
|
* The analysis is soundy, i.e. it is sound if no undefined behaviour is present
|
||||||
* in the program.
|
* in the program.
|
||||||
* Furthermore, it crucially depends on the soundiness of the range analysis and
|
* Furthermore, it crucially depends on the soundiness of the range analysis and
|
||||||
* the array length analysis.
|
* the array length analysis.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: codeql/cpp-all
|
name: codeql/cpp-all
|
||||||
version: 0.0.9
|
version: 0.0.2
|
||||||
groups: cpp
|
|
||||||
dbscheme: semmlecode.cpp.dbscheme
|
dbscheme: semmlecode.cpp.dbscheme
|
||||||
extractor: cpp
|
extractor: cpp
|
||||||
library: true
|
library: true
|
||||||
upgrades: upgrades
|
dependencies:
|
||||||
|
codeql/cpp-upgrades: 0.0.2
|
||||||
|
|||||||
@@ -206,7 +206,9 @@ class Class extends UserType {
|
|||||||
* it is callable by a particular caller. For C++11, there's also a question
|
* it is callable by a particular caller. For C++11, there's also a question
|
||||||
* of whether to include members that are defaulted or deleted.
|
* of whether to include members that are defaulted or deleted.
|
||||||
*/
|
*/
|
||||||
deprecated predicate hasCopyConstructor() { this.getAMemberFunction() instanceof CopyConstructor }
|
deprecated predicate hasCopyConstructor() {
|
||||||
|
exists(CopyConstructor cc | cc = this.getAMemberFunction())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if this class has a copy assignment operator that is either
|
* Holds if this class has a copy assignment operator that is either
|
||||||
@@ -222,7 +224,7 @@ class Class extends UserType {
|
|||||||
* or deleted.
|
* or deleted.
|
||||||
*/
|
*/
|
||||||
deprecated predicate hasCopyAssignmentOperator() {
|
deprecated predicate hasCopyAssignmentOperator() {
|
||||||
this.getAMemberFunction() instanceof CopyAssignmentOperator
|
exists(CopyAssignmentOperator coa | coa = this.getAMemberFunction())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -885,7 +887,7 @@ class NestedClass extends Class {
|
|||||||
* pure virtual function.
|
* pure virtual function.
|
||||||
*/
|
*/
|
||||||
class AbstractClass extends Class {
|
class AbstractClass extends Class {
|
||||||
AbstractClass() { this.getAMemberFunction() instanceof PureVirtualFunction }
|
AbstractClass() { exists(PureVirtualFunction f | this.getAMemberFunction() = f) }
|
||||||
|
|
||||||
override string getAPrimaryQlClass() { result = "AbstractClass" }
|
override string getAPrimaryQlClass() { result = "AbstractClass" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,13 +286,13 @@ class AttributeArgument extends Element, @attribute_arg {
|
|||||||
override Location getLocation() { attribute_args(underlyingElement(this), _, _, _, result) }
|
override Location getLocation() { attribute_args(underlyingElement(this), _, _, _, result) }
|
||||||
|
|
||||||
override string toString() {
|
override string toString() {
|
||||||
if underlyingElement(this) instanceof @attribute_arg_empty
|
if exists(@attribute_arg_empty self | self = underlyingElement(this))
|
||||||
then result = "empty argument"
|
then result = "empty argument"
|
||||||
else
|
else
|
||||||
exists(string prefix, string tail |
|
exists(string prefix, string tail |
|
||||||
(if exists(this.getName()) then prefix = this.getName() + "=" else prefix = "") and
|
(if exists(this.getName()) then prefix = this.getName() + "=" else prefix = "") and
|
||||||
(
|
(
|
||||||
if underlyingElement(this) instanceof @attribute_arg_type
|
if exists(@attribute_arg_type self | self = underlyingElement(this))
|
||||||
then tail = this.getValueType().getName()
|
then tail = this.getValueType().getName()
|
||||||
else tail = this.getValueText()
|
else tail = this.getValueText()
|
||||||
) and
|
) and
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
|
|||||||
XMLAttribute getAttribute(string name) { result.getElement() = this and result.getName() = name }
|
XMLAttribute getAttribute(string name) { result.getElement() = this and result.getName() = name }
|
||||||
|
|
||||||
/** Holds if this XML element has an attribute with the specified `name`. */
|
/** Holds if this XML element has an attribute with the specified `name`. */
|
||||||
predicate hasAttribute(string name) { exists(this.getAttribute(name)) }
|
predicate hasAttribute(string name) { exists(XMLAttribute a | a = this.getAttribute(name)) }
|
||||||
|
|
||||||
/** Gets the value of the attribute with the specified `name`, if any. */
|
/** Gets the value of the attribute with the specified `name`, if any. */
|
||||||
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }
|
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }
|
||||||
|
|||||||
@@ -3,14 +3,11 @@ private import semmle.code.cpp.models.interfaces.ArrayFunction
|
|||||||
private import semmle.code.cpp.models.implementations.Strcat
|
private import semmle.code.cpp.models.implementations.Strcat
|
||||||
import semmle.code.cpp.dataflow.DataFlow
|
import semmle.code.cpp.dataflow.DataFlow
|
||||||
|
|
||||||
/**
|
private predicate mayAddNullTerminatorHelper(Expr e, VariableAccess va, Expr e0) {
|
||||||
* Holds if the expression `e` assigns something including `va` to a
|
exists(StackVariable v0, Expr val |
|
||||||
* stack variable `v0`.
|
exprDefinition(v0, e, val) and
|
||||||
*/
|
val.getAChild*() = va and
|
||||||
private predicate mayAddNullTerminatorHelper(Expr e, VariableAccess va, StackVariable v0) {
|
mayAddNullTerminator(e0, v0.getAnAccess())
|
||||||
exists(Expr val |
|
|
||||||
exprDefinition(v0, e, val) and // `e` is `v0 := val`
|
|
||||||
val.getAChild*() = va
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,8 +25,8 @@ private predicate controlFlowNodeSuccessorTransitive(ControlFlowNode n1, Control
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the expression `e` may add a null terminator to the string
|
* Holds if the expression `e` may add a null terminator to the string in
|
||||||
* accessed by `va`.
|
* variable `v`.
|
||||||
*/
|
*/
|
||||||
predicate mayAddNullTerminator(Expr e, VariableAccess va) {
|
predicate mayAddNullTerminator(Expr e, VariableAccess va) {
|
||||||
// Assignment: dereferencing or array access
|
// Assignment: dereferencing or array access
|
||||||
@@ -46,9 +43,8 @@ predicate mayAddNullTerminator(Expr e, VariableAccess va) {
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
// Assignment to another stack variable
|
// Assignment to another stack variable
|
||||||
exists(StackVariable v0, Expr e0 |
|
exists(Expr e0 |
|
||||||
mayAddNullTerminatorHelper(e, va, v0) and
|
mayAddNullTerminatorHelper(pragma[only_bind_into](e), va, pragma[only_bind_into](e0)) and
|
||||||
mayAddNullTerminator(pragma[only_bind_into](e0), pragma[only_bind_into](v0.getAnAccess())) and
|
|
||||||
controlFlowNodeSuccessorTransitive(e, e0)
|
controlFlowNodeSuccessorTransitive(e, e0)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
@@ -101,21 +97,6 @@ predicate functionArgumentMustBeNullTerminated(Function f, int i) {
|
|||||||
f instanceof StrcatFunction and i = 0
|
f instanceof StrcatFunction and i = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `arg` is a string format argument to a formatting function call
|
|
||||||
* `ffc`.
|
|
||||||
*/
|
|
||||||
predicate formatArgumentMustBeNullTerminated(FormattingFunctionCall ffc, Expr arg) {
|
|
||||||
// String argument to a formatting function (such as `printf`)
|
|
||||||
exists(int n, FormatLiteral fl |
|
|
||||||
ffc.getConversionArgument(n) = arg and
|
|
||||||
fl = ffc.getFormat() and
|
|
||||||
fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc
|
|
||||||
not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p`
|
|
||||||
not fl.hasPrecision(n) // exclude: `%.*s`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `va` is a variable access where the contents must be null terminated.
|
* Holds if `va` is a variable access where the contents must be null terminated.
|
||||||
*/
|
*/
|
||||||
@@ -128,7 +109,13 @@ predicate variableMustBeNullTerminated(VariableAccess va) {
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
// String argument to a formatting function (such as `printf`)
|
// String argument to a formatting function (such as `printf`)
|
||||||
formatArgumentMustBeNullTerminated(fc, va)
|
exists(int n, FormatLiteral fl |
|
||||||
|
fc.(FormattingFunctionCall).getConversionArgument(n) = va and
|
||||||
|
fl = fc.(FormattingFunctionCall).getFormat() and
|
||||||
|
fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc
|
||||||
|
not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p`
|
||||||
|
not fl.hasPrecision(n) // exclude: `%.*s`
|
||||||
|
)
|
||||||
or
|
or
|
||||||
// Call to a wrapper function that requires null termination
|
// Call to a wrapper function that requires null termination
|
||||||
// (not itself adding a null terminator)
|
// (not itself adding a null terminator)
|
||||||
|
|||||||
@@ -6,108 +6,6 @@ import semmle.code.cpp.Type
|
|||||||
import semmle.code.cpp.commons.CommonType
|
import semmle.code.cpp.commons.CommonType
|
||||||
import semmle.code.cpp.commons.StringAnalysis
|
import semmle.code.cpp.commons.StringAnalysis
|
||||||
import semmle.code.cpp.models.interfaces.FormattingFunction
|
import semmle.code.cpp.models.interfaces.FormattingFunction
|
||||||
private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
|
||||||
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
|
||||||
|
|
||||||
private newtype TBufferWriteEstimationReason =
|
|
||||||
TUnspecifiedEstimateReason() or
|
|
||||||
TTypeBoundsAnalysis() or
|
|
||||||
TWidenedValueFlowAnalysis() or
|
|
||||||
TValueFlowAnalysis()
|
|
||||||
|
|
||||||
private predicate gradeToReason(int grade, TBufferWriteEstimationReason reason) {
|
|
||||||
// when combining reasons, lower grade takes precedence
|
|
||||||
grade = 0 and reason = TUnspecifiedEstimateReason()
|
|
||||||
or
|
|
||||||
grade = 1 and reason = TTypeBoundsAnalysis()
|
|
||||||
or
|
|
||||||
grade = 2 and reason = TWidenedValueFlowAnalysis()
|
|
||||||
or
|
|
||||||
grade = 3 and reason = TValueFlowAnalysis()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A reason for a specific buffer write size estimate.
|
|
||||||
*/
|
|
||||||
abstract class BufferWriteEstimationReason extends TBufferWriteEstimationReason {
|
|
||||||
/**
|
|
||||||
* Returns the name of the concrete class.
|
|
||||||
*/
|
|
||||||
abstract string toString();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a human readable representation of this reason.
|
|
||||||
*/
|
|
||||||
abstract string getDescription();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combine estimate reasons. Used to give a reason for the size of a format string
|
|
||||||
* conversion given reasons coming from its individual specifiers.
|
|
||||||
*/
|
|
||||||
BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
|
|
||||||
exists(int grade, int otherGrade |
|
|
||||||
gradeToReason(grade, this) and gradeToReason(otherGrade, other)
|
|
||||||
|
|
|
||||||
if otherGrade < grade then result = other else result = this
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* No particular reason given. This is currently used for backward compatibility so that
|
|
||||||
* classes derived from BufferWrite and overriding `getMaxData/0` still work with the
|
|
||||||
* queries as intended.
|
|
||||||
*/
|
|
||||||
class UnspecifiedEstimateReason extends BufferWriteEstimationReason, TUnspecifiedEstimateReason {
|
|
||||||
override string toString() { result = "UnspecifiedEstimateReason" }
|
|
||||||
|
|
||||||
override string getDescription() { result = "no reason specified" }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The estimation comes from rough bounds just based on the type (e.g.
|
|
||||||
* `0 <= x < 2^32` for an unsigned 32 bit integer).
|
|
||||||
*/
|
|
||||||
class TypeBoundsAnalysis extends BufferWriteEstimationReason, TTypeBoundsAnalysis {
|
|
||||||
override string toString() { result = "TypeBoundsAnalysis" }
|
|
||||||
|
|
||||||
override string getDescription() { result = "based on type bounds" }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The estimation comes from non trivial bounds found via actual flow analysis,
|
|
||||||
* but a widening aproximation might have been used for variables in loops.
|
|
||||||
* For example
|
|
||||||
* ```
|
|
||||||
* for (int i = 0; i < 10; ++i) {
|
|
||||||
* int j = i + i;
|
|
||||||
* //... <- estimation done here based on j
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
class WidenedValueFlowAnalysis extends BufferWriteEstimationReason, TWidenedValueFlowAnalysis {
|
|
||||||
override string toString() { result = "WidenedValueFlowAnalysis" }
|
|
||||||
|
|
||||||
override string getDescription() {
|
|
||||||
result = "based on flow analysis of value bounds with a widening approximation"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The estimation comes from non trivial bounds found via actual flow analysis.
|
|
||||||
* For example
|
|
||||||
* ```
|
|
||||||
* unsigned u = x;
|
|
||||||
* if (u < 1000) {
|
|
||||||
* //... <- estimation done here based on u
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
class ValueFlowAnalysis extends BufferWriteEstimationReason, TValueFlowAnalysis {
|
|
||||||
override string toString() { result = "ValueFlowAnalysis" }
|
|
||||||
|
|
||||||
override string getDescription() { result = "based on flow analysis of value bounds" }
|
|
||||||
}
|
|
||||||
|
|
||||||
class PrintfFormatAttribute extends FormatAttribute {
|
class PrintfFormatAttribute extends FormatAttribute {
|
||||||
PrintfFormatAttribute() { this.getArchetype() = ["printf", "__printf__"] }
|
PrintfFormatAttribute() { this.getArchetype() = ["printf", "__printf__"] }
|
||||||
@@ -370,50 +268,6 @@ class FormattingFunctionCall extends Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the number of digits required to represent the integer represented by `f`.
|
|
||||||
*
|
|
||||||
* `f` is assumed to be nonnegative.
|
|
||||||
*/
|
|
||||||
bindingset[f]
|
|
||||||
private int lengthInBase10(float f) {
|
|
||||||
f = 0 and result = 1
|
|
||||||
or
|
|
||||||
result = f.log10().floor() + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[nomagic]
|
|
||||||
private predicate isPointerTypeWithBase(Type base, PointerType pt) { base = pt.getBaseType() }
|
|
||||||
|
|
||||||
bindingset[expr]
|
|
||||||
private BufferWriteEstimationReason getEstimationReasonForIntegralExpression(Expr expr) {
|
|
||||||
// we consider the range analysis non trivial if it
|
|
||||||
// * constrained non-trivially both sides of a signed value, or
|
|
||||||
// * constrained non-trivially the positive side of an unsigned value
|
|
||||||
// expr should already be given as getFullyConverted
|
|
||||||
if
|
|
||||||
upperBound(expr) < exprMaxVal(expr) and
|
|
||||||
(exprMinVal(expr) >= 0 or lowerBound(expr) > exprMinVal(expr))
|
|
||||||
then
|
|
||||||
// next we check whether the estimate may have been widened
|
|
||||||
if upperBoundMayBeWidened(expr)
|
|
||||||
then result = TWidenedValueFlowAnalysis()
|
|
||||||
else result = TValueFlowAnalysis()
|
|
||||||
else result = TTypeBoundsAnalysis()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the number of hex digits required to represent the integer represented by `f`.
|
|
||||||
*
|
|
||||||
* `f` is assumed to be nonnegative.
|
|
||||||
*/
|
|
||||||
bindingset[f]
|
|
||||||
private int lengthInBase16(float f) {
|
|
||||||
f = 0 and result = 1
|
|
||||||
or
|
|
||||||
result = (f.log2() / 4.0).floor() + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class to represent format strings that occur as arguments to invocations of formatting functions.
|
* A class to represent format strings that occur as arguments to invocations of formatting functions.
|
||||||
*/
|
*/
|
||||||
@@ -965,19 +819,19 @@ class FormatLiteral extends Literal {
|
|||||||
(
|
(
|
||||||
conv = ["s", "S"] and
|
conv = ["s", "S"] and
|
||||||
len = "h" and
|
len = "h" and
|
||||||
isPointerTypeWithBase(any(PlainCharType plainCharType), result)
|
result.(PointerType).getBaseType() instanceof PlainCharType
|
||||||
or
|
or
|
||||||
conv = ["s", "S"] and
|
conv = ["s", "S"] and
|
||||||
len = ["l", "w"] and
|
len = ["l", "w"] and
|
||||||
isPointerTypeWithBase(this.getWideCharType(), result)
|
result.(PointerType).getBaseType() = this.getWideCharType()
|
||||||
or
|
or
|
||||||
conv = "s" and
|
conv = "s" and
|
||||||
(len != "l" and len != "w" and len != "h") and
|
(len != "l" and len != "w" and len != "h") and
|
||||||
isPointerTypeWithBase(this.getDefaultCharType(), result)
|
result.(PointerType).getBaseType() = this.getDefaultCharType()
|
||||||
or
|
or
|
||||||
conv = "S" and
|
conv = "S" and
|
||||||
(len != "l" and len != "w" and len != "h") and
|
(len != "l" and len != "w" and len != "h") and
|
||||||
isPointerTypeWithBase(this.getNonDefaultCharType(), result)
|
result.(PointerType).getBaseType() = this.getNonDefaultCharType()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1122,14 +976,7 @@ class FormatLiteral extends Literal {
|
|||||||
* conversion specifier of this format string; has no result if this cannot
|
* conversion specifier of this format string; has no result if this cannot
|
||||||
* be determined.
|
* be determined.
|
||||||
*/
|
*/
|
||||||
int getMaxConvertedLength(int n) { result = max(this.getMaxConvertedLength(n, _)) }
|
int getMaxConvertedLength(int n) {
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the maximum length of the string that can be produced by the nth
|
|
||||||
* conversion specifier of this format string, specifying the estimation reason;
|
|
||||||
* has no result if this cannot be determined.
|
|
||||||
*/
|
|
||||||
int getMaxConvertedLength(int n, BufferWriteEstimationReason reason) {
|
|
||||||
exists(int len |
|
exists(int len |
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
@@ -1141,12 +988,10 @@ class FormatLiteral extends Literal {
|
|||||||
) and
|
) and
|
||||||
(
|
(
|
||||||
this.getConversionChar(n) = "%" and
|
this.getConversionChar(n) = "%" and
|
||||||
len = 1 and
|
len = 1
|
||||||
reason = TValueFlowAnalysis()
|
|
||||||
or
|
or
|
||||||
this.getConversionChar(n).toLowerCase() = "c" and
|
this.getConversionChar(n).toLowerCase() = "c" and
|
||||||
len = 1 and
|
len = 1 // e.g. 'a'
|
||||||
reason = TValueFlowAnalysis() // e.g. 'a'
|
|
||||||
or
|
or
|
||||||
this.getConversionChar(n).toLowerCase() = "f" and
|
this.getConversionChar(n).toLowerCase() = "f" and
|
||||||
exists(int dot, int afterdot |
|
exists(int dot, int afterdot |
|
||||||
@@ -1160,8 +1005,7 @@ class FormatLiteral extends Literal {
|
|||||||
afterdot = 6
|
afterdot = 6
|
||||||
) and
|
) and
|
||||||
len = 1 + 309 + dot + afterdot
|
len = 1 + 309 + dot + afterdot
|
||||||
) and
|
) // e.g. -1e308="-100000"...
|
||||||
reason = TTypeBoundsAnalysis() // e.g. -1e308="-100000"...
|
|
||||||
or
|
or
|
||||||
this.getConversionChar(n).toLowerCase() = "e" and
|
this.getConversionChar(n).toLowerCase() = "e" and
|
||||||
exists(int dot, int afterdot |
|
exists(int dot, int afterdot |
|
||||||
@@ -1175,8 +1019,7 @@ class FormatLiteral extends Literal {
|
|||||||
afterdot = 6
|
afterdot = 6
|
||||||
) and
|
) and
|
||||||
len = 1 + 1 + dot + afterdot + 1 + 1 + 3
|
len = 1 + 1 + dot + afterdot + 1 + 1 + 3
|
||||||
) and
|
) // -1e308="-1.000000e+308"
|
||||||
reason = TTypeBoundsAnalysis() // -1e308="-1.000000e+308"
|
|
||||||
or
|
or
|
||||||
this.getConversionChar(n).toLowerCase() = "g" and
|
this.getConversionChar(n).toLowerCase() = "g" and
|
||||||
exists(int dot, int afterdot |
|
exists(int dot, int afterdot |
|
||||||
@@ -1199,111 +1042,62 @@ class FormatLiteral extends Literal {
|
|||||||
// (e.g. 123456, 0.000123456 are just OK)
|
// (e.g. 123456, 0.000123456 are just OK)
|
||||||
// so case %f can be at most P characters + 4 zeroes, sign, dot = P + 6
|
// so case %f can be at most P characters + 4 zeroes, sign, dot = P + 6
|
||||||
len = (afterdot.maximum(1) + 6).maximum(1 + 1 + dot + afterdot + 1 + 1 + 3)
|
len = (afterdot.maximum(1) + 6).maximum(1 + 1 + dot + afterdot + 1 + 1 + 3)
|
||||||
) and
|
) // (e.g. "-1.59203e-319")
|
||||||
reason = TTypeBoundsAnalysis() // (e.g. "-1.59203e-319")
|
|
||||||
or
|
or
|
||||||
this.getConversionChar(n).toLowerCase() = ["d", "i"] and
|
this.getConversionChar(n).toLowerCase() = ["d", "i"] and
|
||||||
// e.g. -2^31 = "-2147483648"
|
// e.g. -2^31 = "-2147483648"
|
||||||
exists(float typeBasedBound, float valueBasedBound |
|
exists(int sizeBits |
|
||||||
// The first case handles length sub-specifiers
|
sizeBits =
|
||||||
// Subtract one in the exponent because one bit is for the sign.
|
min(int bits |
|
||||||
// Add 1 to account for the possible sign in the output.
|
bits = this.getIntegralDisplayType(n).getSize() * 8
|
||||||
typeBasedBound =
|
|
||||||
1 + lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8 - 1)) and
|
|
||||||
// The second case uses range analysis to deduce a length that's shorter than the length
|
|
||||||
// of the number -2^31.
|
|
||||||
exists(Expr arg, float lower, float upper |
|
|
||||||
arg = this.getUse().getConversionArgument(n) and
|
|
||||||
lower = lowerBound(arg.getFullyConverted()) and
|
|
||||||
upper = upperBound(arg.getFullyConverted())
|
|
||||||
|
|
|
||||||
valueBasedBound =
|
|
||||||
max(int cand |
|
|
||||||
// Include the sign bit in the length if it can be negative
|
|
||||||
(
|
|
||||||
if lower < 0
|
|
||||||
then cand = 1 + lengthInBase10(lower.abs())
|
|
||||||
else cand = lengthInBase10(lower)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
(
|
|
||||||
if upper < 0
|
|
||||||
then cand = 1 + lengthInBase10(upper.abs())
|
|
||||||
else cand = lengthInBase10(upper)
|
|
||||||
)
|
|
||||||
) and
|
|
||||||
// we don't want to call this on `arg.getFullyConverted()` as we want
|
|
||||||
// to detect non-trivial range analysis without taking into account up-casting
|
|
||||||
reason = getEstimationReasonForIntegralExpression(arg)
|
|
||||||
) and
|
|
||||||
len = valueBasedBound.minimum(typeBasedBound)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
this.getConversionChar(n).toLowerCase() = "u" and
|
|
||||||
// e.g. 2^32 - 1 = "4294967295"
|
|
||||||
exists(float typeBasedBound, float valueBasedBound |
|
|
||||||
// The first case handles length sub-specifiers
|
|
||||||
typeBasedBound = lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8) - 1) and
|
|
||||||
// The second case uses range analysis to deduce a length that's shorter than
|
|
||||||
// the length of the number 2^31 - 1.
|
|
||||||
exists(Expr arg, float lower, float upper |
|
|
||||||
arg = this.getUse().getConversionArgument(n) and
|
|
||||||
lower = lowerBound(arg.getFullyConverted()) and
|
|
||||||
upper = upperBound(arg.getFullyConverted())
|
|
||||||
|
|
|
||||||
valueBasedBound =
|
|
||||||
lengthInBase10(max(float cand |
|
|
||||||
// If lower can be negative we use `(unsigned)-1` as the candidate value.
|
|
||||||
lower < 0 and
|
|
||||||
cand = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
|
|
||||||
or
|
|
||||||
cand = upper
|
|
||||||
)) and
|
|
||||||
// we don't want to call this on `arg.getFullyConverted()` as we want
|
|
||||||
// to detect non-trivial range analysis without taking into account up-casting
|
|
||||||
reason = getEstimationReasonForIntegralExpression(arg)
|
|
||||||
) and
|
|
||||||
len = valueBasedBound.minimum(typeBasedBound)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
this.getConversionChar(n).toLowerCase() = "x" and
|
|
||||||
// e.g. "12345678"
|
|
||||||
exists(int baseLen, int typeBasedBound, int valueBasedBound |
|
|
||||||
typeBasedBound =
|
|
||||||
min(int digits |
|
|
||||||
digits = 2 * this.getIntegralDisplayType(n).getSize()
|
|
||||||
or
|
or
|
||||||
exists(IntegralType t |
|
exists(IntegralType t |
|
||||||
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||||
|
|
|
|
||||||
t.isUnsigned() and
|
t.isSigned() and bits = t.getSize() * 8
|
||||||
digits = 2 * t.getSize()
|
|
||||||
)
|
)
|
||||||
) and
|
) and
|
||||||
exists(Expr arg, float lower, float upper, float typeLower, float typeUpper |
|
len = 1 + ((sizeBits - 1) / 10.0.log2()).ceil()
|
||||||
arg = this.getUse().getConversionArgument(n) and
|
// this calculation is as %u (below) only we take out the sign bit (- 1) and allow a whole
|
||||||
lower = lowerBound(arg.getFullyConverted()) and
|
// character for it to be expressed as '-'.
|
||||||
upper = upperBound(arg.getFullyConverted()) and
|
)
|
||||||
typeLower = exprMinVal(arg.getFullyConverted()) and
|
|
||||||
typeUpper = exprMaxVal(arg.getFullyConverted())
|
|
||||||
|
|
|
||||||
valueBasedBound =
|
|
||||||
lengthInBase16(max(float cand |
|
|
||||||
// If lower can be negative we use `(unsigned)-1` as the candidate value.
|
|
||||||
lower < 0 and
|
|
||||||
cand = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
|
|
||||||
or
|
or
|
||||||
cand = upper
|
this.getConversionChar(n).toLowerCase() = "u" and
|
||||||
)) and
|
// e.g. 2^32 - 1 = "4294967295"
|
||||||
(
|
exists(int sizeBits |
|
||||||
if lower > typeLower or upper < typeUpper
|
sizeBits =
|
||||||
then reason = TValueFlowAnalysis()
|
min(int bits |
|
||||||
else reason = TTypeBoundsAnalysis()
|
bits = this.getIntegralDisplayType(n).getSize() * 8
|
||||||
|
or
|
||||||
|
exists(IntegralType t |
|
||||||
|
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||||
|
|
|
||||||
|
t.isUnsigned() and bits = t.getSize() * 8
|
||||||
)
|
)
|
||||||
) and
|
) and
|
||||||
baseLen = valueBasedBound.minimum(typeBasedBound) and
|
len = (sizeBits / 10.0.log2()).ceil()
|
||||||
|
// convert the size from bits to decimal characters, and round up as you can't have
|
||||||
|
// fractional characters (10.0.log2() is the number of bits expressed per decimal character)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
this.getConversionChar(n).toLowerCase() = "x" and
|
||||||
|
// e.g. "12345678"
|
||||||
|
exists(int sizeBytes, int baseLen |
|
||||||
|
sizeBytes =
|
||||||
|
min(int bytes |
|
||||||
|
bytes = this.getIntegralDisplayType(n).getSize()
|
||||||
|
or
|
||||||
|
exists(IntegralType t |
|
||||||
|
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
||||||
|
|
|
||||||
|
t.isUnsigned() and bytes = t.getSize()
|
||||||
|
)
|
||||||
|
) and
|
||||||
|
baseLen = sizeBytes * 2 and
|
||||||
|
(
|
||||||
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
|
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
|
||||||
)
|
)
|
||||||
|
)
|
||||||
or
|
or
|
||||||
this.getConversionChar(n).toLowerCase() = "p" and
|
this.getConversionChar(n).toLowerCase() = "p" and
|
||||||
exists(PointerType ptrType, int baseLen |
|
exists(PointerType ptrType, int baseLen |
|
||||||
@@ -1312,8 +1106,7 @@ class FormatLiteral extends Literal {
|
|||||||
(
|
(
|
||||||
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
|
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
|
||||||
)
|
)
|
||||||
) and
|
)
|
||||||
reason = TValueFlowAnalysis()
|
|
||||||
or
|
or
|
||||||
this.getConversionChar(n).toLowerCase() = "o" and
|
this.getConversionChar(n).toLowerCase() = "o" and
|
||||||
// e.g. 2^32 - 1 = "37777777777"
|
// e.g. 2^32 - 1 = "37777777777"
|
||||||
@@ -1332,16 +1125,14 @@ class FormatLiteral extends Literal {
|
|||||||
(
|
(
|
||||||
if this.hasAlternateFlag(n) then len = 1 + baseLen else len = baseLen // "0"
|
if this.hasAlternateFlag(n) then len = 1 + baseLen else len = baseLen // "0"
|
||||||
)
|
)
|
||||||
) and
|
)
|
||||||
reason = TTypeBoundsAnalysis()
|
|
||||||
or
|
or
|
||||||
this.getConversionChar(n).toLowerCase() = "s" and
|
this.getConversionChar(n).toLowerCase() = "s" and
|
||||||
len =
|
len =
|
||||||
min(int v |
|
min(int v |
|
||||||
v = this.getPrecision(n) or
|
v = this.getPrecision(n) or
|
||||||
v = this.getUse().getFormatArgument(n).(AnalysedString).getMaxLength() - 1 // (don't count null terminator)
|
v = this.getUse().getFormatArgument(n).(AnalysedString).getMaxLength() - 1 // (don't count null terminator)
|
||||||
) and
|
)
|
||||||
reason = TValueFlowAnalysis()
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1353,19 +1144,10 @@ class FormatLiteral extends Literal {
|
|||||||
* determining whether a buffer overflow is caused by long float to string
|
* determining whether a buffer overflow is caused by long float to string
|
||||||
* conversions.
|
* conversions.
|
||||||
*/
|
*/
|
||||||
int getMaxConvertedLengthLimited(int n) { result = max(this.getMaxConvertedLengthLimited(n, _)) }
|
int getMaxConvertedLengthLimited(int n) {
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the maximum length of the string that can be produced by the nth
|
|
||||||
* conversion specifier of this format string, specifying the reason for the
|
|
||||||
* estimation, except that float to string conversions are assumed to be 8
|
|
||||||
* characters. This is helpful for determining whether a buffer overflow is
|
|
||||||
* caused by long float to string conversions.
|
|
||||||
*/
|
|
||||||
int getMaxConvertedLengthLimited(int n, BufferWriteEstimationReason reason) {
|
|
||||||
if this.getConversionChar(n).toLowerCase() = "f"
|
if this.getConversionChar(n).toLowerCase() = "f"
|
||||||
then result = this.getMaxConvertedLength(n, reason).minimum(8)
|
then result = this.getMaxConvertedLength(n).minimum(8)
|
||||||
else result = this.getMaxConvertedLength(n, reason)
|
else result = this.getMaxConvertedLength(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1405,35 +1187,29 @@ class FormatLiteral extends Literal {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMaxConvertedLengthAfter(int n, BufferWriteEstimationReason reason) {
|
private int getMaxConvertedLengthAfter(int n) {
|
||||||
if n = this.getNumConvSpec()
|
if n = this.getNumConvSpec()
|
||||||
then result = this.getConstantSuffix().length() + 1 and reason = TValueFlowAnalysis()
|
then result = this.getConstantSuffix().length() + 1
|
||||||
else
|
else
|
||||||
exists(BufferWriteEstimationReason headReason, BufferWriteEstimationReason tailReason |
|
|
||||||
result =
|
result =
|
||||||
this.getConstantPart(n).length() + this.getMaxConvertedLength(n, headReason) +
|
this.getConstantPart(n).length() + this.getMaxConvertedLength(n) +
|
||||||
this.getMaxConvertedLengthAfter(n + 1, tailReason) and
|
this.getMaxConvertedLengthAfter(n + 1)
|
||||||
reason = headReason.combineWith(tailReason)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMaxConvertedLengthAfterLimited(int n, BufferWriteEstimationReason reason) {
|
private int getMaxConvertedLengthAfterLimited(int n) {
|
||||||
if n = this.getNumConvSpec()
|
if n = this.getNumConvSpec()
|
||||||
then result = this.getConstantSuffix().length() + 1 and reason = TValueFlowAnalysis()
|
then result = this.getConstantSuffix().length() + 1
|
||||||
else
|
else
|
||||||
exists(BufferWriteEstimationReason headReason, BufferWriteEstimationReason tailReason |
|
|
||||||
result =
|
result =
|
||||||
this.getConstantPart(n).length() + this.getMaxConvertedLengthLimited(n, headReason) +
|
this.getConstantPart(n).length() + this.getMaxConvertedLengthLimited(n) +
|
||||||
this.getMaxConvertedLengthAfterLimited(n + 1, tailReason) and
|
this.getMaxConvertedLengthAfterLimited(n + 1)
|
||||||
reason = headReason.combineWith(tailReason)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the maximum length of the string that can be produced by this format
|
* Gets the maximum length of the string that can be produced by this format
|
||||||
* string. Has no result if this cannot be determined.
|
* string. Has no result if this cannot be determined.
|
||||||
*/
|
*/
|
||||||
int getMaxConvertedLength() { result = this.getMaxConvertedLengthAfter(0, _) }
|
int getMaxConvertedLength() { result = this.getMaxConvertedLengthAfter(0) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the maximum length of the string that can be produced by this format
|
* Gets the maximum length of the string that can be produced by this format
|
||||||
@@ -1441,24 +1217,5 @@ class FormatLiteral extends Literal {
|
|||||||
* characters. This is helpful for determining whether a buffer overflow
|
* characters. This is helpful for determining whether a buffer overflow
|
||||||
* is caused by long float to string conversions.
|
* is caused by long float to string conversions.
|
||||||
*/
|
*/
|
||||||
int getMaxConvertedLengthLimited() { result = this.getMaxConvertedLengthAfterLimited(0, _) }
|
int getMaxConvertedLengthLimited() { result = this.getMaxConvertedLengthAfterLimited(0) }
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the maximum length of the string that can be produced by this format
|
|
||||||
* string, specifying the reason for the estimate. Has no result if no estimate
|
|
||||||
* can be found.
|
|
||||||
*/
|
|
||||||
int getMaxConvertedLengthWithReason(BufferWriteEstimationReason reason) {
|
|
||||||
result = this.getMaxConvertedLengthAfter(0, reason)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the maximum length of the string that can be produced by this format
|
|
||||||
* string, specifying the reason for the estimate, except that float to string
|
|
||||||
* conversions are assumed to be 8 characters. This is helpful for determining
|
|
||||||
* whether a buffer overflow is caused by long float to string conversions.
|
|
||||||
*/
|
|
||||||
int getMaxConvertedLengthLimitedWithReason(BufferWriteEstimationReason reason) {
|
|
||||||
result = this.getMaxConvertedLengthAfterLimited(0, reason)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ import cpp
|
|||||||
*/
|
*/
|
||||||
bindingset[input]
|
bindingset[input]
|
||||||
int parseOctal(string input) {
|
int parseOctal(string input) {
|
||||||
input.regexpMatch("0[0-7]+") and
|
input.charAt(0) = "0" and
|
||||||
result =
|
result =
|
||||||
strictsum(int ix |
|
strictsum(int ix |
|
||||||
ix in [1 .. input.length()]
|
ix in [0 .. input.length()]
|
||||||
|
|
|
|
||||||
8.pow(input.length() - (ix + 1)) * input.charAt(ix).toInt()
|
8.pow(input.length() - (ix + 1)) * input.charAt(ix).toInt()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class GuardCondition extends Expr {
|
|||||||
exists(IRGuardCondition ir | this = ir.getUnconvertedResultExpression())
|
exists(IRGuardCondition ir | this = ir.getUnconvertedResultExpression())
|
||||||
or
|
or
|
||||||
// no binary operators in the IR
|
// no binary operators in the IR
|
||||||
this.(BinaryLogicalOperation).getAnOperand() instanceof GuardCondition
|
exists(GuardCondition gc | this.(BinaryLogicalOperation).getAnOperand() = gc)
|
||||||
or
|
or
|
||||||
// the IR short-circuits if(!x)
|
// the IR short-circuits if(!x)
|
||||||
// don't produce a guard condition for `y = !x` and other non-short-circuited cases
|
// don't produce a guard condition for `y = !x` and other non-short-circuited cases
|
||||||
@@ -98,7 +98,7 @@ class GuardCondition extends Expr {
|
|||||||
*/
|
*/
|
||||||
private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
|
private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
|
||||||
GuardConditionFromBinaryLogicalOperator() {
|
GuardConditionFromBinaryLogicalOperator() {
|
||||||
this.(BinaryLogicalOperation).getAnOperand() instanceof GuardCondition
|
exists(GuardCondition gc | this.(BinaryLogicalOperation).getAnOperand() = gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate controls(BasicBlock controlled, boolean testIsTrue) {
|
override predicate controls(BasicBlock controlled, boolean testIsTrue) {
|
||||||
|
|||||||
@@ -153,11 +153,9 @@ library class SSAHelper extends int {
|
|||||||
* Modern Compiler Implementation by Andrew Appel.
|
* Modern Compiler Implementation by Andrew Appel.
|
||||||
*/
|
*/
|
||||||
private predicate frontier_phi_node(StackVariable v, BasicBlock b) {
|
private predicate frontier_phi_node(StackVariable v, BasicBlock b) {
|
||||||
exists(BasicBlock x |
|
exists(BasicBlock x | dominanceFrontier(x, b) and ssa_defn_rec(v, x)) and
|
||||||
dominanceFrontier(x, b) and ssa_defn_rec(pragma[only_bind_into](v), pragma[only_bind_into](x))
|
|
||||||
) and
|
|
||||||
/* We can also eliminate those nodes where the variable is not live on any incoming edge */
|
/* We can also eliminate those nodes where the variable is not live on any incoming edge */
|
||||||
live_at_start_of_bb(pragma[only_bind_into](v), b)
|
live_at_start_of_bb(v, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate ssa_defn_rec(StackVariable v, BasicBlock b) {
|
private predicate ssa_defn_rec(StackVariable v, BasicBlock b) {
|
||||||
|
|||||||
@@ -626,9 +626,9 @@ library class ExprEvaluator extends int {
|
|||||||
// All assignments must have the same int value
|
// All assignments must have the same int value
|
||||||
result =
|
result =
|
||||||
unique(Expr value |
|
unique(Expr value |
|
||||||
value = v.getAnAssignedValue() and not this.ignoreVariableAssignment(e, v, value)
|
value = v.getAnAssignedValue() and not ignoreVariableAssignment(e, v, value)
|
||||||
|
|
|
|
||||||
this.getValueInternalNonSubExpr(value)
|
getValueInternalNonSubExpr(value)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
private import cpp
|
private import cpp
|
||||||
private import semmle.code.cpp.dataflow.internal.DataFlowPrivate
|
|
||||||
private import semmle.code.cpp.dataflow.internal.DataFlowUtil
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a function that might be called by `call`.
|
* Gets a function that might be called by `call`.
|
||||||
@@ -65,17 +63,3 @@ predicate mayBenefitFromCallContext(Call call, Function f) { none() }
|
|||||||
* restricted to those `call`s for which a context might make a difference.
|
* restricted to those `call`s for which a context might make a difference.
|
||||||
*/
|
*/
|
||||||
Function viableImplInCallContext(Call call, Call ctx) { none() }
|
Function viableImplInCallContext(Call call, Call ctx) { none() }
|
||||||
|
|
||||||
/** A parameter position represented by an integer. */
|
|
||||||
class ParameterPosition extends int {
|
|
||||||
ParameterPosition() { any(ParameterNode p).isParameterOf(_, this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** An argument position represented by an integer. */
|
|
||||||
class ArgumentPosition extends int {
|
|
||||||
ArgumentPosition() { any(ArgumentNode a).argumentOf(_, this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
|
|
||||||
pragma[inline]
|
|
||||||
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user