Merge branch 'main' into calumgrant/bmn/wrong-type-format-arg-linkage

This commit is contained in:
Jeroen Ketema
2025-02-03 11:23:27 +01:00
committed by GitHub
645 changed files with 34917 additions and 13475 deletions

View File

@@ -2,6 +2,9 @@ common --enable_platform_specific_config
# because we use --override_module with `%workspace%`, the lock file is not stable
common --lockfile_mode=off
# Build release binaries by default, can be overwritten to in local.bazelrc and set to `fastbuild` or `dbg`
build --compilation_mode opt
# when building from this repository in isolation, the internal repository will not be found at ..
# where `MODULE.bazel` looks for it. The following will get us past the module loading phase, so
# that we can build things that do not rely on that

View File

@@ -1,9 +0,0 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.236.0/containers/cpp/.devcontainer/base.Dockerfile
# [Choice] Debian / Ubuntu version (use Debian 11, Ubuntu 18.04/22.04 on local arm64/Apple Silicon): debian-11, debian-10, ubuntu-22.04, ubuntu-20.04, ubuntu-18.04
FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-ubuntu-22.04
USER root
ADD root.sh /tmp/root.sh
ADD update-codeql.sh /usr/local/bin/update-codeql
RUN bash /tmp/root.sh && rm /tmp/root.sh

View File

@@ -1,25 +0,0 @@
{
"extensions": [
"github.vscode-codeql",
"hbenl.vscode-test-explorer",
"ms-vscode.test-adapter-converter",
"slevesque.vscode-zipexplorer",
"ms-vscode.cpptools"
],
"settings": {
"files.watcherExclude": {
"**/target/**": true
},
"codeQL.runningQueries.memory": 2048
},
"build": {
"dockerfile": "Dockerfile",
},
"runArgs": [
"--cap-add=SYS_PTRACE",
"--security-opt",
"seccomp=unconfined"
],
"remoteUser": "vscode",
"onCreateCommand": ".devcontainer/swift/user.sh"
}

View File

@@ -1,34 +0,0 @@
set -xe
BAZELISK_VERSION=v1.12.0
BAZELISK_DOWNLOAD_SHA=6b0bcb2ea15bca16fffabe6fda75803440375354c085480fe361d2cbf32501db
# install git lfs apt source
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash
# install gh apt source
(type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) \
&& sudo mkdir -p -m 755 /etc/apt/keyrings \
&& wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
apt-get update
export DEBIAN_FRONTEND=noninteractive
apt-get -y install --no-install-recommends \
zlib1g-dev \
uuid-dev \
python3-distutils \
python3-pip \
bash-completion \
git-lfs \
gh
# Install Bazel
curl -fSsL -o /usr/local/bin/bazelisk https://github.com/bazelbuild/bazelisk/releases/download/${BAZELISK_VERSION}/bazelisk-linux-amd64
echo "${BAZELISK_DOWNLOAD_SHA} */usr/local/bin/bazelisk" | sha256sum --check -
chmod 0755 /usr/local/bin/bazelisk
ln -s bazelisk /usr/local/bin/bazel
# install latest codeql
update-codeql

View File

@@ -1,20 +0,0 @@
#!/bin/bash -e
URL=https://github.com/github/codeql-cli-binaries/releases
LATEST_VERSION=$(curl -L -s -H 'Accept: application/json' $URL/latest | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
CURRENT_VERSION=v$(codeql version 2>/dev/null | sed -ne 's/.*release \([0-9.]*\)\./\1/p')
if [[ $CURRENT_VERSION != $LATEST_VERSION ]]; then
if [[ $UID != 0 ]]; then
echo "update required, please run this script with sudo:"
echo " sudo $0"
exit 1
fi
ZIP=$(mktemp codeql.XXXX.zip)
curl -fSqL -o $ZIP $URL/download/$LATEST_VERSION/codeql-linux64.zip
unzip -q $ZIP -d /opt
rm $ZIP
ln -sf /opt/codeql/codeql /usr/local/bin/codeql
echo installed version $LATEST_VERSION
else
echo current version $CURRENT_VERSION is up-to-date
fi

View File

@@ -1,15 +0,0 @@
set -xe
git lfs install
# add the workspace to the codeql search path
mkdir -p /home/vscode/.config/codeql
echo "--search-path /workspaces/codeql" > /home/vscode/.config/codeql/config
# create a swift extractor pack with the current state
cd /workspaces/codeql
bazel run swift/create-extractor-pack
#install and set up pre-commit
python3 -m pip install pre-commit --no-warn-script-location
$HOME/.local/bin/pre-commit install

View File

@@ -1,14 +0,0 @@
### Pull Request checklist
#### All query authors
- [ ] A change note is added if necessary. See [the documentation](https://github.com/github/codeql/blob/main/docs/change-notes.md) in this repository.
- [ ] All new queries have appropriate `.qhelp`. See [the documentation](https://github.com/github/codeql/blob/main/docs/query-help-style-guide.md) in this repository.
- [ ] QL tests are added if necessary. See [Testing custom queries](https://docs.github.com/en/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/testing-custom-queries) in the GitHub documentation.
- [ ] New and changed queries have correct query metadata. See [the documentation](https://github.com/github/codeql/blob/main/docs/query-metadata-style-guide.md) in this repository.
#### Internal query authors only
- [ ] Autofixes generated based on these changes are valid, only needed if this PR makes significant changes to `.ql`, `.qll`, or `.qhelp` files. See [the documentation](https://github.com/github/codeql-team/blob/main/docs/best-practices/validating-autofix-for-query-changes.md) (internal access required).
- [ ] Changes are validated [at scale](https://github.com/github/codeql-dca/) (internal access required).
- [ ] Adding a new query? Consider also [adding the query to autofix](https://github.com/github/codeml-autofix/blob/main/docs/updating-query-support.md#adding-a-new-query-to-the-query-suite).

View File

@@ -48,12 +48,6 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: ./swift/actions/build-and-test
build-and-test-linux:
if: github.repository_owner == 'github'
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: ./swift/actions/build-and-test
qltests-macos:
if: ${{ github.repository_owner == 'github' && github.event_name == 'pull_request' }}
needs: build-and-test-macos

View File

@@ -2,10 +2,16 @@ if (($null -ne $env:LGTM_INDEX_INCLUDE) -or ($null -ne $env:LGTM_INDEX_EXCLUDE)
Write-Output 'Path filters set. Passing them through to the JavaScript extractor.'
} else {
Write-Output 'No path filters set. Using the default filters.'
# Note: We're adding the `reusable_workflows` subdirectories to proactively
# record workflows that were called cross-repo, check them out locally,
# and enable an interprocedural analysis across the workflow files.
# These workflows follow the convention `.github/reusable_workflows/<nwo>/*.ya?ml`
$DefaultPathFilters = @(
'exclude:**/*',
'include:.github/workflows/**/*.yml',
'include:.github/workflows/**/*.yaml',
'include:.github/workflows/*.yml',
'include:.github/workflows/*.yaml',
'include:.github/reusable_workflows/**/*.yml',
'include:.github/reusable_workflows/**/*.yaml',
'include:**/action.yml',
'include:**/action.yaml'
)

View File

@@ -2,10 +2,16 @@
set -eu
# Note: We're adding the `reusable_workflows` subdirectories to proactively
# record workflows that were called cross-repo, check them out locally,
# and enable an interprocedural analysis across the workflow files.
# These workflows follow the convention `.github/reusable_workflows/<nwo>/*.ya?ml`
DEFAULT_PATH_FILTERS=$(cat << END
exclude:**/*
include:.github/workflows/**/*.yml
include:.github/workflows/**/*.yaml
include:.github/workflows/*.yml
include:.github/workflows/*.yaml
include:.github/reusable_workflows/**/*.yml
include:.github/reusable_workflows/**/*.yaml
include:**/action.yml
include:**/action.yaml
END

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* Improved `untrustedGhCommandDataModel` regex for `gh pr view` and Bash taint analysis in GitHub Actions.

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* Fixed data for vulnerable versions of `actions/download-artifact` and `rlespinasse/github-slug-action` (following GHSA-cxww-7g56-2vh6 and GHSA-6q4m-7476-932w).

View File

@@ -695,6 +695,19 @@ module Bash {
not varMatchesRegexTest(script, var2, alphaNumericRegex())
)
or
exists(string var2, string value2, string var3, string value3 |
// VAR2=$(cmd)
// VAR3=$VAR2
// echo "FIELD=${VAR3:-default}" >> $GITHUB_ENV (field, file_write_value)
containsCmdSubstitution(value2, cmd) and
script.getAnAssignment(var2, value2) and
containsParameterExpansion(value3, var2, _, _) and
script.getAnAssignment(var3, value3) and
containsParameterExpansion(expr, var3, _, _) and
not varMatchesRegexTest(script, var2, alphaNumericRegex()) and
not varMatchesRegexTest(script, var3, alphaNumericRegex())
)
or
// var reaches the file write directly
// echo "FIELD=$(cmd)" >> $GITHUB_ENV (field, file_write_value)
containsCmdSubstitution(expr, cmd)

View File

@@ -134,6 +134,10 @@ private module Implementation implements CfgShared::InputSig<Location> {
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
predicate isAbnormalExitType(SuccessorType t) { none() }
int idOfAstNode(AstNode node) { none() }
int idOfCfgScope(CfgScope scope) { none() }
}
module CfgImpl = CfgShared::Make<Location, Implementation>;

View File

@@ -7,26 +7,29 @@ extensions:
# PULL REQUESTS
#
# HEAD_REF=$(gh pr view "${{ github.event.issue.number }}" --json headRefName -q '.headRefName')
- ["gh\\s+pr\\b.*\\bview\\b.*\\.headRefName.*", "branch,oneline"]
- ["gh\\s+pr\\b.*\\bview\\b.*\\bheadRefName\\b", "branch,oneline"]
# TITLE=$(gh pr view $PR_NUMBER --json title --jq .title)
- ["gh\\s+pr\\b.*\\bview\\b.*\\.title.*", "title,oneline"]
# TITLE=$(gh pr view $PR_NUMBER --json "title")
- ["gh\\s+pr\\b.*\\bview\\b.*\\btitle\\b", "title,oneline"]
# BODY=$(gh pr view $PR_NUMBER --json body --jq .body)
- ["gh\\s+pr\\b.*\\bview\\b.*\\.body.*", "text,multiline"]
- ["gh\\s+pr\\b.*\\bview\\b.*\\bbody\\b", "text,multiline"]
# COMMENTS="$(gh pr view --repo ${{ github.repository }} "$PR_NUMBER" --json "body,comments" -q '.body, .comments[].body')"
- ["gh\\s+pr\\b.*\\bview\\b.*\\.comments.*", "text,multiline"]
- ["gh\\s+pr\\b.*\\bview\\b.*\\bcomments\\b", "text,multiline"]
# CHANGED_FILES="$(gh pr view --repo ${{ github.repository }} ${{ needs.check-comment.outputs.pull_number }} --json files --jq '.files.[].path')"
- ["gh\\s+pr\\b.*\\bview\\b.*\\.files.*", "filename,multiline"]
- ["gh\\s+pr\\b.*\\bview\\b.*\\bfiles\\b", "filename,multiline"]
# AUTHOR=$(gh pr view ${ORI_PR} -R ${REPO} --json author -q '.author.login')
- ["gh\\s+pr\\b.*\\bview\\b.*\\.author.*", "username,oneline"]
- ["gh\\s+pr\\b.*\\bview\\b.*\\bauthor\\b", "username,oneline"]
#
# ISSUES
#
# TITLE=$(gh issue view "$ISSUE_NUMBER" --json title --jq '.title')
- ["gh\\s+issue\\b.*\\bview\\b.*\\.title.*", "title,oneline"]
# TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,body)
# TITLE=$(gh issue view "$ISSUE_NUMBER" --json "title,body")
- ["gh\\s+issue\\b.*\\bview\\b.*\\btitle\\b", "title,oneline"]
# BODY=$(gh issue view -R ${GITHUB_REPOSITORY} ${ORIGINAL_ISSUE_NUMBER} --json title,body,assignees --jq .body)
- ["gh\\s+issue\\b.*\\bview\\b.*\\.body.*", "text,multiline"]
- ["gh\\s+issue\\b.*\\bview\\b.*\\bbody\\b", "text,multiline"]
# COMMENTS=$(gh issue view "$ISSUE_NUMBER" --json comments --jq '.comments[].body')
- ["gh\\s+issue\\b.*\\bview\\b.*\\.comments.*", "text,multiline"]
- ["gh\\s+issue\\b.*\\bview\\b.*\\bcomments\\b", "text,multiline"]
#
# API
#

View File

@@ -6,38 +6,12 @@ extensions:
# gh api /repos/actions/download-artifact/tags --jq 'map({name: .name, sha: .commit.sha})' --paginate | jq -r '.[] | "- \"\(.name)\", \"\(.sha)\""'
#
# actions/download-artifact
- ["actions/download-artifact", "v4.1.6", "9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395", "4.1.7"]
- ["actions/download-artifact", "v4.1.5", "8caf195ad4b1dee92908e23f56eeb0696f1dd42d", "4.1.7"]
- ["actions/download-artifact", "v4.1.4", "c850b930e6ba138125429b7e5c93fc707a7f8427", "4.1.7"]
- ["actions/download-artifact", "v4.1.3", "87c55149d96e628cc2ef7e6fc2aab372015aec85", "4.1.7"]
- ["actions/download-artifact", "v4.1.2", "eaceaf801fd36c7dee90939fad912460b18a1ffe", "4.1.7"]
- ["actions/download-artifact", "v4.1.1", "6b208ae046db98c579e8a3aa621ab581ff575935", "4.1.7"]
- ["actions/download-artifact", "v4.1.0", "f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110", "4.1.7"]
- ["actions/download-artifact", "v4.0.0", "7a1cd3216ca9260cd8022db641d960b1db4d1be4", "4.1.7"]
- ["actions/download-artifact", "v3.0.2", "9bc31d5ccc31df68ecc42ccf4149144866c47d8a", "4.1.7"]
- ["actions/download-artifact", "v3.0.1", "9782bd6a9848b53b110e712e20e42d89988822b7", "4.1.7"]
- ["actions/download-artifact", "v3.0.0", "fb598a63ae348fa914e94cd0ff38f362e927b741", "4.1.7"]
- ["actions/download-artifact", "v3", "9bc31d5ccc31df68ecc42ccf4149144866c47d8a", "4.1.7"]
- ["actions/download-artifact", "v3-node20", "246d7188e736d3686f6d19628d253ede9697bd55", "4.1.7"]
- ["actions/download-artifact", "v2.1.1", "cbed621e49e4c01b044d60f6c80ea4ed6328b281", "4.1.7"]
- ["actions/download-artifact", "v2.1.0", "f023be2c48cc18debc3bacd34cb396e0295e2869", "4.1.7"]
- ["actions/download-artifact", "v2.0.10", "3be87be14a055c47b01d3bd88f8fe02320a9bb60", "4.1.7"]
- ["actions/download-artifact", "v2.0.9", "158ca71f7c614ae705e79f25522ef4658df18253", "4.1.7"]
- ["actions/download-artifact", "v2.0.8", "4a7a711286f30c025902c28b541c10e147a9b843", "4.1.7"]
- ["actions/download-artifact", "v2.0.7", "f144d3c3916a86f4d6b11ff379d17a49d8f85dbc", "4.1.7"]
- ["actions/download-artifact", "v2.0.6", "f8e41fbffeebb48c0273438d220bb2387727471f", "4.1.7"]
- ["actions/download-artifact", "v2.0.5", "c3f5d00c8784369c43779f3d2611769594a61f7a", "4.1.7"]
- ["actions/download-artifact", "v2.0.4", "b3cedea9bed36890c824f4065163b667eeca272b", "4.1.7"]
- ["actions/download-artifact", "v2.0.3", "80d2d4023c185001eacb50e37afd7dd667ba8044", "4.1.7"]
- ["actions/download-artifact", "v2.0.2", "381af06b4268a1e0ad7b7c7e5a09f1894977120f", "4.1.7"]
- ["actions/download-artifact", "v2.0.1", "1ac47ba4b6af92e65d0438b64ce1ea49ce1cc48d", "4.1.7"]
- ["actions/download-artifact", "v2.0", "1de1dea89c32dcb1f37183c96fe85cfe067b682a", "4.1.7"]
- ["actions/download-artifact", "v2", "cbed621e49e4c01b044d60f6c80ea4ed6328b281", "4.1.7"]
- ["actions/download-artifact", "v1.0.0", "18f0f591fbc635562c815484d73b6e8e3980482e", "4.1.7"]
- ["actions/download-artifact", "v1", "18f0f591fbc635562c815484d73b6e8e3980482e", "4.1.7"]
- ["actions/download-artifact", "1.0.0", "18f0f591fbc635562c815484d73b6e8e3980482e", "4.1.7"]
# https://github.com/advisories/GHSA-cxww-7g56-2vh6 Affected versions: >= 4.0.0, < 4.1.3
- ["actions/download-artifact", "v4.1.2", "eaceaf801fd36c7dee90939fad912460b18a1ffe", "4.1.3"]
- ["actions/download-artifact", "v4.1.1", "6b208ae046db98c579e8a3aa621ab581ff575935", "4.1.3"]
- ["actions/download-artifact", "v4.1.0", "f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110", "4.1.3"]
- ["actions/download-artifact", "v4.0.0", "7a1cd3216ca9260cd8022db641d960b1db4d1be4", "4.1.3"]
# tj-actions/changed-files
# https://github.com/advisories/GHSA-mcph-m25j-8j63
@@ -530,22 +504,13 @@ extensions:
- ["gradle/gradle-build-action", "v1", "b3afdc78a7849557ab26e243ccf07548086da025", "2.4.2"]
# rlespinasse/github-slug-action
# https://github.com/advisories/GHSA-6q4m-7476-932w
# https://github.com/advisories/GHSA-6q4m-7476-932w Affected versions: >= 4.0.0, < 4.4.1
# CVE-2023-27581
- ["rlespinasse/github-slug-action", "v4.4.1", "102b1a064a9b145e56556e22b18b19c624538d94", "4.4.1"]
- ["rlespinasse/github-slug-action", "v4.4.0", "a362e5fb42057a3a23a62218b050838f1bacca5d", "4.4.1"]
- ["rlespinasse/github-slug-action", "v4.3.2", "b011e83cf8cb29e22dda828db30586691ae164e4", "4.4.1"]
- ["rlespinasse/github-slug-action", "v4.3.1", "00198f89920d4454e37e4b27af2b7a8eba79c530", "4.4.1"]
- ["rlespinasse/github-slug-action", "v4.3.0", "9c3571fd3dba541bfdaebc001482a49a1c1f136a", "4.4.1"]
- ["rlespinasse/github-slug-action", "v4.2.5", "0141d9b38d1f21c3b3de63229e20b7b0ad7ef0f4", "4.4.1"]
- ["rlespinasse/github-slug-action", "v3.9.0", "2daab132aa3a6e23ea9d409f9946b3bf6468cc77", "4.4.1"]
- ["rlespinasse/github-slug-action", "v3.8.0", "4a00c29bc1c0a737315b4200af6c6991bb4ace18", "4.4.1"]
- ["rlespinasse/github-slug-action", "v3.7.1", "5150a26d43ce06608443c66efea46fc6f3c50d38", "4.4.1"]
- ["rlespinasse/github-slug-action", "v3.7.0", "ebfc49c0e9cd081acb7ba0634d8d6a711b4c73cf", "4.4.1"]
- ["rlespinasse/github-slug-action", "v3", "2daab132aa3a6e23ea9d409f9946b3bf6468cc77", "4.4.1"]
- ["rlespinasse/github-slug-action", "v3.x", "2daab132aa3a6e23ea9d409f9946b3bf6468cc77", "4.4.1"]
- ["rlespinasse/github-slug-action", "v2.x", "9d2c65418d6ecbbd3c08e686997b30482e9f4a80", "4.4.1"]
- ["rlespinasse/github-slug-action", "v1.1.x", "fbf6d7b9c7af4e8d06135dbc7d774e717d788731", "4.4.1"]
- ["rlespinasse/github-slug-action", "4.2.5", "0141d9b38d1f21c3b3de63229e20b7b0ad7ef0f4", "4.4.1"]
- ["rlespinasse/github-slug-action", "4.2.4", "33cd7a701db9c2baf4ad705d930ade51a9f25c14", "4.4.1"]
- ["rlespinasse/github-slug-action", "4.2.3", "1615fcb48b5315152b3733b7bed1a9f5dfada6e3", "4.4.1"]
@@ -555,25 +520,6 @@ extensions:
- ["rlespinasse/github-slug-action", "4.1.0", "88f3ee8f6f5d1955de92f1fe2fdb301fd40207c6", "4.4.1"]
- ["rlespinasse/github-slug-action", "4.0.1", "cd9871b66e11e9562e3f72469772fe100be4c95a", "4.4.1"]
- ["rlespinasse/github-slug-action", "4.0.0", "bd31a9f564f7930eea1ecfc8d0e6aebc4bc3279f", "4.4.1"]
- ["rlespinasse/github-slug-action", "3.6.1", "1bf76b7bc6ef7dc6ba597ff790f956d9082479d7", "4.4.1"]
- ["rlespinasse/github-slug-action", "3.6.0", "172fe43594a58b5938e248ec757ada60cdb17e18", "4.4.1"]
- ["rlespinasse/github-slug-action", "3.5.1", "016823880d193a56b180527cf7ee52f13c3cfe33", "4.4.1"]
- ["rlespinasse/github-slug-action", "3.5.0", "4060fda2690bcebaabcd86db4fbc8e1c2817c835", "4.4.1"]
- ["rlespinasse/github-slug-action", "3.4.0", "0c099abd978b382cb650281af13913c1905fdd50", "4.4.1"]
- ["rlespinasse/github-slug-action", "3.3.0", "d1880ea5b39f611effb9f3f83f4d35bff34083a6", "4.4.1"]
- ["rlespinasse/github-slug-action", "3.2.0", "c8d8ee50d00177c1e80dd57905fc61f81e437279", "4.4.1"]
- ["rlespinasse/github-slug-action", "3.1.0", "e4699e49fcf890a3172a02c56ba78d867dbb9fd5", "4.4.1"]
- ["rlespinasse/github-slug-action", "3.0.0", "6a873bec5ac11c6d2a11756b8763356da63a8939", "4.4.1"]
- ["rlespinasse/github-slug-action", "2.2.0", "9d2c65418d6ecbbd3c08e686997b30482e9f4a80", "4.4.1"]
- ["rlespinasse/github-slug-action", "2.1.1", "72cfc4cb1f36c102c48541cb59511a6267e89c95", "4.4.1"]
- ["rlespinasse/github-slug-action", "2.1.0", "1172ed1802078eb665a55c252fc180138b907c51", "4.4.1"]
- ["rlespinasse/github-slug-action", "2.0.0", "ca9a67fa1f1126b377a9d80dc1ea354284c71d21", "4.4.1"]
- ["rlespinasse/github-slug-action", "1.2.0", "fbf6d7b9c7af4e8d06135dbc7d774e717d788731", "4.4.1"]
- ["rlespinasse/github-slug-action", "1.1.1", "242e04c2d28ac5db296e5d8203dfd7dc6bcc17a9", "4.4.1"]
- ["rlespinasse/github-slug-action", "1.1.0", "881085bcae8c3443a89cc9401f3e1c60fb014ed2", "4.4.1"]
- ["rlespinasse/github-slug-action", "1.0.2", "a35a1a486a260cfd99c5b6f8c6034a2929ba9b3f", "4.4.1"]
- ["rlespinasse/github-slug-action", "1.0.1", "e46186066296e23235242d0877e2b4fe54003d54", "4.4.1"]
- ["rlespinasse/github-slug-action", "1.0.0", "9671420482a6e4c59c06f2d2d9e0605e941b1287", "4.4.1"]
# Azure/setup-kubectl
# https://github.com/advisories/GHSA-p756-rfxh-x63h

View File

@@ -6,7 +6,7 @@ on:
jobs:
test1:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
outputs:
job_output: ${{ steps.source.outputs.value }}
steps:

View File

@@ -491,7 +491,7 @@ jobs:
send_results:
name: Send results to webhook
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: always()
needs: [
setup,

View File

@@ -106,7 +106,27 @@ jobs:
COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')
echo "comments=$COMMENTS" >> "$GITHUB_OUTPUT"
- run: echo "${{ steps.comments.outputs.comments}}"
pulls3:
runs-on: ubuntu-latest
steps:
- id: title1
run: |
DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")
TITLE=$(echo $DETAILS | jq -r '.title')
echo "title=$TITLE" >> "$GITHUB_OUTPUT"
- run: echo "${{ steps.title1.outputs.title}}"
- id: title2
run: |
TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")
TITLE=$(echo $TITLE | jq -r '.title')
echo "title=$TITLE" >> "$GITHUB_OUTPUT"
- run: echo "${{ steps.title2.outputs.title}}"
- id: title3
run: |
TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)
TITLE=$(echo $TITLE | jq -r '.title')
echo "title=$TITLE" >> "$GITHUB_OUTPUT"
- run: echo "${{ steps.title3.outputs.title}}"

View File

@@ -3,7 +3,7 @@ on:
jobs:
test:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: >
(github.event.workflow_run.event == 'pull_request' ||
github.event.workflow_run.event == 'pull_request_target') &&

View File

@@ -3,7 +3,7 @@ on:
jobs:
test:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Run Issue form parser
id: parse

View File

@@ -128,10 +128,14 @@ edges
| .github/workflows/test9.yml:12:9:20:6 | Uses Step: issue_body_parser_request | .github/workflows/test9.yml:10:17:10:70 | steps.issue_body_parser_request.outputs.payload | provenance | |
| .github/workflows/test9.yml:12:9:20:6 | Uses Step: issue_body_parser_request | .github/workflows/test9.yml:20:20:20:73 | steps.issue_body_parser_request.outputs.payload | provenance | |
| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | provenance | |
| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | provenance | |
| .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | provenance | |
| .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | provenance | |
| .github/workflows/test11.yml:22:9:30:6 | Uses Step | .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | provenance | Config |
| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | provenance | |
| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | provenance | |
| .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | provenance | |
| .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | provenance | |
| .github/workflows/test14.yml:13:9:16:6 | Run Step: changed-files [files] | .github/workflows/test14.yml:16:21:16:60 | steps.changed-files.outputs.files | provenance | |
| .github/workflows/test14.yml:14:14:15:117 | echo "files=$(git diff-tree --no-commit-id --name-only -r ${{ github.sha }} -- docs/)" >> "$GITHUB_OUTPUT"\n | .github/workflows/test14.yml:13:9:16:6 | Run Step: changed-files [files] | provenance | |
| .github/workflows/test14.yml:23:9:27:6 | Run Step: changed-files [files] | .github/workflows/test14.yml:27:21:27:60 | steps.changed-files.outputs.files | provenance | |
@@ -199,6 +203,12 @@ edges
| .github/workflows/test19.yml:100:14:102:48 | BODY=$(gh api /repos/test/test/issues/${{PR_NUMBER}} --jq ".body")\necho "body=$BODY" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:99:9:103:6 | Run Step: body [body] | provenance | |
| .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | provenance | |
| .github/workflows/test19.yml:105:14:107:56 | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | provenance | |
| .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | provenance | |
| .github/workflows/test19.yml:113:14:116:50 | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | provenance | |
| .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | provenance | |
| .github/workflows/test19.yml:119:14:122:50 | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | provenance | |
| .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | provenance | |
| .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | provenance | |
| .github/workflows/test24.yml:8:9:17:6 | Uses Step: parse | .github/workflows/test24.yml:19:17:19:50 | steps.parse.outputs.payload | provenance | |
| .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:12:20:12:50 | steps.parse.outputs.data | provenance | |
| .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:13:20:13:58 | toJSON(steps.parse.outputs.data) | provenance | |
@@ -495,11 +505,15 @@ nodes
| .github/workflows/test10.yml:423:34:423:77 | github.event.workflow_run.head_branch | semmle.label | github.event.workflow_run.head_branch |
| .github/workflows/test10.yml:518:34:518:77 | github.event.workflow_run.head_branch | semmle.label | github.event.workflow_run.head_branch |
| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | semmle.label | Job outputs node [pr_num] |
| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | semmle.label | Job outputs node [ref] |
| .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | semmle.label | steps.set-ref.outputs.pr_num |
| .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | semmle.label | steps.set-ref.outputs.ref |
| .github/workflows/test11.yml:22:9:30:6 | Uses Step | semmle.label | Uses Step |
| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | semmle.label | Run Step: set-ref [pr_num] |
| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | semmle.label | Run Step: set-ref [ref] |
| .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | semmle.label | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n |
| .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | semmle.label | needs.get-artifacts.outputs.pr_num |
| .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | semmle.label | needs.get-artifacts.outputs.ref |
| .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | semmle.label | github.event.pull_request.title \|\| "foo" |
| .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | semmle.label | github.event.changes.body.from |
| .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | semmle.label | github.event.changes.title.from |
@@ -606,6 +620,15 @@ nodes
| .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | semmle.label | Run Step: comments [comments] |
| .github/workflows/test19.yml:105:14:107:56 | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | semmle.label | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n |
| .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | semmle.label | steps.comments.outputs.comments |
| .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | semmle.label | Run Step: title1 [title] |
| .github/workflows/test19.yml:113:14:116:50 | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n |
| .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | semmle.label | steps.title1.outputs.title |
| .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | semmle.label | Run Step: title2 [title] |
| .github/workflows/test19.yml:119:14:122:50 | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n |
| .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | semmle.label | steps.title2.outputs.title |
| .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | semmle.label | Run Step: title3 [title] |
| .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n |
| .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | semmle.label | steps.title3.outputs.title |
| .github/workflows/test21.yml:22:35:22:73 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |
| .github/workflows/test21.yml:23:36:23:74 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |
| .github/workflows/test21.yml:24:50:24:88 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |
@@ -767,6 +790,7 @@ subpaths
| .github/workflows/test9.yml:31:42:31:99 | fromJson(needs.parse-issue.outputs.payload).version | .github/workflows/test9.yml:12:9:20:6 | Uses Step: issue_body_parser_request | .github/workflows/test9.yml:31:42:31:99 | fromJson(needs.parse-issue.outputs.payload).version | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test9.yml:31:42:31:99 | fromJson(needs.parse-issue.outputs.payload).version | ${{ fromJson(needs.parse-issue.outputs.payload).version }} | .github/workflows/test9.yml:4:3:4:15 | issue_comment | issue_comment |
| .github/workflows/test9.yml:39:42:39:72 | github.event.issue.title | .github/workflows/test9.yml:39:42:39:72 | github.event.issue.title | .github/workflows/test9.yml:39:42:39:72 | github.event.issue.title | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test9.yml:39:42:39:72 | github.event.issue.title | ${{ github.event.issue.title }} | .github/workflows/test9.yml:4:3:4:15 | issue_comment | issue_comment |
| .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | .github/workflows/test11.yml:22:9:30:6 | Uses Step | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | ${{ needs.get-artifacts.outputs.pr_num }} | .github/workflows/test11.yml:4:3:4:14 | workflow_run | workflow_run |
| .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | .github/workflows/test11.yml:22:9:30:6 | Uses Step | .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | ${{ needs.get-artifacts.outputs.ref }} | .github/workflows/test11.yml:4:3:4:14 | workflow_run | workflow_run |
| .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | ${{ github.event.pull_request.title \|\| "foo" }} | .github/workflows/test12.yml:4:3:4:21 | pull_request_target | pull_request_target |
| .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | ${{ github.event.changes.body.from }} | .github/workflows/test13.yml:4:3:4:21 | pull_request_target | pull_request_target |
| .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | ${{ github.event.changes.title.from }} | .github/workflows/test13.yml:4:3:4:21 | pull_request_target | pull_request_target |
@@ -807,6 +831,9 @@ subpaths
| .github/workflows/test19.yml:98:21:98:51 | steps.title.outputs.title | .github/workflows/test19.yml:95:14:97:50 | TITLE=$(gh api /repos/test/test/issues/${{PR_NUMBER}} --jq ".title")\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:98:21:98:51 | steps.title.outputs.title | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:98:21:98:51 | steps.title.outputs.title | ${{ steps.title.outputs.title}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target |
| .github/workflows/test19.yml:103:21:103:49 | steps.body.outputs.body | .github/workflows/test19.yml:100:14:102:48 | BODY=$(gh api /repos/test/test/issues/${{PR_NUMBER}} --jq ".body")\necho "body=$BODY" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:103:21:103:49 | steps.body.outputs.body | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:103:21:103:49 | steps.body.outputs.body | ${{ steps.body.outputs.body}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target |
| .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | .github/workflows/test19.yml:105:14:107:56 | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | ${{ steps.comments.outputs.comments}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target |
| .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | .github/workflows/test19.yml:113:14:116:50 | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | ${{ steps.title1.outputs.title}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target |
| .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | .github/workflows/test19.yml:119:14:122:50 | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | ${{ steps.title2.outputs.title}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target |
| .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | ${{ steps.title3.outputs.title}} | .github/workflows/test19.yml:4:3:4:21 | pull_request_target | pull_request_target |
| .github/workflows/test24.yml:19:17:19:50 | steps.parse.outputs.payload | .github/workflows/test24.yml:8:9:17:6 | Uses Step: parse | .github/workflows/test24.yml:19:17:19:50 | steps.parse.outputs.payload | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test24.yml:19:17:19:50 | steps.parse.outputs.payload | ${{ steps.parse.outputs.payload }} | .github/workflows/test24.yml:2:3:2:8 | issues | issues |
| .github/workflows/test25.yml:12:20:12:50 | steps.parse.outputs.data | .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:12:20:12:50 | steps.parse.outputs.data | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test25.yml:12:20:12:50 | steps.parse.outputs.data | ${{ steps.parse.outputs.data }} | .github/workflows/test25.yml:3:5:3:10 | issues | issues |
| .github/workflows/test25.yml:13:20:13:58 | toJSON(steps.parse.outputs.data) | .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:13:20:13:58 | toJSON(steps.parse.outputs.data) | Potential code injection in $@, which may be controlled by an external user ($@). | .github/workflows/test25.yml:13:20:13:58 | toJSON(steps.parse.outputs.data) | ${{ toJSON(steps.parse.outputs.data) }} | .github/workflows/test25.yml:3:5:3:10 | issues | issues |

View File

@@ -128,10 +128,14 @@ edges
| .github/workflows/test9.yml:12:9:20:6 | Uses Step: issue_body_parser_request | .github/workflows/test9.yml:10:17:10:70 | steps.issue_body_parser_request.outputs.payload | provenance | |
| .github/workflows/test9.yml:12:9:20:6 | Uses Step: issue_body_parser_request | .github/workflows/test9.yml:20:20:20:73 | steps.issue_body_parser_request.outputs.payload | provenance | |
| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | provenance | |
| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | provenance | |
| .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | provenance | |
| .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | provenance | |
| .github/workflows/test11.yml:22:9:30:6 | Uses Step | .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | provenance | Config |
| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | provenance | |
| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | provenance | |
| .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | provenance | |
| .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | provenance | |
| .github/workflows/test14.yml:13:9:16:6 | Run Step: changed-files [files] | .github/workflows/test14.yml:16:21:16:60 | steps.changed-files.outputs.files | provenance | |
| .github/workflows/test14.yml:14:14:15:117 | echo "files=$(git diff-tree --no-commit-id --name-only -r ${{ github.sha }} -- docs/)" >> "$GITHUB_OUTPUT"\n | .github/workflows/test14.yml:13:9:16:6 | Run Step: changed-files [files] | provenance | |
| .github/workflows/test14.yml:23:9:27:6 | Run Step: changed-files [files] | .github/workflows/test14.yml:27:21:27:60 | steps.changed-files.outputs.files | provenance | |
@@ -199,6 +203,12 @@ edges
| .github/workflows/test19.yml:100:14:102:48 | BODY=$(gh api /repos/test/test/issues/${{PR_NUMBER}} --jq ".body")\necho "body=$BODY" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:99:9:103:6 | Run Step: body [body] | provenance | |
| .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | provenance | |
| .github/workflows/test19.yml:105:14:107:56 | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | provenance | |
| .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | provenance | |
| .github/workflows/test19.yml:113:14:116:50 | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | provenance | |
| .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | provenance | |
| .github/workflows/test19.yml:119:14:122:50 | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | provenance | |
| .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | provenance | |
| .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | provenance | |
| .github/workflows/test24.yml:8:9:17:6 | Uses Step: parse | .github/workflows/test24.yml:19:17:19:50 | steps.parse.outputs.payload | provenance | |
| .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:12:20:12:50 | steps.parse.outputs.data | provenance | |
| .github/workflows/test25.yml:9:9:12:6 | Uses Step: parse | .github/workflows/test25.yml:13:20:13:58 | toJSON(steps.parse.outputs.data) | provenance | |
@@ -495,11 +505,15 @@ nodes
| .github/workflows/test10.yml:423:34:423:77 | github.event.workflow_run.head_branch | semmle.label | github.event.workflow_run.head_branch |
| .github/workflows/test10.yml:518:34:518:77 | github.event.workflow_run.head_branch | semmle.label | github.event.workflow_run.head_branch |
| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [pr_num] | semmle.label | Job outputs node [pr_num] |
| .github/workflows/test11.yml:19:7:21:4 | Job outputs node [ref] | semmle.label | Job outputs node [ref] |
| .github/workflows/test11.yml:19:16:19:50 | steps.set-ref.outputs.pr_num | semmle.label | steps.set-ref.outputs.pr_num |
| .github/workflows/test11.yml:20:13:20:44 | steps.set-ref.outputs.ref | semmle.label | steps.set-ref.outputs.ref |
| .github/workflows/test11.yml:22:9:30:6 | Uses Step | semmle.label | Uses Step |
| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [pr_num] | semmle.label | Run Step: set-ref [pr_num] |
| .github/workflows/test11.yml:30:9:46:2 | Run Step: set-ref [ref] | semmle.label | Run Step: set-ref [ref] |
| .github/workflows/test11.yml:32:14:44:44 | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n | semmle.label | pr_num=$(jq -r '.pull_request.number' artifacts/event_file/event.json)\nif [ -z "$pr_num" ] \|\| [ "$pr_num" == "null" ]; then\n pr_num=""\nfi\n\nref=$pr_num\nif [ -z "$ref" ] \|\| [ "$ref" == "null" ]; then\n ref=${{ github.ref }}\nfi\n\necho "pr_num=$pr_num" >> $GITHUB_OUTPUT\necho "ref=$ref" >> $GITHUB_OUTPUT\n |
| .github/workflows/test11.yml:54:20:54:60 | needs.get-artifacts.outputs.pr_num | semmle.label | needs.get-artifacts.outputs.pr_num |
| .github/workflows/test11.yml:55:20:55:57 | needs.get-artifacts.outputs.ref | semmle.label | needs.get-artifacts.outputs.ref |
| .github/workflows/test12.yml:10:21:10:67 | github.event.pull_request.title \|\| "foo" | semmle.label | github.event.pull_request.title \|\| "foo" |
| .github/workflows/test13.yml:10:21:10:57 | github.event.changes.body.from | semmle.label | github.event.changes.body.from |
| .github/workflows/test13.yml:11:21:11:58 | github.event.changes.title.from | semmle.label | github.event.changes.title.from |
@@ -606,6 +620,15 @@ nodes
| .github/workflows/test19.yml:104:9:108:6 | Run Step: comments [comments] | semmle.label | Run Step: comments [comments] |
| .github/workflows/test19.yml:105:14:107:56 | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n | semmle.label | COMMENTS=$(gh api /repos/test/test/pulls/${PR_NUMBER}/comments --jq '.[].body')\necho "comments=$COMMENTS" >> "$GITHUB_OUTPUT"\n |
| .github/workflows/test19.yml:108:21:108:57 | steps.comments.outputs.comments | semmle.label | steps.comments.outputs.comments |
| .github/workflows/test19.yml:112:9:117:6 | Run Step: title1 [title] | semmle.label | Run Step: title1 [title] |
| .github/workflows/test19.yml:113:14:116:50 | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | DETAILS=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $DETAILS \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n |
| .github/workflows/test19.yml:117:21:117:52 | steps.title1.outputs.title | semmle.label | steps.title1.outputs.title |
| .github/workflows/test19.yml:118:9:123:6 | Run Step: title2 [title] | semmle.label | Run Step: title2 [title] |
| .github/workflows/test19.yml:119:14:122:50 | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | TITLE=$(gh pr view $PR_NUMBER --json "title,author,headRefName")\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n |
| .github/workflows/test19.yml:123:21:123:52 | steps.title2.outputs.title | semmle.label | steps.title2.outputs.title |
| .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | semmle.label | Run Step: title3 [title] |
| .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n |
| .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | semmle.label | steps.title3.outputs.title |
| .github/workflows/test21.yml:22:35:22:73 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |
| .github/workflows/test21.yml:23:36:23:74 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |
| .github/workflows/test21.yml:24:50:24:88 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |

View File

@@ -7,15 +7,15 @@ jobs:
test1:
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v1
- uses: actions/download-artifact@v1.0.0
- uses: actions/download-artifact@v2
- uses: actions/download-artifact@v2.1.0
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v3.0.2
- uses: actions/download-artifact@v1 # SECURE
- uses: actions/download-artifact@v1.0.0 # SECURE
- uses: actions/download-artifact@v2 # SECURE
- uses: actions/download-artifact@v2.1.0 # SECURE
- uses: actions/download-artifact@v3 # SECURE
- uses: actions/download-artifact@v3.0.2 # SECURE
- uses: actions/download-artifact@v4.1.0
- uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
- uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 # SECURE
- uses: actions/download-artifact@v4 # SECURE
- uses: actions/download-artifact@v4.1.7 # SECURE
- uses: actions/download-artifact@v4.1.8 # SECURE

View File

@@ -1,9 +1,2 @@
| .github/workflows/test1.yml:10:9:11:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:10:9:11:6 | Uses Step | v1 | .github/workflows/test1.yml:10:9:11:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:10:9:11:6 | Uses Step | 4.1.7 |
| .github/workflows/test1.yml:11:9:12:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:11:9:12:6 | Uses Step | v1.0.0 | .github/workflows/test1.yml:11:9:12:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:11:9:12:6 | Uses Step | 4.1.7 |
| .github/workflows/test1.yml:12:9:13:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:12:9:13:6 | Uses Step | v2 | .github/workflows/test1.yml:12:9:13:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:12:9:13:6 | Uses Step | 4.1.7 |
| .github/workflows/test1.yml:13:9:14:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:13:9:14:6 | Uses Step | v2.1.0 | .github/workflows/test1.yml:13:9:14:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:13:9:14:6 | Uses Step | 4.1.7 |
| .github/workflows/test1.yml:14:9:15:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:14:9:15:6 | Uses Step | v3 | .github/workflows/test1.yml:14:9:15:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:14:9:15:6 | Uses Step | 4.1.7 |
| .github/workflows/test1.yml:15:9:16:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:15:9:16:6 | Uses Step | v3.0.2 | .github/workflows/test1.yml:15:9:16:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:15:9:16:6 | Uses Step | 4.1.7 |
| .github/workflows/test1.yml:16:9:17:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:16:9:17:6 | Uses Step | v4.1.0 | .github/workflows/test1.yml:16:9:17:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:16:9:17:6 | Uses Step | 4.1.7 |
| .github/workflows/test1.yml:17:9:18:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:17:9:18:6 | Uses Step | 87c55149d96e628cc2ef7e6fc2aab372015aec85 | .github/workflows/test1.yml:17:9:18:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:17:9:18:6 | Uses Step | 4.1.7 |
| .github/workflows/test1.yml:18:9:19:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:18:9:19:6 | Uses Step | 9bc31d5ccc31df68ecc42ccf4149144866c47d8a | .github/workflows/test1.yml:18:9:19:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:18:9:19:6 | Uses Step | 4.1.7 |
| .github/workflows/test1.yml:16:9:17:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:16:9:17:6 | Uses Step | v4.1.0 | .github/workflows/test1.yml:16:9:17:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:16:9:17:6 | Uses Step | 4.1.3 |
| .github/workflows/test1.yml:17:9:18:6 | Uses Step | The workflow is using a known vulnerable version ($@) of the $@ action. Update it to $@ | .github/workflows/test1.yml:17:9:18:6 | Uses Step | eaceaf801fd36c7dee90939fad912460b18a1ffe | .github/workflows/test1.yml:17:9:18:6 | Uses Step | actions/download-artifact | .github/workflows/test1.yml:17:9:18:6 | Uses Step | 4.1.3 |

View File

@@ -25,7 +25,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4.0.0
with:
name: results
- run: python test.py

View File

@@ -7,7 +7,7 @@ on:
jobs:
test1:
if: github.event.comment.body == '@metabase-bot run visual tests'
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Fetch issue
uses: octokit/request-action@v2.x

View File

@@ -7,7 +7,7 @@ on:
jobs:
test1:
if: github.event.comment.body == '@metabase-bot run visual tests'
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Fetch issue
uses: octokit/request-action@v2.x

View File

@@ -21,9 +21,9 @@ jobs:
matrix:
include:
- language: javascript
os: ubuntu-22.04
os: ubuntu-24.04
- language: ruby
os: ubuntu-22.04-16core
os: ubuntu-24.04-16core
steps:
- name: Checkout repository

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
description: Mix typedefs and usings
compatibility: full
usertypes.rel: run usertypes.qlo
usertype_alias_kind.rel: delete

View File

@@ -0,0 +1,20 @@
class UserType extends @usertype {
string toString() { none() }
}
int getTyperefKind(UserType usertype) {
usertype_alias_kind(usertype, 0) and
result = 5
or
usertype_alias_kind(usertype, 1) and
result = 14
}
bindingset[kind]
int getKind(UserType usertype, int kind) {
if kind = 18 then result = getTyperefKind(usertype) else result = kind
}
from UserType usertype, string name, int kind
where usertypes(usertype, name, kind)
select usertype, name, getKind(usertype, kind)

View File

@@ -0,0 +1,4 @@
---
category: breaking
---
* Deleted the deprecated `getAllocatorCall` predicate from `DeleteOrDeleteArrayExpr`, use `getDeallocatorCall` instead.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* A new predicate `getOffsetInClass` was added to the `Field` class, which computes the byte offset of a field relative to a given `Class`.

View File

@@ -87,11 +87,11 @@ module LiteralAlgorithmTracerConfig implements DataFlow::ConfigSig {
// False positives in OpenSSL also observed for CRYPTO_strndup (filtering any CRYPTO_* function)
// due to setting a null byte in the string
(
isPossibleOpenSSLFunction(source.getEnclosingCallable())
isPossibleOpenSSLFunction(source.getFunction())
implies
(
not source.getEnclosingCallable().getName().matches("OBJ_%") and
not source.getEnclosingCallable().getName().matches("CRYPTO_%")
not source.getFunction().getName().matches("OBJ_%") and
not source.getFunction().getName().matches("CRYPTO_%")
)
)
}

View File

@@ -5,6 +5,30 @@
import semmle.code.cpp.Variable
import semmle.code.cpp.Enum
private predicate hasAFieldWithOffset(Class c, Field f, int offset) {
// Base case: `f` is a field in `c`.
f = c.getAField() and
offset = f.getByteOffset() and
not f.getUnspecifiedType().(Class).hasDefinition()
or
// Otherwise, we find the struct that is a field of `c` which then has
// the field `f` as a member.
exists(Field g |
g = c.getAField() and
// Find the field with the largest offset that's less than or equal to
// offset. That's the struct we need to search recursively.
g =
max(Field cand, int candOffset |
cand = c.getAField() and
candOffset = cand.getByteOffset() and
offset >= candOffset
|
cand order by candOffset
) and
hasAFieldWithOffset(g.getUnspecifiedType(), f, offset - g.getByteOffset())
)
}
/**
* A C structure member or C++ non-static member variable. For example the
* member variable `m` in the following code (but not `s`):
@@ -76,6 +100,27 @@ class Field extends MemberVariable {
rank[result + 1](int index | cls.getCanonicalMember(index).(Field).isInitializable())
)
}
/**
* Gets the offset (in bytes) of this field starting at `c`.
*
* For example, consider:
* ```cpp
* struct S1 {
* int a;
* void* b;
* };
*
* struct S2 {
* S1 s1;
* char c;
* };
* ```
* If `f` represents the field `s1` and `c` represents the class `S2` then
* `f.getOffsetInClass(S2) = 0` holds. Likewise, if `f` represents the
* field `a`, then `f.getOffsetInClass(c) = 0` holds.
*/
int getOffsetInClass(Class c) { hasAFieldWithOffset(c, this, result) }
}
/**

View File

@@ -13,7 +13,7 @@ private import semmle.code.cpp.internal.ResolveClass
* ```
*/
class TypedefType extends UserType {
TypedefType() { usertypes(underlyingElement(this), _, [5, 14]) }
TypedefType() { usertypes(underlyingElement(this), _, 18) }
/**
* Gets the base type of this typedef type.
@@ -54,7 +54,7 @@ class TypedefType extends UserType {
* ```
*/
class CTypedefType extends TypedefType {
CTypedefType() { usertypes(underlyingElement(this), _, 5) }
CTypedefType() { usertype_alias_kind(underlyingElement(this), 0) }
override string getAPrimaryQlClass() { result = "CTypedefType" }
@@ -70,7 +70,7 @@ class CTypedefType extends TypedefType {
* ```
*/
class UsingAliasTypedefType extends TypedefType {
UsingAliasTypedefType() { usertypes(underlyingElement(this), _, 14) }
UsingAliasTypedefType() { usertype_alias_kind(underlyingElement(this), 1) }
override string getAPrimaryQlClass() { result = "UsingAliasTypedefType" }

View File

@@ -47,10 +47,16 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
else result = this.getADeclarationLocation()
}
pragma[nomagic]
private TypeDeclarationEntry getADeclarationEntryBase() {
type_decls(underlyingElement(result), unresolveElement(this), _)
}
override TypeDeclarationEntry getADeclarationEntry() {
if type_decls(_, unresolveElement(this), _)
then type_decls(underlyingElement(result), unresolveElement(this), _)
else exists(Class t | this.(Class).isConstructedFrom(t) and result = t.getADeclarationEntry())
pragma[only_bind_into](result) = pragma[only_bind_into](this).getADeclarationEntryBase()
or
not exists(this.getADeclarationEntryBase()) and
exists(Class t | this.(Class).isConstructedFrom(t) and result = t.getADeclarationEntry())
}
override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }

View File

@@ -24,6 +24,74 @@ predicate memberMayBeVarSize(Class c, MemberVariable v) {
exists(ArrayType t | t = v.getUnspecifiedType() | not t.getArraySize() > 1)
}
/**
* Given a chain of accesses of the form `x.f1.f2...fn` this
* predicate gives the type of `x`. Note that `x` may be an implicit
* `this` expression.
*/
private Class getRootType(FieldAccess fa) {
// If the object is accessed inside a member function then the root will
// be a(n implicit) `this`. And the root type will be the type of `this`.
exists(VariableAccess root |
root = fa.getQualifier*() and
result =
root.getQualifier()
.(ThisExpr)
.getUnspecifiedType()
.(PointerType)
.getBaseType()
.getUnspecifiedType()
)
or
// Otherwise, if this is not inside a member function there will not be
// a(n implicit) `this`. And the root type is the type of the outermost
// access.
exists(VariableAccess root |
root = fa.getQualifier+() and
not exists(root.getQualifier()) and
result = root.getUnspecifiedType()
)
}
/**
* Gets the size of the buffer access at `va`.
*/
private int getSize(VariableAccess va) {
exists(Variable v | va.getTarget() = v |
// If `v` is not a field then the size of the buffer is just
// the size of the type of `v`.
exists(Type t |
t = v.getUnspecifiedType() and
not v instanceof Field and
not t instanceof ReferenceType and
result = t.getSize()
)
or
exists(Class c |
// Otherwise, we find the "outermost" object and compute the size
// as the difference between the size of the type of the "outermost
// object" and the offset of the field relative to that type.
// For example, consider the following structs:
// ```
// struct S {
// uint32_t x;
// uint32_t y;
// };
// struct S2 {
// S s;
// uint32_t z;
// };
// ```
// Given an object `S2 s2` the size of the buffer `&s2.s.y`
// is the size of the base object type (i.e., `S2`) minutes the offset
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
// buffer is `12 - 4 = 8`.
c = getRootType(va) and
result = c.getSize() - v.(Field).getOffsetInClass(c)
)
)
}
/**
* Holds if `bufferExpr` is an allocation-like expression.
*
@@ -54,22 +122,11 @@ private int isSource(Expr bufferExpr, Element why) {
result = bufferExpr.(AllocationExpr).getSizeBytes() and
why = bufferExpr
or
exists(Type bufferType |
exists(Variable v |
v = why and
// buffer is the address of a variable
why = bufferExpr.(AddressOfExpr).getAddressable() and
bufferType = why.(Variable).getUnspecifiedType() and
result = bufferType.getSize() and
not bufferType instanceof ReferenceType and
not any(Union u).getAMemberVariable() = why
)
or
exists(Union bufferType |
// buffer is the address of a union member; in this case, we
// take the size of the union itself rather the union member, since
// it's usually OK to access that amount (e.g. clearing with memset).
why = bufferExpr.(AddressOfExpr).getAddressable() and
bufferType.getAMemberVariable() = why and
result = bufferType.getSize()
result = getSize(bufferExpr.(AddressOfExpr).getOperand())
)
}

View File

@@ -102,49 +102,76 @@ abstract private class GuardConditionImpl extends Expr {
this.valueControls(controlled, any(BooleanValue bv | bv.getValue() = testIsTrue))
}
/** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */
/**
* Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this
* expression evaluates to `testIsTrue`. Note that there's a 4-argument
* ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`).
*/
pragma[inline]
abstract predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue);
/**
* Holds if (determined by this guard) `left < right + k` must be `isLessThan` in `block`.
* If `isLessThan = false` then this implies `left >= right + k`.
* If `isLessThan = false` then this implies `left >= right + k`. Note that there's a 4-argument
* ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`).
*/
pragma[inline]
abstract predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan);
/**
* Holds if (determined by this guard) `e < k` evaluates to `isLessThan` if
* this expression evaluates to `value`.
* this expression evaluates to `value`. Note that there's a 4-argument
* ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`).
*/
pragma[inline]
abstract predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value);
/**
* Holds if (determined by this guard) `e < k` must be `isLessThan` in `block`.
* If `isLessThan = false` then this implies `e >= k`.
* If `isLessThan = false` then this implies `e >= k`. Note that there's a 4-argument
* ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`).
*/
pragma[inline]
abstract predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan);
/** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
/**
* Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this
* expression evaluates to `testIsTrue`. Note that there's a 4-argument ("unary") and a
* 5-argument ("binary") version of `comparesEq` and they are not equivalent:
* - the unary version is suitable for guards where there is no expression representing the
* right-hand side, such as `if (x)`, and also works for equality with an integer constant
* (such as `if (x == k)`).
* - the binary version is the more general case for comparison of any expressions (not
* necessarily integer).
*/
pragma[inline]
abstract predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue);
/**
* Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`.
* If `areEqual = false` then this implies `left != right + k`.
* If `areEqual = false` then this implies `left != right + k`. Note that there's a 4-argument
* ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`).
*/
pragma[inline]
abstract predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual);
/** Holds if (determined by this guard) `e == k` evaluates to `areEqual` if this expression evaluates to `value`. */
/**
* Holds if (determined by this guard) `e == k` evaluates to `areEqual` if this expression
* evaluates to `value`. Note that there's a 4-argument ("unary") and a 5-argument ("binary")
* version of `comparesEq` and they are not equivalent:
* - the unary version is suitable for guards where there is no expression representing the
* right-hand side, such as `if (x)`, and also works for equality with an integer constant
* (such as `if (x == k)`).
* - the binary version is the more general case for comparison of any expressions (not
* necessarily integer).
*/
pragma[inline]
abstract predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value);
/**
* Holds if (determined by this guard) `e == k` must be `areEqual` in `block`.
* If `areEqual = false` then this implies `e != k`.
* If `areEqual = false` then this implies `e != k`. Note that there's a 4-argument
* ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`).
*/
pragma[inline]
abstract predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual);
@@ -981,7 +1008,8 @@ private module Cached {
or
exists(CompareValueNumber cmp, Operand left, Operand right, AbstractValue v |
test = cmp and
cmp.hasOperands(left, right) and
pragma[only_bind_into](cmp)
.hasOperands(pragma[only_bind_into](left), pragma[only_bind_into](right)) and
isConvertedBool(left.getDef()) and
int_value(right.getDef()) = 0 and
unary_compares_eq(valueNumberOfOperand(left), op, k, areEqual, v)

View File

@@ -1110,11 +1110,6 @@ class DeleteOrDeleteArrayExpr extends Expr, TDeleteOrDeleteArrayExpr {
expr_deallocator(underlyingElement(this), unresolveElement(result), _)
}
/**
* DEPRECATED: use `getDeallocatorCall` instead.
*/
deprecated FunctionCall getAllocatorCall() { result = this.getChild(0) }
/**
* Gets the call to a non-default `operator delete`/`delete[]` that deallocates storage, if any.
*

View File

@@ -152,7 +152,7 @@ private module VirtualDispatch {
ReturnNode node, ReturnKind kind, DataFlowCallable callable
) {
node.getKind() = kind and
node.getEnclosingCallable() = callable.getUnderlyingCallable()
node.getFunction() = callable.getUnderlyingCallable()
}
/** Call through a function pointer. */

View File

@@ -333,9 +333,7 @@ private module IndirectInstructions {
import IndirectInstructions
/** Gets the callable in which this node occurs. */
DataFlowCallable nodeGetEnclosingCallable(Node n) {
result.getUnderlyingCallable() = n.getEnclosingCallable()
}
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
@@ -1012,9 +1010,7 @@ class CastNode extends Node {
cached
private newtype TDataFlowCallable =
TSourceCallable(Cpp::Declaration decl) {
not decl instanceof FlowSummaryImpl::Public::SummarizedCallable
} or
TSourceCallable(Cpp::Declaration decl) or
TSummarizedCallable(FlowSummaryImpl::Public::SummarizedCallable c)
/**
@@ -1127,7 +1123,21 @@ class DataFlowCall extends TDataFlowCall {
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
DataFlowCallable getStaticCallTarget() { none() }
Function getStaticCallSourceTarget() { none() }
/**
* Gets the target of this call. If a summarized callable exists for the
* target this is chosen, and otherwise the callable is the implementation
* from the source code.
*/
DataFlowCallable getStaticCallTarget() {
exists(Function target | target = this.getStaticCallSourceTarget() |
not exists(TSummarizedCallable(target)) and
result.asSourceCallable() = target
or
result.asSummarizedCallable() = target
)
}
/**
* Gets the `index`'th argument operand. The qualifier is considered to have index `-1`.
@@ -1173,14 +1183,12 @@ private class NormalCall extends DataFlowCall, TNormalCall {
override CallTargetOperand getCallTargetOperand() { result = call.getCallTargetOperand() }
override DataFlowCallable getStaticCallTarget() {
result.getUnderlyingCallable() = call.getStaticCallTarget()
}
override Function getStaticCallSourceTarget() { result = call.getStaticCallTarget() }
override ArgumentOperand getArgumentOperand(int index) { result = call.getArgumentOperand(index) }
override DataFlowCallable getEnclosingCallable() {
result.getUnderlyingCallable() = call.getEnclosingFunction()
result.asSourceCallable() = call.getEnclosingFunction()
}
override string toString() { result = call.toString() }
@@ -1331,7 +1339,12 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
(
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode() or
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode()
or
// No need to infer a lambda call if we already have a static dispatch target.
// We only need to check this in the disjunct since a `SummaryCall` never
// has a result for `getStaticCallTarget`.
not exists(call.getStaticCallTarget()) and
call.asCallInstruction().getCallTargetOperand() = receiver.asOperand()
) and
exists(kind)

View File

@@ -146,7 +146,7 @@ class Node extends TIRDataFlowNode {
/**
* INTERNAL: Do not use.
*/
Declaration getEnclosingCallable() { none() } // overridden in subclasses
DataFlowCallable getEnclosingCallable() { none() } // overridden in subclasses
/** Gets the function to which this node belongs, if any. */
Declaration getFunction() { none() } // overridden in subclasses
@@ -508,7 +508,9 @@ private class Node0 extends Node, TNode0 {
Node0() { this = TNode0(node) }
override Declaration getEnclosingCallable() { result = node.getEnclosingCallable() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = node.getEnclosingCallable()
}
override Declaration getFunction() { result = node.getFunction() }
@@ -573,7 +575,9 @@ class PostUpdateNodeImpl extends PartialDefinitionNode, TPostUpdateNodeImpl {
override Declaration getFunction() { result = operand.getUse().getEnclosingFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result = this.getPreUpdateNode().getEnclosingCallable()
}
/** Gets the operand associated with this node. */
Operand getOperand() { result = operand }
@@ -626,7 +630,9 @@ class SsaPhiNode extends Node, TSsaPhiNode {
/** Gets the phi node associated with this node. */
Ssa::PhiNode getPhiNode() { result = phi }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
@@ -709,7 +715,9 @@ class SsaPhiInputNode extends Node, TSsaPhiInputNode {
/** Gets the basic block in which this input originates. */
IRBlock getBlock() { result = block }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
@@ -738,7 +746,9 @@ class SsaIteratorNode extends Node, TSsaIteratorNode {
/** Gets the phi node associated with this node. */
IteratorFlow::IteratorFlowNode getIteratorFlowNode() { result = node }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = node.getFunction() }
@@ -773,7 +783,9 @@ class SideEffectOperandNode extends Node instanceof IndirectOperand {
int getArgumentIndex() { result = argumentIndex }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = call.getEnclosingFunction() }
@@ -794,7 +806,9 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
/** Gets the underlying SSA use. */
Ssa::GlobalUse getGlobalUse() { result = globalUse }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = globalUse.getIRFunction().getFunction() }
@@ -824,7 +838,9 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
/** Gets the underlying SSA definition. */
Ssa::GlobalDef getGlobalDef() { result = globalDef }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = globalDef.getIRFunction().getFunction() }
@@ -855,7 +871,9 @@ class BodyLessParameterNodeImpl extends Node, TBodyLessParameterNodeImpl {
BodyLessParameterNodeImpl() { this = TBodyLessParameterNodeImpl(p, indirectionIndex) }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = p.getFunction() }
@@ -901,7 +919,9 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
* Gets the enclosing callable. For a `FlowSummaryNode` this is always the
* summarized function this node is part of.
*/
override Declaration getEnclosingCallable() { result = this.getSummarizedCallable() }
override DataFlowCallable getEnclosingCallable() {
result.asSummarizedCallable() = this.getSummarizedCallable()
}
override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() }
@@ -922,7 +942,7 @@ class IndirectReturnNode extends Node {
.hasOperandAndIndirectionIndex(any(ReturnValueInstruction ret).getReturnAddressOperand(), _)
}
override Declaration getEnclosingCallable() { result = this.getFunction() }
override SourceCallable getEnclosingCallable() { result.asSourceCallable() = this.getFunction() }
/**
* Holds if this node represents the value that is returned to the caller
@@ -1116,11 +1136,11 @@ private module RawIndirectNodes {
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
override Declaration getFunction() {
result = this.getOperand().getDef().getEnclosingFunction()
}
override Declaration getFunction() { result = node.getFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = node.getEnclosingCallable()
}
override predicate isGLValue() { this.getOperand().isGLValue() }
@@ -1162,9 +1182,11 @@ private module RawIndirectNodes {
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() }
override Declaration getFunction() { result = node.getFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = node.getEnclosingCallable()
}
override predicate isGLValue() { this.getInstruction().isGLValue() }
@@ -1264,7 +1286,9 @@ class FinalParameterNode extends Node, TFinalParameterNode {
override Declaration getFunction() { result = p.getFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override DataFlowType getType() { result = getTypeImpl(p.getUnderlyingType(), indirectionIndex) }
@@ -1306,7 +1330,29 @@ abstract private class AbstractParameterNode extends Node {
* implicit `this` parameter is considered to have position `-1`, and
* pointer-indirection parameters are at further negative positions.
*/
abstract predicate isParameterOf(DataFlowCallable f, ParameterPosition pos);
predicate isSourceParameterOf(Function f, ParameterPosition pos) { none() }
/**
* Holds if this node is the parameter of `sc` at the specified position. The
* implicit `this` parameter is considered to have position `-1`, and
* pointer-indirection parameters are at further negative positions.
*/
predicate isSummaryParameterOf(
FlowSummaryImpl::Public::SummarizedCallable sc, ParameterPosition pos
) {
none()
}
/**
* Holds if this node is the parameter of `c` at the specified position. The
* implicit `this` parameter is considered to have position `-1`, and
* pointer-indirection parameters are at further negative positions.
*/
final predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.isSummaryParameterOf(c.asSummarizedCallable(), pos)
or
this.isSourceParameterOf(c.asSourceCallable(), pos)
}
/** Gets the `Parameter` associated with this node, if it exists. */
Parameter getParameter() { none() } // overridden by subclasses
@@ -1362,12 +1408,14 @@ private class IndirectInstructionParameterNode extends AbstractIndirectParameter
/** Gets the parameter whose indirection is initialized. */
override Parameter getParameter() { result = init.getParameter() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = init.getEnclosingFunction() }
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
this.getEnclosingCallable() = f.getUnderlyingCallable() and
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
this.getFunction() = f and
exists(int argumentIndex, int indirectionIndex |
indirectPositionHasArgumentIndexAndIndex(pos, argumentIndex, indirectionIndex) and
indirectParameterNodeHasArgumentIndexAndIndex(this, argumentIndex, indirectionIndex)
@@ -1424,9 +1472,8 @@ private class ExplicitParameterInstructionNode extends AbstractExplicitParameter
{
ExplicitParameterInstructionNode() { exists(instr.getParameter()) }
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
f.getUnderlyingCallable().(Function).getParameter(pos.(DirectPosition).getIndex()) =
instr.getParameter()
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
f.getParameter(pos.(DirectPosition).getIndex()) = instr.getParameter()
}
override string toStringImpl() { result = instr.getParameter().toString() }
@@ -1440,9 +1487,9 @@ class ThisParameterInstructionNode extends AbstractExplicitParameterNode,
{
ThisParameterInstructionNode() { instr.getIRVariable() instanceof IRThisVariable }
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
pos.(DirectPosition).getIndex() = -1 and
instr.getEnclosingFunction() = f.getUnderlyingCallable()
instr.getEnclosingFunction() = f
}
override string toStringImpl() { result = "this" }
@@ -1460,8 +1507,10 @@ class SummaryParameterNode extends AbstractParameterNode, FlowSummaryNode {
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result)
}
override predicate isParameterOf(DataFlowCallable c, ParameterPosition p) {
c.getUnderlyingCallable() = this.getSummarizedCallable() and
override predicate isSummaryParameterOf(
FlowSummaryImpl::Public::SummarizedCallable c, ParameterPosition p
) {
c = this.getSummarizedCallable() and
p = this.getPosition()
}
}
@@ -1471,12 +1520,9 @@ private class DirectBodyLessParameterNode extends AbstractExplicitParameterNode,
{
DirectBodyLessParameterNode() { indirectionIndex = 0 }
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
exists(Function func |
this.getFunction() = func and
f.asSourceCallable() = func and
func.getParameter(pos.(DirectPosition).getIndex()) = p
)
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
this.getFunction() = f and
f.getParameter(pos.(DirectPosition).getIndex()) = p
}
override Parameter getParameter() { result = p }
@@ -1487,12 +1533,11 @@ private class IndirectBodyLessParameterNode extends AbstractIndirectParameterNod
{
IndirectBodyLessParameterNode() { not this instanceof DirectBodyLessParameterNode }
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
exists(Function func, int argumentPosition |
this.getFunction() = func and
f.asSourceCallable() = func and
indirectPositionHasArgumentIndexAndIndex(pos, argumentPosition, indirectionIndex) and
func.getParameter(argumentPosition) = p
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
exists(int argumentPosition |
this.getFunction() = f and
f.getParameter(argumentPosition) = p and
indirectPositionHasArgumentIndexAndIndex(pos, argumentPosition, indirectionIndex)
)
}
@@ -1605,13 +1650,13 @@ class VariableNode extends Node, TGlobalLikeVariableNode {
override Declaration getFunction() { none() }
override Declaration getEnclosingCallable() {
override DataFlowCallable getEnclosingCallable() {
// When flow crosses from one _enclosing callable_ to another, the
// interprocedural data-flow library discards call contexts and inserts a
// node in the big-step relation used for human-readable path explanations.
// Therefore we want a distinct enclosing callable for each `VariableNode`,
// and that can be the `Variable` itself.
result = v
result.asSourceCallable() = v
}
override DataFlowType getType() {

View File

@@ -587,8 +587,8 @@ module ProductFlow {
pragma[nomagic]
private predicate interprocEdge1(
Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1,
TKind kind
DataFlowCallable predDecl, DataFlowCallable succDecl, Flow1::PathNode pred1,
Flow1::PathNode succ1, TKind kind
) {
Flow1::PathGraph::edges(pred1, succ1, _, _) and
predDecl != succDecl and
@@ -607,8 +607,8 @@ module ProductFlow {
pragma[nomagic]
private predicate interprocEdge2(
Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2,
TKind kind
DataFlowCallable predDecl, DataFlowCallable succDecl, Flow2::PathNode pred2,
Flow2::PathNode succ2, TKind kind
) {
Flow2::PathGraph::edges(pred2, succ2, _, _) and
predDecl != succDecl and
@@ -628,7 +628,7 @@ module ProductFlow {
private predicate interprocEdgePair(
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode succ1, Flow2::PathNode succ2
) {
exists(Declaration predDecl, Declaration succDecl, TKind kind |
exists(DataFlowCallable predDecl, DataFlowCallable succDecl, TKind kind |
interprocEdge1(predDecl, succDecl, pred1, succ1, kind) and
interprocEdge2(predDecl, succDecl, pred2, succ2, kind)
)

View File

@@ -1,5 +1,6 @@
import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
@@ -8,7 +9,7 @@ import semmle.code.cpp.models.interfaces.SideEffect
* guaranteed to be side-effect free.
*/
private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction,
SideEffectFunction
SideEffectFunction, DataFlowFunction
{
PureStrFunction() {
this.hasGlobalOrStdOrBslName([
@@ -25,23 +26,48 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
}
/** Holds if `i` is a locale parameter that does not carry taint. */
private predicate isLocaleParameter(ParameterIndex i) {
this.getName().matches("%\\_l") and i + 1 = this.getNumberOfParameters()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// For these functions we add taint flow according to the following rules:
// 1. If the parameter is of a pointer type then there is taint from the
// indirection of the parameter. Otherwise, there is taint from the
// parameter.
// 2. If the return value is of a pointer type then there is taint to the
// indirection of the return. Otherwise, there is taint to the return.
exists(ParameterIndex i |
(
input.isParameter(i) and
exists(this.getParameter(i))
or
input.isParameterDeref(i) and
this.getParameter(i).getUnspecifiedType() instanceof PointerType
) and
exists(this.getParameter(i)) and
// Functions that end with _l also take a locale argument (always as the last argument),
// and we don't want taint from those arguments.
(not this.getName().matches("%\\_l") or exists(this.getParameter(i + 1)))
not this.isLocaleParameter(i)
|
if this.getParameter(i).getUnspecifiedType() instanceof PointerType
then input.isParameterDeref(i)
else input.isParameter(i)
) and
(
output.isReturnValueDeref() and
this.getUnspecifiedType() instanceof PointerType
or
if this.getUnspecifiedType() instanceof PointerType
then output.isReturnValueDeref()
else output.isReturnValue()
)
or
// If there is taint flow from *input to *output then there is also taint
// flow from input to output.
this.hasTaintFlow(input.getIndirectionInput(), output.getIndirectionOutput()) and
// No need to add taint flow if we already have data flow.
not this.hasDataFlow(input, output)
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
exists(int i |
input.isParameter(i) and
not this.isLocaleParameter(i) and
// These functions always return the same pointer as they are given
this.hasGlobalOrStdOrBslName([strrev(), strlwr(), strupr()]) and
this.getParameter(i).getUnspecifiedType() instanceof PointerType and
output.isReturnValue()
)
}

View File

@@ -148,119 +148,81 @@ class HashCons extends HCBase {
/** Gets the kind of the HC. This can be useful for debugging. */
string getKind() {
if this instanceof HC_IntLiteral
then result = "IntLiteral"
else
if this instanceof HC_EnumConstantAccess
then result = "EnumConstantAccess"
else
if this instanceof HC_FloatLiteral
then result = "FloatLiteral"
else
if this instanceof HC_StringLiteral
then result = "StringLiteral"
else
if this instanceof HC_Nullptr
then result = "Nullptr"
else
if this instanceof HC_Variable
then result = "Variable"
else
if this instanceof HC_FieldAccess
then result = "FieldAccess"
else
if this instanceof HC_Deref
then result = "Deref"
else
if this instanceof HC_ThisExpr
then result = "ThisExpr"
else
if this instanceof HC_Conversion
then result = "Conversion"
else
if this instanceof HC_BinaryOp
then result = "BinaryOp"
else
if this instanceof HC_UnaryOp
then result = "UnaryOp"
else
if this instanceof HC_ArrayAccess
then result = "ArrayAccess"
else
if this instanceof HC_Unanalyzable
then result = "Unanalyzable"
else
if this instanceof HC_NonmemberFunctionCall
then result = "NonmemberFunctionCall"
else
if this instanceof HC_MemberFunctionCall
then result = "MemberFunctionCall"
else
if this instanceof HC_NewExpr
then result = "NewExpr"
else
if this instanceof HC_NewArrayExpr
then result = "NewArrayExpr"
else
if this instanceof HC_SizeofType
then result = "SizeofTypeOperator"
else
if this instanceof HC_SizeofExpr
then result = "SizeofExprOperator"
else
if this instanceof HC_AlignofType
then result = "AlignofTypeOperator"
else
if this instanceof HC_AlignofExpr
then result = "AlignofExprOperator"
else
if this instanceof HC_UuidofOperator
then result = "UuidofOperator"
else
if this instanceof HC_TypeidType
then result = "TypeidType"
else
if this instanceof HC_TypeidExpr
then result = "TypeidExpr"
else
if this instanceof HC_ArrayAggregateLiteral
then result = "ArrayAggregateLiteral"
else
if this instanceof HC_ClassAggregateLiteral
then result = "ClassAggregateLiteral"
else
if this instanceof HC_DeleteExpr
then result = "DeleteExpr"
else
if this instanceof HC_DeleteArrayExpr
then result = "DeleteArrayExpr"
else
if this instanceof HC_ThrowExpr
then result = "ThrowExpr"
else
if this instanceof HC_ReThrowExpr
then result = "ReThrowExpr"
else
if this instanceof HC_ExprCall
then result = "ExprCall"
else
if
this instanceof
HC_ConditionalExpr
then result = "ConditionalExpr"
else
if
this instanceof
HC_NoExceptExpr
then result = "NoExceptExpr"
else
if
this instanceof
HC_AllocatorArgZero
then
result =
"AllocatorArgZero"
else result = "error"
result = this.getKind0()
or
not exists(this.getKind0()) and result = "error"
}
private string getKind0() {
this instanceof HC_IntLiteral and result = "IntLiteral"
or
this instanceof HC_EnumConstantAccess and result = "EnumConstantAccess"
or
this instanceof HC_FloatLiteral and result = "FloatLiteral"
or
this instanceof HC_StringLiteral and result = "StringLiteral"
or
this instanceof HC_Nullptr and result = "Nullptr"
or
this instanceof HC_Variable and result = "Variable"
or
this instanceof HC_FieldAccess and result = "FieldAccess"
or
this instanceof HC_Deref and result = "Deref"
or
this instanceof HC_ThisExpr and result = "ThisExpr"
or
this instanceof HC_Conversion and result = "Conversion"
or
this instanceof HC_BinaryOp and result = "BinaryOp"
or
this instanceof HC_UnaryOp and result = "UnaryOp"
or
this instanceof HC_ArrayAccess and result = "ArrayAccess"
or
this instanceof HC_Unanalyzable and result = "Unanalyzable"
or
this instanceof HC_NonmemberFunctionCall and result = "NonmemberFunctionCall"
or
this instanceof HC_MemberFunctionCall and result = "MemberFunctionCall"
or
this instanceof HC_NewExpr and result = "NewExpr"
or
this instanceof HC_NewArrayExpr and result = "NewArrayExpr"
or
this instanceof HC_SizeofType and result = "SizeofTypeOperator"
or
this instanceof HC_SizeofExpr and result = "SizeofExprOperator"
or
this instanceof HC_AlignofType and result = "AlignofTypeOperator"
or
this instanceof HC_AlignofExpr and result = "AlignofExprOperator"
or
this instanceof HC_UuidofOperator and result = "UuidofOperator"
or
this instanceof HC_TypeidType and result = "TypeidType"
or
this instanceof HC_TypeidExpr and result = "TypeidExpr"
or
this instanceof HC_ArrayAggregateLiteral and result = "ArrayAggregateLiteral"
or
this instanceof HC_ClassAggregateLiteral and result = "ClassAggregateLiteral"
or
this instanceof HC_DeleteExpr and result = "DeleteExpr"
or
this instanceof HC_DeleteArrayExpr and result = "DeleteArrayExpr"
or
this instanceof HC_ThrowExpr and result = "ThrowExpr"
or
this instanceof HC_ReThrowExpr and result = "ReThrowExpr"
or
this instanceof HC_ExprCall and result = "ExprCall"
or
this instanceof HC_ConditionalExpr and result = "ConditionalExpr"
or
this instanceof HC_NoExceptExpr and result = "NoExceptExpr"
or
this instanceof HC_AllocatorArgZero and result = "AllocatorArgZero"
}
/**

View File

@@ -776,7 +776,7 @@ case @usertype.kind of
| 2 = @class
| 3 = @union
| 4 = @enum
| 5 = @typedef // classic C: typedef typedef type name
// ... 5 = @typedef deprecated // classic C: typedef typedef type name
// ... 6 = @template deprecated
| 7 = @template_parameter
| 8 = @template_template_parameter
@@ -785,10 +785,11 @@ case @usertype.kind of
// ... 11 objc_protocol deprecated
// ... 12 objc_category deprecated
| 13 = @scoped_enum
| 14 = @using_alias // a using name = type style typedef
// ... 14 = @using_alias deprecated // a using name = type style typedef
| 15 = @template_struct
| 16 = @template_class
| 17 = @template_union
| 18 = @alias
;
*/
@@ -811,6 +812,17 @@ usertype_uuid(
string uuid: string ref
);
/*
case @usertype.alias_kind of
| 0 = @typedef
| 1 = @alias
*/
usertype_alias_kind(
int id: @usertype ref,
int alias_kind: int ref
)
nontype_template_parameters(
int id: @expr ref
);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
description: Mix typedefs and usings
compatibility: full
usertypes.rel: run usertypes.qlo
usertype_alias_kind.rel: run usertype_alias_kind.qlo

View File

@@ -0,0 +1,14 @@
class UserType extends @usertype {
string toString() { none() }
}
bindingset[kind]
int getKind(int kind) {
kind = 5 and result = 0
or
kind = 14 and result = 1
}
from UserType usertype, int kind
where usertypes(usertype, _, kind)
select usertype, getKind(kind)

View File

@@ -0,0 +1,10 @@
class UserType extends @usertype {
string toString() { none() }
}
bindingset[kind]
int getKind(int kind) { if kind = [5, 14] then result = 18 else result = kind }
from UserType usertype, string name, int kind
where usertypes(usertype, name, kind)
select usertype, name, getKind(kind)

View File

@@ -33,8 +33,9 @@ predicate allocSink(HeuristicAllocationExpr alloc, DataFlow::Node sink) {
)
}
predicate readsVariable(LoadInstruction load, Variable var) {
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
predicate readsVariable(LoadInstruction load, Variable var, IRBlock bb) {
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var and
bb = load.getBlock()
}
predicate hasUpperBoundsCheck(Variable var) {
@@ -46,10 +47,18 @@ predicate hasUpperBoundsCheck(Variable var) {
)
}
predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
exists(Instruction instr | instr = node.asOperand().getDef() |
readsVariable(instr, checkedVar) and
any(IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true)
predicate variableEqualityCheckedInBlock(Variable checkedVar, IRBlock bb) {
exists(Operand access |
readsVariable(access.getDef(), checkedVar, _) and
any(IRGuardCondition guard).ensuresEq(access, _, _, bb, true)
)
}
predicate nodeIsBarrierEquality(DataFlow::Node node) {
exists(Variable checkedVar, Instruction instr, IRBlock bb |
instr = node.asOperand().getDef() and
readsVariable(instr, checkedVar, bb) and
variableEqualityCheckedInBlock(checkedVar, bb)
)
}
@@ -72,14 +81,11 @@ module TaintedAllocationSizeConfig implements DataFlow::ConfigSig {
)
or
exists(Variable checkedVar, Instruction instr | instr = node.asOperand().getDef() |
readsVariable(instr, checkedVar) and
readsVariable(instr, checkedVar, _) and
hasUpperBoundsCheck(checkedVar)
)
or
exists(Variable checkedVar, Operand access |
readsVariable(access.getDef(), checkedVar) and
nodeIsBarrierEqualityCandidate(node, access, checkedVar)
)
nodeIsBarrierEquality(node)
or
// block flow to inside of identified allocation functions (this flow leads
// to duplicate results)

View File

@@ -14,48 +14,6 @@ import cpp
import semmle.code.cpp.dataflow.new.DataFlow
import Flow::PathGraph
/**
* Holds if `f` is a field located at byte offset `offset` in `c`.
*
* Note that predicate is recursive, so that given the following:
* ```cpp
* struct S1 {
* int a;
* void* b;
* };
*
* struct S2 {
* S1 s1;
* char c;
* };
* ```
* both `hasAFieldWithOffset(S2, s1, 0)` and `hasAFieldWithOffset(S2, a, 0)`
* holds.
*/
predicate hasAFieldWithOffset(Class c, Field f, int offset) {
// Base case: `f` is a field in `c`.
f = c.getAField() and
offset = f.getByteOffset() and
not f.getUnspecifiedType().(Class).hasDefinition()
or
// Otherwise, we find the struct that is a field of `c` which then has
// the field `f` as a member.
exists(Field g |
g = c.getAField() and
// Find the field with the largest offset that's less than or equal to
// offset. That's the struct we need to search recursively.
g =
max(Field cand, int candOffset |
cand = c.getAField() and
candOffset = cand.getByteOffset() and
offset >= candOffset
|
cand order by candOffset
) and
hasAFieldWithOffset(g.getUnspecifiedType(), f, offset - g.getByteOffset())
)
}
/** Holds if `f` is the last field of its declaring class. */
predicate lastField(Field f) {
exists(Class c | c = f.getDeclaringType() |
@@ -75,7 +33,7 @@ predicate lastField(Field f) {
bindingset[f1, offset, c2]
pragma[inline_late]
predicate hasCompatibleFieldAtOffset(Field f1, int offset, Class c2) {
exists(Field f2 | hasAFieldWithOffset(c2, f2, offset) |
exists(Field f2 | offset = f2.getOffsetInClass(c2) |
// Let's not deal with bit-fields for now.
f2 instanceof BitField
or
@@ -100,7 +58,7 @@ predicate prefix(Class c1, Class c2) {
exists(Field f1, int offset |
// Let's not deal with bit-fields for now.
not f1 instanceof BitField and
hasAFieldWithOffset(c1, f1, offset)
offset = f1.getOffsetInClass(c1)
|
hasCompatibleFieldAtOffset(f1, offset, c2)
)
@@ -108,7 +66,7 @@ predicate prefix(Class c1, Class c2) {
forall(Field f1, int offset |
// Let's not deal with bit-fields for now.
not f1 instanceof BitField and
hasAFieldWithOffset(c1, f1, offset)
offset = f1.getOffsetInClass(c1)
|
hasCompatibleFieldAtOffset(f1, offset, c2)
)

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Call to memory access function may overflow buffer" query (`cpp/overflow-buffer`) now produces fewer FPs involving non-static member variables.

View File

@@ -77,3 +77,18 @@
| test.cpp:193:8:193:9 | b1 |
| test.cpp:193:8:193:15 | ... \|\| ... |
| test.cpp:193:14:193:15 | b2 |
| test.cpp:211:9:211:15 | ... == ... |
| test.cpp:214:9:214:17 | ... == ... |
| test.cpp:217:9:217:15 | ... == ... |
| test.cpp:220:9:220:14 | ... == ... |
| test.cpp:223:9:223:16 | ... == ... |
| test.cpp:226:9:226:14 | ... == ... |
| test.cpp:229:9:229:14 | ... == ... |
| test.cpp:232:9:232:18 | ... == ... |
| test.cpp:235:9:235:17 | ... == ... |
| test.cpp:238:9:238:17 | ... == ... |
| test.cpp:241:9:241:17 | ... == ... |
| test.cpp:241:9:241:30 | ... && ... |
| test.cpp:241:9:241:43 | ... && ... |
| test.cpp:241:22:241:30 | ... == ... |
| test.cpp:241:35:241:43 | ... == ... |

View File

@@ -653,3 +653,116 @@
| 206 | c != 0 when c is true |
| 206 | c == 0 when ! ... is true |
| 206 | c == 0 when c is false |
| 211 | 0 != sc+0 when ... == ... is false |
| 211 | 0 == sc+0 when ... == ... is true |
| 211 | ... == ... != 0 when ... == ... is true |
| 211 | ... == ... != 1 when ... == ... is false |
| 211 | ... == ... == 0 when ... == ... is false |
| 211 | ... == ... == 1 when ... == ... is true |
| 211 | sc != 0 when ... == ... is false |
| 211 | sc != 0+0 when ... == ... is false |
| 211 | sc == 0 when ... == ... is true |
| 211 | sc == 0+0 when ... == ... is true |
| 214 | 0 != sc+0 when ... == ... is false |
| 214 | 0 == sc+0 when ... == ... is true |
| 214 | ... == ... != 0 when ... == ... is true |
| 214 | ... == ... != 1 when ... == ... is false |
| 214 | ... == ... == 0 when ... == ... is false |
| 214 | ... == ... == 1 when ... == ... is true |
| 214 | sc != 0 when ... == ... is false |
| 214 | sc != 0+0 when ... == ... is false |
| 214 | sc == 0 when ... == ... is true |
| 214 | sc == 0+0 when ... == ... is true |
| 217 | 0 != ul+0 when ... == ... is false |
| 217 | 0 == ul+0 when ... == ... is true |
| 217 | ... == ... != 0 when ... == ... is true |
| 217 | ... == ... != 1 when ... == ... is false |
| 217 | ... == ... == 0 when ... == ... is false |
| 217 | ... == ... == 1 when ... == ... is true |
| 217 | ul != 0 when ... == ... is false |
| 217 | ul != 0+0 when ... == ... is false |
| 217 | ul == 0 when ... == ... is true |
| 217 | ul == 0+0 when ... == ... is true |
| 220 | 0 != f+0 when ... == ... is false |
| 220 | 0 == f+0 when ... == ... is true |
| 220 | ... == ... != 0 when ... == ... is true |
| 220 | ... == ... != 1 when ... == ... is false |
| 220 | ... == ... == 0 when ... == ... is false |
| 220 | ... == ... == 1 when ... == ... is true |
| 220 | f != 0+0 when ... == ... is false |
| 220 | f == 0+0 when ... == ... is true |
| 223 | 0.0 != f+0 when ... == ... is false |
| 223 | 0.0 == f+0 when ... == ... is true |
| 223 | ... == ... != 0 when ... == ... is true |
| 223 | ... == ... != 1 when ... == ... is false |
| 223 | ... == ... == 0 when ... == ... is false |
| 223 | ... == ... == 1 when ... == ... is true |
| 223 | f != 0.0+0 when ... == ... is false |
| 223 | f == 0.0+0 when ... == ... is true |
| 226 | 0 != d+0 when ... == ... is false |
| 226 | 0 == d+0 when ... == ... is true |
| 226 | ... == ... != 0 when ... == ... is true |
| 226 | ... == ... != 1 when ... == ... is false |
| 226 | ... == ... == 0 when ... == ... is false |
| 226 | ... == ... == 1 when ... == ... is true |
| 226 | d != 0+0 when ... == ... is false |
| 226 | d == 0+0 when ... == ... is true |
| 229 | 0 != b+0 when ... == ... is false |
| 229 | 0 == b+0 when ... == ... is true |
| 229 | ... == ... != 0 when ... == ... is true |
| 229 | ... == ... != 1 when ... == ... is false |
| 229 | ... == ... == 0 when ... == ... is false |
| 229 | ... == ... == 1 when ... == ... is true |
| 229 | b != 0 when ... == ... is false |
| 229 | b != 0+0 when ... == ... is false |
| 229 | b == 0 when ... == ... is true |
| 229 | b == 0+0 when ... == ... is true |
| 232 | 0 != b+0 when ... == ... is false |
| 232 | 0 == b+0 when ... == ... is true |
| 232 | ... == ... != 0 when ... == ... is true |
| 232 | ... == ... != 1 when ... == ... is false |
| 232 | ... == ... == 0 when ... == ... is false |
| 232 | ... == ... == 1 when ... == ... is true |
| 232 | b != 0 when ... == ... is false |
| 232 | b != 0+0 when ... == ... is false |
| 232 | b == 0 when ... == ... is true |
| 232 | b == 0+0 when ... == ... is true |
| 235 | 0 != i+0 when ... == ... is false |
| 235 | 0 == i+0 when ... == ... is true |
| 235 | ... == ... != 0 when ... == ... is true |
| 235 | ... == ... != 1 when ... == ... is false |
| 235 | ... == ... == 0 when ... == ... is false |
| 235 | ... == ... == 1 when ... == ... is true |
| 235 | i != 0 when ... == ... is false |
| 235 | i != 0+0 when ... == ... is false |
| 235 | i == 0 when ... == ... is true |
| 235 | i == 0+0 when ... == ... is true |
| 238 | 0 != f+0 when ... == ... is false |
| 238 | 0 == f+0 when ... == ... is true |
| 238 | ... == ... != 0 when ... == ... is true |
| 238 | ... == ... != 1 when ... == ... is false |
| 238 | ... == ... == 0 when ... == ... is false |
| 238 | ... == ... == 1 when ... == ... is true |
| 238 | f != 0+0 when ... == ... is false |
| 238 | f == 0+0 when ... == ... is true |
| 241 | 0 != f+0 when ... == ... is false |
| 241 | 0 != i+0 when ... == ... is false |
| 241 | 0 == f+0 when ... && ... is true |
| 241 | 0 == f+0 when ... == ... is true |
| 241 | 0 == i+0 when ... && ... is true |
| 241 | 0 == i+0 when ... == ... is true |
| 241 | ... == ... != 0 when ... && ... is true |
| 241 | ... == ... != 0 when ... == ... is true |
| 241 | ... == ... != 1 when ... == ... is false |
| 241 | ... == ... == 0 when ... == ... is false |
| 241 | ... == ... == 1 when ... && ... is true |
| 241 | ... == ... == 1 when ... == ... is true |
| 241 | f != 0+0 when ... == ... is false |
| 241 | f == 0+0 when ... && ... is true |
| 241 | f == 0+0 when ... == ... is true |
| 241 | i != 0 when ... == ... is false |
| 241 | i != 0+0 when ... == ... is false |
| 241 | i == 0 when ... && ... is true |
| 241 | i == 0 when ... == ... is true |
| 241 | i == 0+0 when ... && ... is true |
| 241 | i == 0+0 when ... == ... is true |

View File

@@ -146,3 +146,21 @@
| test.cpp:193:8:193:15 | ... \|\| ... | false | 193 | 196 |
| test.cpp:193:8:193:15 | ... \|\| ... | true | 197 | 199 |
| test.cpp:193:14:193:15 | b2 | false | 192 | 193 |
| test.cpp:211:9:211:15 | ... == ... | true | 211 | 212 |
| test.cpp:214:9:214:17 | ... == ... | true | 214 | 215 |
| test.cpp:217:9:217:15 | ... == ... | true | 217 | 218 |
| test.cpp:220:9:220:14 | ... == ... | true | 220 | 221 |
| test.cpp:223:9:223:16 | ... == ... | true | 223 | 224 |
| test.cpp:226:9:226:14 | ... == ... | true | 226 | 227 |
| test.cpp:229:9:229:14 | ... == ... | true | 229 | 230 |
| test.cpp:232:9:232:18 | ... == ... | true | 232 | 233 |
| test.cpp:235:9:235:17 | ... == ... | true | 235 | 236 |
| test.cpp:238:9:238:17 | ... == ... | true | 238 | 239 |
| test.cpp:241:9:241:17 | ... == ... | true | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | true | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | true | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | true | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | true | 241 | 242 |
| test.cpp:241:22:241:30 | ... == ... | true | 241 | 241 |
| test.cpp:241:22:241:30 | ... == ... | true | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | true | 241 | 242 |

View File

@@ -207,6 +207,96 @@ binary
| test.cpp:176:7:176:8 | ! ... | test.cpp:174:16:174:16 | b | >= | test.cpp:174:12:174:12 | a | 0 | 176 | 178 |
| test.cpp:176:8:176:8 | c | test.cpp:174:12:174:12 | a | < | test.cpp:174:16:174:16 | b | 1 | 176 | 178 |
| test.cpp:176:8:176:8 | c | test.cpp:174:16:174:16 | b | >= | test.cpp:174:12:174:12 | a | 0 | 176 | 178 |
| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:10 | sc | == | test.cpp:211:15:211:15 | 0 | 0 | 211 | 212 |
| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:15:211:15 | 0 | == | test.cpp:211:9:211:10 | sc | 0 | 211 | 212 |
| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:10 | sc | == | test.cpp:214:15:214:17 | 0 | 0 | 211 | 212 |
| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:15:214:17 | 0 | == | test.cpp:214:9:214:10 | sc | 0 | 211 | 212 |
| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:10 | sc | == | test.cpp:211:15:211:15 | 0 | 0 | 214 | 215 |
| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:15:211:15 | 0 | == | test.cpp:211:9:211:10 | sc | 0 | 214 | 215 |
| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:10 | sc | == | test.cpp:214:15:214:17 | 0 | 0 | 214 | 215 |
| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:15:214:17 | 0 | == | test.cpp:214:9:214:10 | sc | 0 | 214 | 215 |
| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:10 | ul | == | test.cpp:217:15:217:15 | 0 | 0 | 217 | 218 |
| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:15:217:15 | 0 | == | test.cpp:217:9:217:10 | ul | 0 | 217 | 218 |
| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:9:220:9 | f | == | test.cpp:220:14:220:14 | 0 | 0 | 220 | 221 |
| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:14:220:14 | 0 | == | test.cpp:220:9:220:9 | f | 0 | 220 | 221 |
| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:9:223:9 | f | == | test.cpp:223:14:223:16 | 0.0 | 0 | 223 | 224 |
| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:14:223:16 | 0.0 | == | test.cpp:223:9:223:9 | f | 0 | 223 | 224 |
| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:9:226:9 | d | == | test.cpp:226:14:226:14 | 0 | 0 | 226 | 227 |
| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:14:226:14 | 0 | == | test.cpp:226:9:226:9 | d | 0 | 226 | 227 |
| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:9 | b | == | test.cpp:229:14:229:14 | 0 | 0 | 229 | 230 |
| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:14:229:14 | 0 | == | test.cpp:229:9:229:9 | b | 0 | 229 | 230 |
| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:9 | b | == | test.cpp:232:14:232:18 | 0 | 0 | 229 | 230 |
| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:14:232:18 | 0 | == | test.cpp:232:9:232:9 | b | 0 | 229 | 230 |
| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:9 | b | == | test.cpp:229:14:229:14 | 0 | 0 | 232 | 233 |
| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:14:229:14 | 0 | == | test.cpp:229:9:229:9 | b | 0 | 232 | 233 |
| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:9 | b | == | test.cpp:232:14:232:18 | 0 | 0 | 232 | 233 |
| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:14:232:18 | 0 | == | test.cpp:232:9:232:9 | b | 0 | 232 | 233 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 235 | 236 |
| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 238 | 239 |
| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 238 | 239 |
| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 238 | 239 |
| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 238 | 239 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 242 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 241 | 241 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 241 | 241 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 241 | 242 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 241 | 241 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 241 | 242 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 241 | 241 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 242 |
unary
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | 1 | 10 | 11 |
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | 1 | 7 | 9 |
@@ -712,3 +802,123 @@ unary
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | 193 | 196 |
| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | != | 1 | 192 | 193 |
| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | == | 0 | 192 | 193 |
| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:10 | sc | == | 0 | 211 | 212 |
| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:15 | ... == ... | != | 0 | 211 | 212 |
| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:15 | ... == ... | == | 1 | 211 | 212 |
| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:10 | sc | == | 0 | 211 | 212 |
| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:17 | ... == ... | != | 0 | 211 | 212 |
| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:17 | ... == ... | == | 1 | 211 | 212 |
| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:10 | sc | == | 0 | 214 | 215 |
| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:15 | ... == ... | != | 0 | 214 | 215 |
| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:15 | ... == ... | == | 1 | 214 | 215 |
| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:10 | sc | == | 0 | 214 | 215 |
| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:17 | ... == ... | != | 0 | 214 | 215 |
| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:17 | ... == ... | == | 1 | 214 | 215 |
| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:10 | ul | == | 0 | 217 | 218 |
| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:15 | ... == ... | != | 0 | 217 | 218 |
| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:15 | ... == ... | == | 1 | 217 | 218 |
| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:9:220:14 | ... == ... | != | 0 | 220 | 221 |
| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:9:220:14 | ... == ... | == | 1 | 220 | 221 |
| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:9:223:16 | ... == ... | != | 0 | 223 | 224 |
| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:9:223:16 | ... == ... | == | 1 | 223 | 224 |
| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:9:226:14 | ... == ... | != | 0 | 226 | 227 |
| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:9:226:14 | ... == ... | == | 1 | 226 | 227 |
| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:9 | b | == | 0 | 229 | 230 |
| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:14 | ... == ... | != | 0 | 229 | 230 |
| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:14 | ... == ... | == | 1 | 229 | 230 |
| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:9 | b | == | 0 | 229 | 230 |
| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:18 | ... == ... | != | 0 | 229 | 230 |
| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:18 | ... == ... | == | 1 | 229 | 230 |
| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:9 | b | == | 0 | 232 | 233 |
| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:14 | ... == ... | != | 0 | 232 | 233 |
| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:14 | ... == ... | == | 1 | 232 | 233 |
| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:9 | b | == | 0 | 232 | 233 |
| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:18 | ... == ... | != | 0 | 232 | 233 |
| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:18 | ... == ... | == | 1 | 232 | 233 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 235 | 236 |
| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | 235 | 236 |
| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 238 | 239 |
| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 238 | 239 |
| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 238 | 239 |
| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 238 | 239 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 241 |
| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 241 |
| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 242 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 241 | 241 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 241 | 241 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 241 | 241 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 241 | 241 |
| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 242 |
| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 242 |

View File

@@ -198,4 +198,47 @@ void test_logical_or(bool b1, bool b2) {
use(b1);
use(b2);
}
}
}
struct Mystruct {
int i;
float f;
};
int test_types(signed char sc, unsigned long ul, float f, double d, bool b, Mystruct &ms) {
int ctr = 0;
if (sc == 0) {
ctr++;
}
if (sc == 0x0) {
ctr++;
}
if (ul == 0) {
ctr++;
}
if (f == 0) {
ctr++;
}
if (f == 0.0) {
ctr++;
}
if (d == 0) {
ctr++;
}
if (b == 0) {
ctr++;
}
if (b == false) {
ctr++;
}
if (ms.i == 0) {
ctr++;
}
if (ms.f == 0) {
ctr++;
}
if (ms.i == 0 && ms.f == 0 && ms.i == 0) {
ctr++;
}
}

View File

@@ -102,32 +102,49 @@ sourceCallables
| tests.cpp:139:6:139:10 | value |
| tests.cpp:140:6:140:11 | value2 |
| tests.cpp:141:7:141:9 | ptr |
| tests.cpp:144:5:144:19 | madArg0ToReturn |
| tests.cpp:144:25:144:25 | x |
| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
| tests.cpp:145:34:145:34 | x |
| tests.cpp:146:5:146:15 | notASummary |
| tests.cpp:146:21:146:21 | x |
| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
| tests.cpp:147:34:147:34 | x |
| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
| tests.cpp:148:34:148:34 | x |
| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
| tests.cpp:149:41:149:41 | x |
| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
| tests.cpp:150:37:150:37 | x |
| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
| tests.cpp:151:32:151:32 | x |
| tests.cpp:151:40:151:40 | y |
| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
| tests.cpp:152:47:152:47 | x |
| tests.cpp:152:55:152:55 | y |
| tests.cpp:153:5:153:18 | madArgsComplex |
| tests.cpp:153:25:153:25 | a |
| tests.cpp:153:33:153:33 | b |
| tests.cpp:153:40:153:40 | c |
| tests.cpp:153:47:153:47 | d |
| tests.cpp:154:5:154:14 | madArgsAny |
| tests.cpp:154:20:154:20 | a |
| tests.cpp:154:28:154:28 | b |
| tests.cpp:155:5:155:28 | madAndImplementedComplex |
| tests.cpp:155:34:155:34 | a |
| tests.cpp:155:41:155:41 | b |
| tests.cpp:155:48:155:48 | c |
| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
| tests.cpp:160:38:160:39 | mc |
| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
| tests.cpp:161:47:161:48 | mc |
| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
| tests.cpp:162:46:162:47 | mc |
| tests.cpp:163:13:163:32 | madArg0ToReturnField |
| tests.cpp:163:38:163:38 | x |
| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
| tests.cpp:164:47:164:47 | x |
| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
| tests.cpp:165:46:165:46 | x |
| tests.cpp:167:13:167:30 | madFieldToFieldVar |
| tests.cpp:168:13:168:38 | madFieldToIndirectFieldVar |
@@ -160,9 +177,13 @@ sourceCallables
| tests.cpp:280:7:280:23 | qualifierArg0Sink |
| tests.cpp:280:29:280:29 | x |
| tests.cpp:281:7:281:24 | qualifierFieldSink |
| tests.cpp:284:7:284:19 | madArg0ToSelf |
| tests.cpp:284:25:284:25 | x |
| tests.cpp:285:6:285:20 | madSelfToReturn |
| tests.cpp:286:6:286:16 | notASummary |
| tests.cpp:287:7:287:20 | madArg0ToField |
| tests.cpp:287:26:287:26 | x |
| tests.cpp:288:6:288:21 | madFieldToReturn |
| tests.cpp:290:6:290:8 | val |
| tests.cpp:293:7:293:7 | MyDerivedClass |
| tests.cpp:293:7:293:7 | operator= |
@@ -183,6 +204,7 @@ sourceCallables
| tests.cpp:308:52:308:52 | x |
| tests.cpp:309:7:309:31 | namespaceMemberMadSinkVar |
| tests.cpp:310:14:310:44 | namespaceStaticMemberMadSinkVar |
| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
| tests.cpp:317:22:317:28 | source3 |
| tests.cpp:319:6:319:23 | test_class_members |
| tests.cpp:320:10:320:11 | mc |
@@ -208,10 +230,14 @@ sourceCallables
| tests.cpp:429:8:429:14 | intPair |
| tests.cpp:430:6:430:10 | first |
| tests.cpp:431:6:431:11 | second |
| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
| tests.cpp:434:37:434:43 | fun_ptr |
| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
| tests.cpp:435:46:435:52 | fun_ptr |
| tests.cpp:436:6:436:25 | madCallArg0WithValue |
| tests.cpp:436:34:436:40 | fun_ptr |
| tests.cpp:436:53:436:57 | value |
| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
| tests.cpp:437:45:437:51 | fun_ptr |
| tests.cpp:437:64:437:68 | value |
| tests.cpp:439:5:439:14 | getTainted |
@@ -225,6 +251,7 @@ sourceCallables
| tests.cpp:457:8:457:35 | StructWithTypedefInParameter<int> |
| tests.cpp:458:12:458:15 | Type |
| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
| tests.cpp:459:45:459:45 | x |
| tests.cpp:459:45:459:45 | x |
| tests.cpp:462:6:462:37 | test_parameter_ref_to_return_ref |
@@ -232,6 +259,7 @@ sourceCallables
| tests.cpp:464:36:464:36 | s |
| tests.cpp:465:6:465:6 | y |
| tests.cpp:469:7:469:9 | INT |
| tests.cpp:471:5:471:17 | receive_array |
| tests.cpp:471:23:471:23 | a |
| tests.cpp:473:6:473:23 | test_receive_array |
| tests.cpp:474:6:474:6 | x |

View File

@@ -0,0 +1,30 @@
uniqueEnclosingCallable
uniqueCallEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
parameterCallable
localFlowIsLocal
readStepIsLocal
storeStepIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
| tests.cpp:436:6:436:25 | [summary] to write: Argument[1] in madCallArg0WithValue | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge
uniqueParameterNodeAtPosition
uniqueParameterNodePosition
uniqueContentApprox
identityLocalStep
missingArgumentCall
multipleArgumentCall
lambdaCallEnclosingCallableMismatch
speculativeStepAlreadyHasModel

View File

@@ -0,0 +1,2 @@
import testModels
import semmle.code.cpp.ir.dataflow.internal.DataFlowImplConsistency::Consistency

View File

@@ -205,7 +205,7 @@ void test_summaries() {
sink(madAndImplementedComplex(0, 0, 0));
sink(madAndImplementedComplex(source(), 0, 0));
sink(madAndImplementedComplex(0, source(), 0)); // $ ir
sink(madAndImplementedComplex(0, source(), 0)); // Clean. We have a MaD model specifying different behavior.
sink(madAndImplementedComplex(0, 0, source())); // $ ir
sink(madArgsAny(0, 0));

View File

@@ -7741,6 +7741,32 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
| taint.cpp:809:8:809:9 | p2 | taint.cpp:809:7:809:9 | * ... | TAINT |
| taint.cpp:811:12:811:28 | call to SysAllocStringLen | taint.cpp:812:8:812:9 | p3 | |
| taint.cpp:812:8:812:9 | p3 | taint.cpp:812:7:812:9 | * ... | TAINT |
| taint.cpp:817:42:817:46 | p_out | taint.cpp:817:42:817:46 | p_out | |
| taint.cpp:817:42:817:46 | p_out | taint.cpp:819:4:819:8 | p_out | |
| taint.cpp:817:62:817:65 | p_in | taint.cpp:817:62:817:65 | p_in | |
| taint.cpp:817:62:817:65 | p_in | taint.cpp:818:20:818:23 | p_in | |
| taint.cpp:818:19:818:23 | * ... | taint.cpp:819:19:819:19 | q | |
| taint.cpp:818:20:818:23 | p_in | taint.cpp:818:19:818:23 | * ... | TAINT |
| taint.cpp:819:3:819:8 | * ... [post update] | taint.cpp:817:42:817:46 | p_out | |
| taint.cpp:819:3:819:8 | * ... [post update] | taint.cpp:819:4:819:8 | p_out [inner post update] | |
| taint.cpp:819:3:819:25 | ... = ... | taint.cpp:819:3:819:8 | * ... [post update] | |
| taint.cpp:819:4:819:8 | p_out | taint.cpp:819:3:819:8 | * ... | TAINT |
| taint.cpp:819:12:819:17 | call to strchr | taint.cpp:819:3:819:25 | ... = ... | |
| taint.cpp:819:19:819:19 | q | taint.cpp:819:12:819:17 | call to strchr | TAINT |
| taint.cpp:819:22:819:24 | 47 | taint.cpp:819:12:819:17 | call to strchr | TAINT |
| taint.cpp:822:33:822:35 | out | taint.cpp:822:33:822:35 | out | |
| taint.cpp:822:33:822:35 | out | taint.cpp:826:27:826:29 | out | |
| taint.cpp:822:50:822:51 | in | taint.cpp:822:50:822:51 | in | |
| taint.cpp:822:50:822:51 | in | taint.cpp:826:33:826:34 | in | |
| taint.cpp:826:26:826:29 | ref arg & ... | taint.cpp:822:33:822:35 | out | |
| taint.cpp:826:26:826:29 | ref arg & ... | taint.cpp:826:27:826:29 | out [inner post update] | |
| taint.cpp:826:27:826:29 | out | taint.cpp:826:26:826:29 | & ... | |
| taint.cpp:826:32:826:34 | ref arg & ... | taint.cpp:822:50:822:51 | in | |
| taint.cpp:826:32:826:34 | ref arg & ... | taint.cpp:826:33:826:34 | in [inner post update] | |
| taint.cpp:826:33:826:34 | in | taint.cpp:826:32:826:34 | & ... | |
| taint.cpp:830:20:830:34 | call to indirect_source | taint.cpp:832:23:832:24 | in | |
| taint.cpp:831:15:831:17 | out | taint.cpp:832:18:832:20 | out | |
| taint.cpp:831:15:831:17 | out | taint.cpp:833:8:833:10 | out | |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |

View File

@@ -810,4 +810,25 @@ void test_sysalloc() {
auto p3 = SysAllocStringLen((LPOLESTR)indirect_source(), 10);
sink(*p3); // $ ir MISSING: ast
}
char* strchr(const char*, int);
void write_to_const_ptr_ptr(const char **p_out, const char **p_in) {
const char* q = *p_in;
*p_out = strchr(q, '/');
}
void take_const_ptr(const char *out, const char *in) {
// NOTE: We take the address of `out` in `take_const_ptr`'s stack space.
// Assigning to this pointer does not change `out` in
// `test_write_to_const_ptr_ptr`.
write_to_const_ptr_ptr(&out, &in);
}
void test_write_to_const_ptr_ptr() {
const char* in = indirect_source();
const char* out;
take_const_ptr(out, in);
sink(out); // $ SPURIOUS: ast
}

View File

@@ -626,6 +626,11 @@ signatureMatches
| taint.cpp:725:10:725:15 | strtol | (XCHAR *,const XCHAR *,int) | CSimpleStringT | CopyCharsOverlapped | 2 |
| taint.cpp:727:6:727:16 | test_strtol | (char *) | CStringT | CStringT | 0 |
| taint.cpp:785:6:785:15 | fopen_test | (char *) | CStringT | CStringT | 0 |
| taint.cpp:815:7:815:12 | strchr | (LPCOLESTR,int) | CComBSTR | Append | 1 |
| taint.cpp:815:7:815:12 | strchr | (char,int) | CStringT | CStringT | 1 |
| taint.cpp:815:7:815:12 | strchr | (const XCHAR *,int) | CStringT | CStringT | 1 |
| taint.cpp:815:7:815:12 | strchr | (const YCHAR *,int) | CStringT | CStringT | 1 |
| taint.cpp:815:7:815:12 | strchr | (wchar_t,int) | CStringT | CStringT | 1 |
| vector.cpp:333:6:333:35 | vector_iterator_assign_wrapper | (LPCOLESTR,int) | CComBSTR | Append | 1 |
| vector.cpp:333:6:333:35 | vector_iterator_assign_wrapper | (char,int) | CStringT | CStringT | 1 |
| vector.cpp:333:6:333:35 | vector_iterator_assign_wrapper | (const XCHAR *,int) | CStringT | CStringT | 1 |
@@ -2029,6 +2034,12 @@ getParameterTypeName
| taint.cpp:802:6:802:22 | SysAllocStringLen | 0 | const OLECHAR * |
| taint.cpp:802:6:802:22 | SysAllocStringLen | 0 | const wchar_t * |
| taint.cpp:802:6:802:22 | SysAllocStringLen | 1 | unsigned int |
| taint.cpp:815:7:815:12 | strchr | 0 | const char * |
| taint.cpp:815:7:815:12 | strchr | 1 | int |
| taint.cpp:817:6:817:27 | write_to_const_ptr_ptr | 0 | const char ** |
| taint.cpp:817:6:817:27 | write_to_const_ptr_ptr | 1 | const char ** |
| taint.cpp:822:6:822:19 | take_const_ptr | 0 | const char * |
| taint.cpp:822:6:822:19 | take_const_ptr | 1 | const char * |
| vector.cpp:13:6:13:9 | sink | 0 | int |
| vector.cpp:14:27:14:30 | sink | 0 | vector> & |
| vector.cpp:14:27:14:30 | sink | 0 | vector> & |

View File

@@ -1,4 +1,4 @@
edges
subpaths
nodes
subpaths
#select

View File

@@ -49,6 +49,37 @@
| tests.cpp:577:7:577:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:565:7:565:12 | buffer | array |
| tests.cpp:637:6:637:15 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:633:7:633:12 | buffer | array |
| tests.cpp:645:7:645:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:633:7:633:12 | buffer | array |
| tests.cpp:708:3:708:8 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 8 bytes. | tests.cpp:693:16:693:16 | c | destination buffer |
| tests.cpp:712:3:712:8 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:693:16:693:16 | c | destination buffer |
| tests.cpp:716:3:716:8 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 16 bytes. | tests.cpp:692:16:692:16 | b | destination buffer |
| tests.cpp:727:2:727:7 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 8 bytes. | tests.cpp:693:16:693:16 | c | destination buffer |
| tests.cpp:753:5:753:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:735:20:735:22 | b_1 | destination buffer |
| tests.cpp:756:5:756:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:735:20:735:22 | b_1 | destination buffer |
| tests.cpp:760:5:760:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
| tests.cpp:761:5:761:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
| tests.cpp:763:5:763:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
| tests.cpp:764:5:764:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
| tests.cpp:774:5:774:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:740:20:740:22 | b_2 | destination buffer |
| tests.cpp:777:5:777:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:740:20:740:22 | b_2 | destination buffer |
| tests.cpp:795:5:795:10 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:790:16:790:16 | b | destination buffer |
| tests.cpp:822:5:822:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:801:16:801:16 | b | destination buffer |
| tests.cpp:825:5:825:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:801:16:801:16 | b | destination buffer |
| tests.cpp:827:5:827:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:801:16:801:16 | b | destination buffer |
| tests.cpp:830:5:830:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
| tests.cpp:831:5:831:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
| tests.cpp:833:5:833:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
| tests.cpp:835:5:835:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
| tests.cpp:846:5:846:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
| tests.cpp:847:5:847:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
| tests.cpp:848:5:848:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
| tests.cpp:849:5:849:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
| tests.cpp:851:5:851:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
| tests.cpp:862:5:862:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
| tests.cpp:863:5:863:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
| tests.cpp:864:5:864:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
| tests.cpp:865:5:865:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
| tests.cpp:866:5:866:10 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
| tests.cpp:867:5:867:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
| tests_restrict.c:12:2:12:7 | call to memcpy | This 'memcpy' operation accesses 2 bytes but the $@ is only 1 byte. | tests_restrict.c:7:6:7:13 | smallbuf | source buffer |
| unions.cpp:26:2:26:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:21:10:21:11 | mu | destination buffer |
| unions.cpp:30:2:30:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:15:7:15:11 | small | destination buffer |

View File

@@ -27,8 +27,8 @@ edges
| main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | |
| main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | **argv | provenance | |
| main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | *argv | provenance | |
| main.cpp:10:20:10:23 | **argv | tests.cpp:689:32:689:35 | **argv | provenance | |
| main.cpp:10:20:10:23 | *argv | tests.cpp:689:32:689:35 | *argv | provenance | |
| main.cpp:10:20:10:23 | **argv | tests.cpp:872:32:872:35 | **argv | provenance | |
| main.cpp:10:20:10:23 | *argv | tests.cpp:872:32:872:35 | *argv | provenance | |
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | provenance | |
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | *argv | provenance | |
| test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | provenance | |
@@ -41,12 +41,12 @@ edges
| tests.cpp:628:14:628:14 | *s [*home] | tests.cpp:628:14:628:19 | *home | provenance | |
| tests.cpp:628:14:628:14 | *s [*home] | tests.cpp:628:16:628:19 | *home | provenance | |
| tests.cpp:628:16:628:19 | *home | tests.cpp:628:14:628:19 | *home | provenance | |
| tests.cpp:689:32:689:35 | **argv | tests.cpp:714:9:714:15 | *access to array | provenance | |
| tests.cpp:689:32:689:35 | **argv | tests.cpp:715:9:715:15 | *access to array | provenance | |
| tests.cpp:689:32:689:35 | *argv | tests.cpp:714:9:714:15 | *access to array | provenance | |
| tests.cpp:689:32:689:35 | *argv | tests.cpp:715:9:715:15 | *access to array | provenance | |
| tests.cpp:714:9:714:15 | *access to array | tests.cpp:613:19:613:24 | *source | provenance | |
| tests.cpp:715:9:715:15 | *access to array | tests.cpp:622:19:622:24 | *source | provenance | |
| tests.cpp:872:32:872:35 | **argv | tests.cpp:897:9:897:15 | *access to array | provenance | |
| tests.cpp:872:32:872:35 | **argv | tests.cpp:898:9:898:15 | *access to array | provenance | |
| tests.cpp:872:32:872:35 | *argv | tests.cpp:897:9:897:15 | *access to array | provenance | |
| tests.cpp:872:32:872:35 | *argv | tests.cpp:898:9:898:15 | *access to array | provenance | |
| tests.cpp:897:9:897:15 | *access to array | tests.cpp:613:19:613:24 | *source | provenance | |
| tests.cpp:898:9:898:15 | *access to array | tests.cpp:622:19:622:24 | *source | provenance | |
| tests_restrict.c:15:41:15:44 | **argv | tests_restrict.c:15:41:15:44 | **argv | provenance | |
| tests_restrict.c:15:41:15:44 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | |
nodes
@@ -80,10 +80,10 @@ nodes
| tests.cpp:628:14:628:14 | *s [*home] | semmle.label | *s [*home] |
| tests.cpp:628:14:628:19 | *home | semmle.label | *home |
| tests.cpp:628:16:628:19 | *home | semmle.label | *home |
| tests.cpp:689:32:689:35 | **argv | semmle.label | **argv |
| tests.cpp:689:32:689:35 | *argv | semmle.label | *argv |
| tests.cpp:714:9:714:15 | *access to array | semmle.label | *access to array |
| tests.cpp:715:9:715:15 | *access to array | semmle.label | *access to array |
| tests.cpp:872:32:872:35 | **argv | semmle.label | **argv |
| tests.cpp:872:32:872:35 | *argv | semmle.label | *argv |
| tests.cpp:897:9:897:15 | *access to array | semmle.label | *access to array |
| tests.cpp:898:9:898:15 | *access to array | semmle.label | *access to array |
| tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv |
| tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv |
| tests_restrict.c:15:41:15:44 | *argv | semmle.label | *argv |

View File

@@ -685,6 +685,189 @@ int test28(MYSTRUCTREF g)
return memcmp(&g, &_myStruct, sizeof(MYSTRUCT)); // GOOD
}
#define offsetof(s, m) __builtin_offsetof(s, m)
struct HasSomeFields {
unsigned long a;
unsigned long b;
unsigned long c;
void test29() {
memset(&a, 0, sizeof(HasSomeFields) - offsetof(HasSomeFields, a)); // GOOD
};
void test30() {
memset(&b, 0, sizeof(HasSomeFields) - offsetof(HasSomeFields, b)); // GOOD
};
void test31() {
memset(&c, 0, sizeof(HasSomeFields) - offsetof(HasSomeFields, c)); // GOOD
};
void test32() {
memset(&c, 0, sizeof(HasSomeFields) - offsetof(HasSomeFields, a)); // BAD
};
void test33() {
memset(&c, 0, sizeof(HasSomeFields) - offsetof(HasSomeFields, b)); // BAD
};
void test34() {
memset(&b, 0, sizeof(HasSomeFields) - offsetof(HasSomeFields, a)); // BAD
};
void test35() {
memset(&b, 0, sizeof(HasSomeFields) - offsetof(HasSomeFields, b) - sizeof(unsigned long)); // GOOD
};
};
void test36() {
HasSomeFields hsf;
memset(&hsf.a, 0, sizeof(HasSomeFields) - offsetof(HasSomeFields, a)); // GOOD
memset(&hsf.c, 0, sizeof(HasSomeFields) - offsetof(HasSomeFields, a)); // BAD
}
struct AnonUnionInStruct
{
union {
struct {
unsigned int a_1;
unsigned int b_1;
unsigned int c_1;
};
struct {
unsigned int a_2;
unsigned int b_2;
};
};
unsigned int d;
void test37() {
memset(&a_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, a_1)); // GOOD
memset(&a_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, b_1)); // GOOD
memset(&a_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, c_1)); // GOOD
memset(&a_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, a_2)); // GOOD
memset(&a_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, b_2)); // GOOD
memset(&a_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, d)); // GOOD
memset(&b_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, a_1)); // BAD
memset(&b_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, b_1)); // GOOD
memset(&b_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, c_1)); // GOOD
memset(&b_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, a_2)); // BAD
memset(&b_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, b_2)); // GOOD
memset(&b_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, d)); // GOOD
memset(&c_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, a_1)); // BAD
memset(&c_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, b_1)); // BAD
memset(&c_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, c_1)); // GOOD
memset(&c_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, a_2)); // BAD
memset(&c_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, b_2)); // GOOD
memset(&c_1, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, d)); // GOOD
memset(&a_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, a_1)); // GOOD
memset(&a_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, b_1)); // GOOD
memset(&a_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, c_1)); // GOOD
memset(&a_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, a_2)); // GOOD
memset(&a_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, b_2)); // GOOD
memset(&a_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, d)); // GOOD
memset(&b_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, a_1)); // BAD
memset(&b_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, b_1)); // GOOD
memset(&b_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, c_1)); // GOOD
memset(&b_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, a_2)); // BAD
memset(&b_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, b_2)); // GOOD
memset(&b_2, 0, sizeof(AnonUnionInStruct) - offsetof(AnonUnionInStruct, d)); // GOOD
};
};
struct UnionWithoutStruct
{
union
{
unsigned int a;
};
unsigned int b;
void test37() {
memset(&a, 0, sizeof(UnionWithoutStruct) - offsetof(UnionWithoutStruct, a)); // GOOD
memset(&a, 0, sizeof(UnionWithoutStruct) - offsetof(UnionWithoutStruct, b)); // GOOD
memset(&b, 0, sizeof(UnionWithoutStruct) - offsetof(UnionWithoutStruct, a)); // BAD
};
};
struct ThreeUInts {
unsigned int a;
unsigned int b;
unsigned int c;
};
struct FourUInts {
ThreeUInts inner;
unsigned int x;
};
struct S2 {
FourUInts f;
unsigned u;
void test38() {
memset(&f.inner.a, 0, sizeof(S2) - offsetof(ThreeUInts, a)); // GOOD
memset(&f.inner.a, 0, sizeof(S2) - offsetof(ThreeUInts, b)); // GOOD
memset(&f.inner.a, 0, sizeof(S2) - offsetof(ThreeUInts, c)); // GOOD
memset(&f.inner.a, 0, sizeof(S2) - offsetof(FourUInts, inner)); // GOOD
memset(&f.inner.a, 0, sizeof(S2) - offsetof(FourUInts, x)); // GOOD
memset(&f.inner.a, 0, sizeof(S2) - offsetof(S2, f)); // GOOD
memset(&f.inner.a, 0, sizeof(S2) - offsetof(S2, u)); // GOOD
memset(&f.inner.b, 0, sizeof(S2) - offsetof(ThreeUInts, a)); // BAD
memset(&f.inner.b, 0, sizeof(S2) - offsetof(ThreeUInts, b)); // GOOD
memset(&f.inner.b, 0, sizeof(S2) - offsetof(ThreeUInts, c)); // GOOD
memset(&f.inner.b, 0, sizeof(S2) - offsetof(FourUInts, inner)); // BAD
memset(&f.inner.b, 0, sizeof(S2) - offsetof(FourUInts, x)); // GOOD
memset(&f.inner.b, 0, sizeof(S2) - offsetof(S2, f)); // BAD
memset(&f.inner.b, 0, sizeof(S2) - offsetof(S2, u)); // GOOD
memset(&f.inner.c, 0, sizeof(S2) - offsetof(ThreeUInts, a)); // BAD
memset(&f.inner.c, 0, sizeof(S2) - offsetof(ThreeUInts, b)); // BAD
memset(&f.inner.c, 0, sizeof(S2) - offsetof(ThreeUInts, c)); // GOOD
memset(&f.inner.c, 0, sizeof(S2) - offsetof(FourUInts, inner)); // BAD
memset(&f.inner.c, 0, sizeof(S2) - offsetof(FourUInts, x)); // GOOD
memset(&f.inner.c, 0, sizeof(S2) - offsetof(S2, f)); // BAD
memset(&f.inner.c, 0, sizeof(S2) - offsetof(S2, u)); // GOOD
memset(&f.inner, 0, sizeof(S2) - offsetof(ThreeUInts, a)); // GOOD
memset(&f.inner, 0, sizeof(S2) - offsetof(ThreeUInts, b)); // GOOD
memset(&f.inner, 0, sizeof(S2) - offsetof(ThreeUInts, c)); // GOOD
memset(&f.inner, 0, sizeof(S2) - offsetof(FourUInts, inner)); // GOOD
memset(&f.inner, 0, sizeof(S2) - offsetof(FourUInts, x)); // GOOD
memset(&f.inner, 0, sizeof(S2) - offsetof(S2, f)); // GOOD
memset(&f.inner, 0, sizeof(S2) - offsetof(S2, u)); // GOOD
memset(&f.x, 0, sizeof(S2) - offsetof(ThreeUInts, a)); // BAD
memset(&f.x, 0, sizeof(S2) - offsetof(ThreeUInts, b)); // BAD
memset(&f.x, 0, sizeof(S2) - offsetof(ThreeUInts, c)); // BAD
memset(&f.x, 0, sizeof(S2) - offsetof(FourUInts, inner)); // BAD
memset(&f.x, 0, sizeof(S2) - offsetof(FourUInts, x)); // GOOD
memset(&f.x, 0, sizeof(S2) - offsetof(S2, f)); // GOOD
memset(&f.x, 0, sizeof(S2) - offsetof(S2, u)); // GOOD
memset(&f, 0, sizeof(S2) - offsetof(ThreeUInts, a)); // GOOD
memset(&f, 0, sizeof(S2) - offsetof(ThreeUInts, b)); // GOOD
memset(&f, 0, sizeof(S2) - offsetof(ThreeUInts, c)); // GOOD
memset(&f, 0, sizeof(S2) - offsetof(FourUInts, inner)); // GOOD
memset(&f, 0, sizeof(S2) - offsetof(FourUInts, x)); // GOOD
memset(&f, 0, sizeof(S2) - offsetof(S2, f)); // GOOD
memset(&f, 0, sizeof(S2) - offsetof(S2, u)); // GOOD
memset(&u, 0, sizeof(S2) - offsetof(ThreeUInts, a)); // BAD
memset(&u, 0, sizeof(S2) - offsetof(ThreeUInts, b)); // BAD
memset(&u, 0, sizeof(S2) - offsetof(ThreeUInts, c)); // BAD
memset(&u, 0, sizeof(S2) - offsetof(FourUInts, inner)); // BAD
memset(&u, 0, sizeof(S2) - offsetof(FourUInts, x)); // BAD
memset(&u, 0, sizeof(S2) - offsetof(S2, f)); // BAD
memset(&u, 0, sizeof(S2) - offsetof(S2, u)); // GOOD
}
};
int tests_main(int argc, char *argv[])
{

View File

@@ -46,7 +46,9 @@ namespace Semmle.Autobuild.CSharp
return WithDotNet(builder, ensureDotNetAvailable: false, (dotNetPath, environment) =>
{
var ret = GetInfoCommand(builder.Actions, dotNetPath, environment);
// When a custom .NET CLI has been installed, `dotnet --info` has already been executed
// to verify the installation.
var ret = dotNetPath is null ? GetInfoCommand(builder.Actions, dotNetPath, environment) : BuildScript.Success;
foreach (var projectOrSolution in builder.ProjectsOrSolutionsToBuild)
{
var cleanCommand = GetCleanCommand(builder.Actions, dotNetPath, environment);

View File

@@ -41,7 +41,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private int conflictedReferences = 0;
private readonly DirectoryInfo sourceDir;
private string? dotnetPath;
private readonly TemporaryDirectory tempWorkingDirectory;
private readonly bool cleanupTempWorkingDirectory;

View File

@@ -19,17 +19,20 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private readonly ILogger logger;
private readonly TemporaryDirectory? tempWorkingDirectory;
private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, TemporaryDirectory? tempWorkingDirectory = null)
private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, bool runDotnetInfo, TemporaryDirectory? tempWorkingDirectory = null)
{
this.tempWorkingDirectory = tempWorkingDirectory;
this.dotnetCliInvoker = dotnetCliInvoker;
this.logger = logger;
Info();
if (runDotnetInfo)
{
Info();
}
}
private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, tempWorkingDirectory) { }
private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, dotNetPath is null, tempWorkingDirectory) { }
internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger) => new DotNet(dotnetCliInvoker, logger);
internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, bool runDotnetInfo) => new DotNet(dotnetCliInvoker, logger, runDotnetInfo);
public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) => new DotNet(logger, dotNetPath, tempWorkingDirectory, dependabotProxy);
@@ -169,7 +172,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
if (versions.Count > 0)
{
return DownloadDotNetVersion(actions, logger, tempWorkingDirectory, shouldCleanUp, installDir, versions);
return
DownloadDotNetVersion(actions, logger, tempWorkingDirectory, shouldCleanUp, installDir, versions) |
// if neither of the versions succeed, try the latest version
DownloadDotNetVersion(actions, logger, tempWorkingDirectory, shouldCleanUp, installDir, [LatestDotNetSdkVersion], needExactVersion: false);
}
if (ensureDotNetAvailable)
@@ -269,6 +275,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
Argument(path).Script;
}
var dotnetInfo = new CommandBuilder(actions).
RunCommand(actions.PathCombine(path, "dotnet")).
Argument("--info").Script;
Func<string, BuildScript> getInstallAndVerify = version =>
// run `dotnet --info` after install, to check that it executes successfully
getInstall(version) & dotnetInfo;
var installScript = prelude & BuildScript.Failure;
var attempted = new HashSet<string>();
@@ -283,7 +297,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
// When there are multiple versions requested, we want to try to fetch them all, reporting
// a successful exit code when at least one of them succeeds
return combinedExit != 0 ? getInstall(version) : BuildScript.Bind(getInstall(version), _ => BuildScript.Success);
return combinedExit != 0 ? getInstallAndVerify(version) : BuildScript.Bind(getInstallAndVerify(version), _ => BuildScript.Success);
});
}

View File

@@ -45,7 +45,7 @@ namespace Semmle.Extraction.Tests
public class DotNetTests
{
private static IDotNet MakeDotnet(IDotNetCliInvoker dotnetCliInvoker) =>
DotNet.Make(dotnetCliInvoker, new LoggerStub());
DotNet.Make(dotnetCliInvoker, new LoggerStub(), true);
private static IList<string> MakeDotnetRestoreOutput() =>
new List<string> {

View File

@@ -3,7 +3,6 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

View File

@@ -1,5 +1,5 @@
{
"sdk": {
"version": "5.0.408"
"version": "9.0.100"
}
}

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="BlazorTest.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html>

View File

@@ -0,0 +1,23 @@
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>

View File

@@ -0,0 +1,96 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}
.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}
.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}
.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}

View File

@@ -0,0 +1,19 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">BlazorTest</a>
</div>
</div>
<input type="checkbox" title="Navigation menu" class="navbar-toggler" />
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="test">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Test
</NavLink>
</div>
</nav>
</div>

View File

@@ -0,0 +1,105 @@
.navbar-toggler {
appearance: none;
cursor: pointer;
width: 3.5rem;
height: 2.5rem;
color: white;
position: absolute;
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked {
background-color: rgba(255, 255, 255, 0.5);
}
.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand {
font-size: 1.1rem;
}
.bi {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}
.bi-house-door-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}
.bi-plus-square-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}
.bi-list-nested-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item ::deep .nav-link {
color: #d7d7d7;
background: none;
border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
width: 100%;
}
.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}
.nav-item ::deep .nav-link:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.nav-scrollable {
display: none;
}
.navbar-toggler:checked ~ .nav-scrollable {
display: block;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.nav-scrollable {
/* Never collapse the sidebar for wide screens */
display: block;
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}

View File

@@ -0,0 +1,20 @@
@rendermode InteractiveServer
<input @bind="Param1" @bind:event="onchange" @bind:after="Fire">
@code {
[Parameter]
public string? Param1 { get; set; } = "";
[Parameter]
public EventCallback<string?> ValueChanged { get; set; }
[Parameter]
public EventCallback<string?> Param1Changed { get; set; }
private void Fire()
{
ValueChanged.InvokeAsync(Param1);
Param1Changed.InvokeAsync(Param1);
}
}

View File

@@ -0,0 +1,11 @@
@rendermode InteractiveServer
<div>
<p>Value from InputText: @Value</p>
<p>Raw value from InputText: @(new MarkupString(Value))</p>
</div>
@code {
[Parameter]
public string Value { get; set; } = "";
}

View File

@@ -0,0 +1,36 @@
@page "/Error"
@using System.Diagnostics
<PageTitle>Error</PageTitle>
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
@code{
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}

View File

@@ -0,0 +1,125 @@
@page "/"
@page "/test/{urlParam?}"
@rendermode InteractiveServer
<PageTitle>TestPage</PageTitle>
<div>
<h3>Route parameter</h3>
<p>Go to: <a href="/test/@XssUrl">/test/@XssUrl</a></p>
<p>Parameter from URL: @UrlParam</p>
<p>Raw parameter from URL: @((MarkupString)UrlParam)</p>
</div>
<hr />
<div>
<h3>Query parameter</h3>
<p>Go to: <a href="/test/?qs=@XssUrl">/test/?qs=@XssUrl</a></p>
<p>Parameter from query string: @QueryParam</p>
<p>Raw parameter from query string: @(new MarkupString(QueryParam))</p>
</div>
<hr />
<div>
<h3>Bind InputText component</h3>
<InputText @bind-Value="InputValue1" />
<p>Value from InputText: @InputValue1</p>
<p>Raw value from InputText: @(new MarkupString(InputValue1))</p>
</div>
<hr />
<div>
<h3>Bind input element</h3>
<input @bind="InputValue2">
<p>Value from InputText: @InputValue2</p>
<p>Raw value from InputText: @(new MarkupString(InputValue2))</p>
</div>
<hr />
<div>
<h3>Bind through object property</h3>
<input @bind="Container1.Value">
<p>Value from InputText: @Container1.Value</p>
<p>Raw value from InputText: @(new MarkupString(Container1.Value))</p>
</div>
<hr />
<div>
<h3>Input component with custom event</h3>
<MyInput Param1="@InputValue3" ValueChanged="MyInputChanged" />
<p>Value from InputText: @InputValue3</p>
<p>Raw value from InputText: @(new MarkupString(InputValue3))</p>
</div>
<hr />
<div>
<h3>Input component with binding</h3>
<MyInput @bind-Param1="InputValue4" />
<p>Value from InputText: @InputValue4</p>
<p>Raw value from InputText: @(new MarkupString(InputValue4))</p>
</div>
<hr />
<div>
<h3>Input, Output components</h3>
<MyInput @bind-Param1="InputValue5" />
<MyOutput Value="@InputValue5" />
</div>
<hr />
<div>
<h3>Bind InputText, Output component</h3>
<InputText @bind-Value="InputValue6" />
<MyOutput Value="@InputValue6" />
</div>
@code {
public class Container
{
public string? Value { get; set; } = "";
}
private const string XssUrl = "<b>aaaa<%2Fb>";
private const string XssUrl2 = "<b>aaaa</b>";
[Parameter]
public string UrlParam { get; set; } = "";
[SupplyParameterFromQuery(Name = "qs")]
public string QueryParam { get; set; } = "";
public string InputValue1 { get; set; } = "";
public string InputValue2 { get; set; } = "";
public string InputValue3 { get; set; } = "";
public string InputValue4 { get; set; } = "";
public string InputValue5 { get; set; } = "";
public string InputValue6 { get; set; } = "";
public Container Container1 { get; set; } = new Container();
protected override void OnInitialized()
{
InputValue1 = XssUrl2;
InputValue2 = XssUrl2;
Container1.Value = XssUrl2;
InputValue3 = XssUrl2;
InputValue4 = XssUrl2;
InputValue5 = XssUrl2;
InputValue6 = XssUrl2;
}
private void MyInputChanged(string value)
{
InputValue3 = value;
}
}

View File

@@ -0,0 +1,6 @@
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

View File

@@ -0,0 +1,10 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using BlazorTest
@using BlazorTest.Components

View File

@@ -0,0 +1,27 @@
using BlazorTest.Components;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();

View File

@@ -0,0 +1,14 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5047",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,5 @@
{
"sdk": {
"version": "9.0.100"
}
}

View File

@@ -0,0 +1,51 @@
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
a, .btn-link {
color: #006bb7;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
.content {
padding-top: 1.1rem;
}
h1:focus {
outline: none;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid #e50000;
}
.validation-message {
color: #e50000;
}
.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
padding: 1rem 1rem 1rem 3.7rem;
color: white;
}
.blazor-error-boundary::after {
content: "An error has occurred."
}
.darker-border-checkbox.form-check-input {
border-color: #929292;
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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