mirror of
https://github.com/github/codeql.git
synced 2026-04-19 22:14:01 +02:00
Merge branch 'main' into redsun82/env-dump-integration-test
This commit is contained in:
3
.bazelrc
3
.bazelrc
@@ -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
|
||||
|
||||
14
.github/pull_request_template.md
vendored
14
.github/pull_request_template.md
vendored
@@ -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).
|
||||
15
MODULE.bazel
15
MODULE.bazel
@@ -14,7 +14,7 @@ local_path_override(
|
||||
|
||||
# see https://registry.bazel.build/ for a list of available packages
|
||||
|
||||
bazel_dep(name = "platforms", version = "0.0.10")
|
||||
bazel_dep(name = "platforms", version = "0.0.11")
|
||||
bazel_dep(name = "rules_go", version = "0.50.1")
|
||||
bazel_dep(name = "rules_pkg", version = "1.0.1")
|
||||
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
|
||||
@@ -28,7 +28,7 @@ bazel_dep(name = "rules_kotlin", version = "2.0.0-codeql.1")
|
||||
bazel_dep(name = "gazelle", version = "0.40.0")
|
||||
bazel_dep(name = "rules_dotnet", version = "0.17.4")
|
||||
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
|
||||
bazel_dep(name = "rules_rust", version = "0.52.2")
|
||||
bazel_dep(name = "rules_rust", version = "0.57.1")
|
||||
bazel_dep(name = "zstd", version = "1.5.5.bcr.1")
|
||||
|
||||
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
|
||||
@@ -53,15 +53,6 @@ use_repo(rust, "rust_toolchains")
|
||||
|
||||
register_toolchains("@rust_toolchains//:all")
|
||||
|
||||
rust_host_tools = use_extension("@rules_rust//rust:extensions.bzl", "rust_host_tools")
|
||||
|
||||
# Don't download a second toolchain as host toolchain, make sure this is the same version as above
|
||||
# The host toolchain is used for vendoring dependencies.
|
||||
rust_host_tools.host_tools(
|
||||
edition = RUST_EDITION,
|
||||
version = RUST_VERSION,
|
||||
)
|
||||
|
||||
# deps for python extractor
|
||||
# keep in sync by running `misc/bazel/3rdparty/update_cargo_deps.sh`
|
||||
py_deps = use_extension("//misc/bazel/3rdparty:py_deps_extension.bzl", "p")
|
||||
@@ -252,7 +243,7 @@ use_repo(
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.23.1")
|
||||
go_sdk.download(version = "1.24.0")
|
||||
|
||||
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//go/extractor:go.mod")
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
## 0.4.2
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed data for vulnerable versions of `actions/download-artifact` and `rlespinasse/github-slug-action` (following GHSA-cxww-7g56-2vh6 and GHSA-6q4m-7476-932w).
|
||||
* Improved `untrustedGhCommandDataModel` regex for `gh pr view` and Bash taint analysis in GitHub Actions.
|
||||
|
||||
## 0.4.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* The "Unpinned tag for a non-immutable Action in workflow" query (`actions/unpinned-tag`) now supports expanding the trusted action owner list using data extensions (`extensible: trustedActionsOwnerDataModel`). If you trust an Action publisher, you can include the owner name/organization in a model pack to add it to the allow list for this query. This addition will prevent security alerts when using unpinned tags for Actions published by that owner. For more information on creating a model pack, see [Creating a CodeQL Model Pack](https://docs.github.com/en/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/creating-and-working-with-codeql-packs#creating-a-codeql-model-pack).
|
||||
6
actions/ql/lib/change-notes/released/0.4.2.md
Normal file
6
actions/ql/lib/change-notes/released/0.4.2.md
Normal file
@@ -0,0 +1,6 @@
|
||||
## 0.4.2
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed data for vulnerable versions of `actions/download-artifact` and `rlespinasse/github-slug-action` (following GHSA-cxww-7g56-2vh6 and GHSA-6q4m-7476-932w).
|
||||
* Improved `untrustedGhCommandDataModel` regex for `gh pr view` and Bash taint analysis in GitHub Actions.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.1
|
||||
lastReleaseVersion: 0.4.2
|
||||
|
||||
@@ -81,7 +81,9 @@ class BashShellScript extends ShellScript {
|
||||
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
|
||||
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
|
||||
)
|
||||
)
|
||||
) and
|
||||
// Only do this for strings that might otherwise disrupt subsequent parsing
|
||||
quotedStr.regexpMatch("[\"'].*[$\n\r'\"" + Bash::separator() + "].*[\"']")
|
||||
}
|
||||
|
||||
private predicate rankedQuotedStringReplacements(int i, string old, string new) {
|
||||
@@ -695,6 +697,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)
|
||||
|
||||
@@ -126,6 +126,15 @@ predicate vulnerableActionsDataModel(
|
||||
*/
|
||||
predicate immutableActionsDataModel(string action) { Extensions::immutableActionsDataModel(action) }
|
||||
|
||||
/**
|
||||
* MaD models for trusted actions owners
|
||||
* Fields:
|
||||
* - owner: owner name
|
||||
*/
|
||||
predicate trustedActionsOwnerDataModel(string owner) {
|
||||
Extensions::trustedActionsOwnerDataModel(owner)
|
||||
}
|
||||
|
||||
/**
|
||||
* MaD models for untrusted git commands
|
||||
* Fields:
|
||||
|
||||
@@ -63,6 +63,11 @@ extensible predicate vulnerableActionsDataModel(
|
||||
*/
|
||||
extensible predicate immutableActionsDataModel(string action);
|
||||
|
||||
/**
|
||||
* Holds for trusted Actions owners.
|
||||
*/
|
||||
extensible predicate trustedActionsOwnerDataModel(string owner);
|
||||
|
||||
/**
|
||||
* Holds for git commands that may introduce untrusted data when called on an attacker controlled branch.
|
||||
*/
|
||||
|
||||
@@ -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>;
|
||||
|
||||
8
actions/ql/lib/ext/config/trusted_actions_owner.yml
Normal file
8
actions/ql/lib/ext/config/trusted_actions_owner.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/actions-all
|
||||
extensible: trustedActionsOwnerDataModel
|
||||
data:
|
||||
- ["actions"]
|
||||
- ["github"]
|
||||
- ["advanced-security"]
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.2-dev
|
||||
version: 0.4.3-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 0.4.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
* @name PATH Enviroment Variable built from user-controlled sources
|
||||
* @description Building the PATH environment variable from user-controlled sources may alter the execution of following system commands
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @problem.severity error
|
||||
* @security-severity 5.0
|
||||
* @precision high
|
||||
* @precision medium
|
||||
* @id actions/envpath-injection/medium
|
||||
* @tags actions
|
||||
* security
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
* @name Enviroment Variable built from user-controlled sources
|
||||
* @description Building an environment variable from user-controlled sources may alter the execution of following system commands
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @problem.severity error
|
||||
* @security-severity 5.0
|
||||
* @precision high
|
||||
* @precision medium
|
||||
* @id actions/envvar-injection/medium
|
||||
* @tags actions
|
||||
* security
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
* @description Workflows should contain permissions to provide a clear understanding has permissions to run the workflow.
|
||||
* @kind problem
|
||||
* @security-severity 5.0
|
||||
* @problem.severity recommendation
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
* @id actions/missing-workflow-permissions
|
||||
* @tags actions
|
||||
* maintainability
|
||||
* security
|
||||
* external/cwe/cwe-275
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
* @name Excessive Secrets Exposure
|
||||
* @description All organization and repository secrets are passed to the workflow runner.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @precision high
|
||||
* @problem.severity warning
|
||||
* @id actions/excessive-secrets-exposure
|
||||
* @tags actions
|
||||
* security
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* @name Artifact poisoning
|
||||
* @description An attacker may be able to poison the workflow's artifacts and influence on consequent steps.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
* @problem.severity error
|
||||
* @precision medium
|
||||
* @security-severity 5.0
|
||||
* @id actions/artifact-poisoning/medium
|
||||
* @tags actions
|
||||
|
||||
@@ -24,4 +24,4 @@ Pinning an action to a full length commit SHA is currently the only way to use a
|
||||
|
||||
## References
|
||||
|
||||
- [Using third-party actions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions)
|
||||
- [Using third-party actions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions)
|
||||
@@ -3,8 +3,8 @@
|
||||
* @description Using a tag for a non-immutable Action that is not pinned to a commit can lead to executing an untrusted Action through a supply chain attack.
|
||||
* @kind problem
|
||||
* @security-severity 5.0
|
||||
* @problem.severity recommendation
|
||||
* @precision high
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @id actions/unpinned-tag
|
||||
* @tags security
|
||||
* actions
|
||||
@@ -17,14 +17,15 @@ import codeql.actions.security.UseOfUnversionedImmutableAction
|
||||
bindingset[version]
|
||||
private predicate isPinnedCommit(string version) { version.regexpMatch("^[A-Fa-f0-9]{40}$") }
|
||||
|
||||
bindingset[repo]
|
||||
private predicate isTrustedOrg(string repo) {
|
||||
repo.matches(["actions", "github", "advanced-security"] + "/%")
|
||||
bindingset[nwo]
|
||||
private predicate isTrustedOwner(string nwo) {
|
||||
// Gets the segment before the first '/' in the name with owner(nwo) string
|
||||
trustedActionsOwnerDataModel(nwo.substring(0, nwo.indexOf("/")))
|
||||
}
|
||||
|
||||
from UsesStep uses, string repo, string version, Workflow workflow, string name
|
||||
from UsesStep uses, string nwo, string version, Workflow workflow, string name
|
||||
where
|
||||
uses.getCallee() = repo and
|
||||
uses.getCallee() = nwo and
|
||||
uses.getEnclosingWorkflow() = workflow and
|
||||
(
|
||||
workflow.getName() = name
|
||||
@@ -32,9 +33,9 @@ where
|
||||
not exists(workflow.getName()) and workflow.getLocation().getFile().getBaseName() = name
|
||||
) and
|
||||
uses.getVersion() = version and
|
||||
not isTrustedOrg(repo) and
|
||||
not isTrustedOwner(nwo) and
|
||||
not isPinnedCommit(version) and
|
||||
not isImmutableAction(uses, repo)
|
||||
not isImmutableAction(uses, nwo)
|
||||
select uses.getCalleeNode(),
|
||||
"Unpinned 3rd party Action '" + name + "' step $@ uses '" + repo + "' with ref '" + version +
|
||||
"Unpinned 3rd party Action '" + name + "' step $@ uses '" + nwo + "' with ref '" + version +
|
||||
"', not a pinned commit hash", uses, uses.toString()
|
||||
|
||||
20
actions/ql/src/change-notes/2025-02-06-curate-suites.md
Normal file
20
actions/ql/src/change-notes/2025-02-06-curate-suites.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* The following queries have been removed from the `code-scanning` and `security-extended` suites.
|
||||
Any existing alerts for these queries will be closed automatically.
|
||||
* `actions/if-expression-always-true/critical`
|
||||
* `actions/if-expression-always-true/high`
|
||||
* `actions/unnecessary-use-of-advanced-config`
|
||||
|
||||
* The following query has been moved from the `code-scanning` suite to the `security-extended`
|
||||
suite. Any existing alerts for this query will be closed automatically unless the analysis is
|
||||
configured to use the `security-extended` suite.
|
||||
* `actions/unpinned-tag`
|
||||
* The following queries have been added to the `security-extended` suite.
|
||||
* `actions/unversioned-immutable-action`
|
||||
* `actions/envpath-injection/medium`
|
||||
* `actions/envvar-injection/medium`
|
||||
* `actions/code-injection/medium`
|
||||
* `actions/artifact-poisoning/medium`
|
||||
* `actions/untrusted-checkout/medium`
|
||||
3
actions/ql/src/change-notes/released/0.4.2.md
Normal file
3
actions/ql/src/change-notes/released/0.4.2.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.2
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.1
|
||||
lastReleaseVersion: 0.4.2
|
||||
|
||||
1
actions/ql/src/codeql-suites/actions-ccr.qls
Normal file
1
actions/ql/src/codeql-suites/actions-ccr.qls
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -1,11 +1,4 @@
|
||||
- description: Standard Code Scanning queries for GitHub Actions
|
||||
- queries: '.'
|
||||
- include:
|
||||
problem.severity:
|
||||
- error
|
||||
- recommendation
|
||||
- exclude:
|
||||
tags contain:
|
||||
- experimental
|
||||
- debug
|
||||
- internal
|
||||
- queries: .
|
||||
- apply: code-scanning-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
- description: Security-extended queries for GitHub Actions
|
||||
- import: codeql-suites/actions-code-scanning.qls
|
||||
- queries: .
|
||||
- apply: security-extended-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.4.2-dev
|
||||
version: 0.4.3-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
18
actions/ql/test/library-tests/.github/workflows/many_strings.yml
vendored
Normal file
18
actions/ql/test/library-tests/.github/workflows/many_strings.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Prev"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
Test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: |
|
||||
# Avoid choking on large chunks of data containing quotes
|
||||
echo '["string1", "string2", "string3", "string4", "string5", "string6", "string7", "string8", "string9", "string10", "string11", "string12", "string13", "string14", "string15", "string16", "string17", "string18", "string19", "string20", "string21", "string22", "string23", "string24", "string25", "string26", "string27", "string28", "string29", "string30", "string31", "string32", "string33", "string34", "string35", "string36", "string37", "string38", "string39", "string40", "string41", "string42", "string43", "string44", "string45", "string46", "string47", "string48", "string49", "string50", "string51", "string52", "string53", "string54", "string55", "string56", "string57", "string58", "string59", "string60", "string61", "string62", "string63", "string64", "string65", "string66", "string67", "string68", "string69", "string70", "string71", "string72", "string73", "string74", "string75", "string76", "string77", "string78", "string79", "string80", "string81", "string82", "string83", "string84", "string85", "string86", "string87", "string88", "string89", "string90", "string91", "string92", "string93", "string94", "string95", "string96", "string97", "string98", "string99", "string100"]'
|
||||
echo "['string1', 'string2', 'string3', 'string4', 'string5', 'string6', 'string7', 'string8', 'string9', 'string10', 'string11', 'string12', 'string13', 'string14', 'string15', 'string16', 'string17', 'string18', 'string19', 'string20', 'string21', 'string22', 'string23', 'string24', 'string25', 'string26', 'string27', 'string28', 'string29', 'string30', 'string31', 'string32', 'string33', 'string34', 'string35', 'string36', 'string37', 'string38', 'string39', 'string40', 'string41', 'string42', 'string43', 'string44', 'string45', 'string46', 'string47', 'string48', 'string49', 'string50', 'string51', 'string52', 'string53', 'string54', 'string55', 'string56', 'string57', 'string58', 'string59', 'string60', 'string61', 'string62', 'string63', 'string64', 'string65', 'string66', 'string67', 'string68', 'string69', 'string70', 'string71', 'string72', 'string73', 'string74', 'string75', 'string76', 'string77', 'string78', 'string79', 'string80', 'string81', 'string82', 'string83', 'string84', 'string85', 'string86', 'string87', 'string88', 'string89', 'string90', 'string91', 'string92', 'string93', 'string94', 'string95', 'string96', 'string97', 'string98', 'string99', 'string100']"
|
||||
|
||||
# Same as above but where each line has an unbalanced internal quote near the end
|
||||
echo '["string1", "string2", "string3", "string4", "string5", "string6", "string7", "string8", "string9", "string10", "string11", "string12", "string13", "string14", "string15", "string16", "string17", "string18", "string19", "string20", "string21", "string22", "string23", "string24", "string25", "string26", "string27", "string28", "string29", "string30", "string31", "string32", "string33", "string34", "string35", "string36", "string37", "string38", "string39", "string40", "string41", "string42", "string43", "string44", "string45", "string46", "string47", "string48", "string49", "string50", "string51", "string52", "string53", "string54", "string55", "string56", "string57", "string58", "string59", "string60", "string61", "string62", "string63", "string64", "string65", "string66", "string67", "string68", "string69", "string70", "string71", "string72", "string73", "string74", "string75", "string76", "string77", "string78", "string79", "string80", "string81", "string82", "string83", "string84", "string85", "string86", "string87", "string88", "string89", "string90", "string91", "string92", "string93", "string94", "string95", "string96", "string97", "string98", "string99", "string100"]"'
|
||||
echo "['string1', 'string2', 'string3', 'string4', 'string5', 'string6', 'string7', 'string8', 'string9', 'string10', 'string11', 'string12', 'string13', 'string14', 'string15', 'string16', 'string17', 'string18', 'string19', 'string20', 'string21', 'string22', 'string23', 'string24', 'string25', 'string26', 'string27', 'string28', 'string29', 'string30', 'string31', 'string32', 'string33', 'string34', 'string35', 'string36', 'string37', 'string38', 'string39', 'string40', 'string41', 'string42', 'string43', 'string44', 'string45', 'string46', 'string47', 'string48', 'string49', 'string50', 'string51', 'string52', 'string53', 'string54', 'string55', 'string56', 'string57', 'string58', 'string59', 'string60', 'string61', 'string62', 'string63', 'string64', 'string65', 'string66', 'string67', 'string68', 'string69', 'string70', 'string71', 'string72', 'string73', 'string74', 'string75', 'string76', 'string77', 'string78', 'string79', 'string80', 'string81', 'string82', 'string83', 'string84', 'string85', 'string86', 'string87', 'string88', 'string89', 'string90', 'string91', 'string92', 'string93', 'string94', 'string95', 'string96', 'string97', 'string98', 'string99', 'string100']'"
|
||||
@@ -25,6 +25,10 @@
|
||||
| .github/workflows/expression_nodes.yml:16:9:20:6 | Run Step | LINE 2 echo '${{github.event.issue.body}}' |
|
||||
| .github/workflows/expression_nodes.yml:16:9:20:6 | Run Step | LINE 3 echo '${{ github.event.comment.body }}' |
|
||||
| .github/workflows/expression_nodes.yml:20:9:21:47 | Run Step | LINE 1 echo '${{ github.event.comment.body }}' echo '${{github.event.issue.body}}' |
|
||||
| .github/workflows/many_strings.yml:11:9:18:1211 | Run Step | echo "['string1', 'string2', 'string3', 'string4', 'string5', 'string6', 'string7', 'string8', 'string9', 'string10', 'string11', 'string12', 'string13', 'string14', 'string15', 'string16', 'string17', 'string18', 'string19', 'string20', 'string21', 'string22', 'string23', 'string24', 'string25', 'string26', 'string27', 'string28', 'string29', 'string30', 'string31', 'string32', 'string33', 'string34', 'string35', 'string36', 'string37', 'string38', 'string39', 'string40', 'string41', 'string42', 'string43', 'string44', 'string45', 'string46', 'string47', 'string48', 'string49', 'string50', 'string51', 'string52', 'string53', 'string54', 'string55', 'string56', 'string57', 'string58', 'string59', 'string60', 'string61', 'string62', 'string63', 'string64', 'string65', 'string66', 'string67', 'string68', 'string69', 'string70', 'string71', 'string72', 'string73', 'string74', 'string75', 'string76', 'string77', 'string78', 'string79', 'string80', 'string81', 'string82', 'string83', 'string84', 'string85', 'string86', 'string87', 'string88', 'string89', 'string90', 'string91', 'string92', 'string93', 'string94', 'string95', 'string96', 'string97', 'string98', 'string99', 'string100']" |
|
||||
| .github/workflows/many_strings.yml:11:9:18:1211 | Run Step | echo "['string1', 'string2', 'string3', 'string4', 'string5', 'string6', 'string7', 'string8', 'string9', 'string10', 'string11', 'string12', 'string13', 'string14', 'string15', 'string16', 'string17', 'string18', 'string19', 'string20', 'string21', 'string22', 'string23', 'string24', 'string25', 'string26', 'string27', 'string28', 'string29', 'string30', 'string31', 'string32', 'string33', 'string34', 'string35', 'string36', 'string37', 'string38', 'string39', 'string40', 'string41', 'string42', 'string43', 'string44', 'string45', 'string46', 'string47', 'string48', 'string49', 'string50', 'string51', 'string52', 'string53', 'string54', 'string55', 'string56', 'string57', 'string58', 'string59', 'string60', 'string61', 'string62', 'string63', 'string64', 'string65', 'string66', 'string67', 'string68', 'string69', 'string70', 'string71', 'string72', 'string73', 'string74', 'string75', 'string76', 'string77', 'string78', 'string79', 'string80', 'string81', 'string82', 'string83', 'string84', 'string85', 'string86', 'string87', 'string88', 'string89', 'string90', 'string91', 'string92', 'string93', 'string94', 'string95', 'string96', 'string97', 'string98', 'string99', 'string100']'" |
|
||||
| .github/workflows/many_strings.yml:11:9:18:1211 | Run Step | echo '["string1", "string2", "string3", "string4", "string5", "string6", "string7", "string8", "string9", "string10", "string11", "string12", "string13", "string14", "string15", "string16", "string17", "string18", "string19", "string20", "string21", "string22", "string23", "string24", "string25", "string26", "string27", "string28", "string29", "string30", "string31", "string32", "string33", "string34", "string35", "string36", "string37", "string38", "string39", "string40", "string41", "string42", "string43", "string44", "string45", "string46", "string47", "string48", "string49", "string50", "string51", "string52", "string53", "string54", "string55", "string56", "string57", "string58", "string59", "string60", "string61", "string62", "string63", "string64", "string65", "string66", "string67", "string68", "string69", "string70", "string71", "string72", "string73", "string74", "string75", "string76", "string77", "string78", "string79", "string80", "string81", "string82", "string83", "string84", "string85", "string86", "string87", "string88", "string89", "string90", "string91", "string92", "string93", "string94", "string95", "string96", "string97", "string98", "string99", "string100"]"' |
|
||||
| .github/workflows/many_strings.yml:11:9:18:1211 | Run Step | echo '["string1", "string2", "string3", "string4", "string5", "string6", "string7", "string8", "string9", "string10", "string11", "string12", "string13", "string14", "string15", "string16", "string17", "string18", "string19", "string20", "string21", "string22", "string23", "string24", "string25", "string26", "string27", "string28", "string29", "string30", "string31", "string32", "string33", "string34", "string35", "string36", "string37", "string38", "string39", "string40", "string41", "string42", "string43", "string44", "string45", "string46", "string47", "string48", "string49", "string50", "string51", "string52", "string53", "string54", "string55", "string56", "string57", "string58", "string59", "string60", "string61", "string62", "string63", "string64", "string65", "string66", "string67", "string68", "string69", "string70", "string71", "string72", "string73", "string74", "string75", "string76", "string77", "string78", "string79", "string80", "string81", "string82", "string83", "string84", "string85", "string86", "string87", "string88", "string89", "string90", "string91", "string92", "string93", "string94", "string95", "string96", "string97", "string98", "string99", "string100"]' |
|
||||
| .github/workflows/multiline2.yml:11:9:15:6 | Run Step | echo "CHANGELOGEOF" |
|
||||
| .github/workflows/multiline2.yml:11:9:15:6 | Run Step | echo "changelog< |
|
||||
| .github/workflows/multiline2.yml:11:9:15:6 | Run Step | echo -e "$FILTERED_CHANGELOG" |
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
Security/CWE-074/OutputClobberingHigh.ql
|
||||
experimental/Security/CWE-074/OutputClobberingHigh.ql
|
||||
|
||||
@@ -1 +1 @@
|
||||
Security/CWE-078/CommandInjectionCritical.ql
|
||||
experimental/Security/CWE-078/CommandInjectionCritical.ql
|
||||
|
||||
@@ -1 +1 @@
|
||||
Security/CWE-078/CommandInjectionMedium.ql
|
||||
experimental/Security/CWE-078/CommandInjectionMedium.ql
|
||||
|
||||
@@ -1 +1 @@
|
||||
Security/CWE-088/ArgumentInjectionCritical.ql
|
||||
experimental/Security/CWE-088/ArgumentInjectionCritical.ql
|
||||
|
||||
@@ -1 +1 @@
|
||||
Security/CWE-088/ArgumentInjectionMedium.ql
|
||||
experimental/Security/CWE-088/ArgumentInjectionMedium.ql
|
||||
|
||||
@@ -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}}"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
Security/CWE-200/SecretExfiltration.ql
|
||||
experimental/Security/CWE-200/SecretExfiltration.ql
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
Security/CWE-284/CodeExecutionOnSelfHostedRunner.ql
|
||||
experimental/Security/CWE-284/CodeExecutionOnSelfHostedRunner.ql
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
Security/CWE-829/ArtifactPoisoningPathTraversal.ql
|
||||
experimental/Security/CWE-829/ArtifactPoisoningPathTraversal.ql
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
Security/CWE-918/RequestForgery.ql
|
||||
experimental/Security/CWE-918/RequestForgery.ql
|
||||
|
||||
2444
cpp/downgrades/e594389175c098d7225683d0fd8cefcc47d84bc1/old.dbscheme
Normal file
2444
cpp/downgrades/e594389175c098d7225683d0fd8cefcc47d84bc1/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: Mix typedefs and usings
|
||||
compatibility: full
|
||||
usertypes.rel: run usertypes.qlo
|
||||
usertype_alias_kind.rel: delete
|
||||
@@ -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)
|
||||
@@ -1,3 +1,15 @@
|
||||
## 4.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Deleted the deprecated `getAllocatorCall` predicate from `DeleteOrDeleteArrayExpr`, use `getDeallocatorCall` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* A new predicate `getOffsetInClass` was added to the `Field` class, which computes the byte offset of a field relative to a given `Class`.
|
||||
* New classes `PreprocessorElifdef` and `PreprocessorElifndef` were introduced, which represents the C23/C++23 `#elifdef` and `#elifndef` preprocessor directives.
|
||||
* A new class `TypeLibraryImport` was introduced, which represents the `#import` preprocessor directive as used by the Microsoft Visual C++ for importing type libraries.
|
||||
|
||||
## 3.2.0
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
## 4.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Deleted the deprecated `getAllocatorCall` predicate from `DeleteOrDeleteArrayExpr`, use `getDeallocatorCall` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* A new predicate `getOffsetInClass` was added to the `Field` class, which computes the byte offset of a field relative to a given `Class`.
|
||||
* New classes `PreprocessorElifdef` and `PreprocessorElifndef` were introduced, which represents the C23/C++23 `#elifdef` and `#elifndef` preprocessor directives.
|
||||
* A new class `TypeLibraryImport` was introduced, which represents the `#import` preprocessor directive as used by the Microsoft Visual C++ for importing type libraries.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 3.2.0
|
||||
lastReleaseVersion: 4.0.0
|
||||
|
||||
@@ -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_%")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 3.2.1-dev
|
||||
version: 4.0.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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" }
|
||||
|
||||
|
||||
@@ -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() }
|
||||
|
||||
@@ -24,6 +24,78 @@ 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
|
||||
// We strip the type because the root may be a pointer. For example `p` in:
|
||||
// struct S { char buffer[10]; };
|
||||
// S* p = ...;
|
||||
// strcpy(p->buffer, "abc");
|
||||
result = root.getUnspecifiedType().stripType()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 +126,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())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
@@ -769,8 +769,4 @@ module InputSigCommon {
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
|
||||
|
||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||
|
||||
class ExitBasicBlock extends BasicBlock {
|
||||
ExitBasicBlock() { this.getLastInstruction() instanceof ExitFunctionInstruction }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -1,3 +1,10 @@
|
||||
## 1.3.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Wrong type of arguments to formatting function" query (`cpp/wrong-type-format-argument`) now produces fewer FPs if the formatting function has multiple definitions.
|
||||
* The "Call to memory access function may overflow buffer" query (`cpp/overflow-buffer`) now produces fewer FPs involving non-static member variables.
|
||||
|
||||
## 1.3.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -171,7 +171,9 @@ where
|
||||
not arg.isAffectedByMacro() and
|
||||
not arg.isFromUninstantiatedTemplate(_) and
|
||||
not actual.stripType() instanceof ErroneousType and
|
||||
not arg.(Call).mayBeFromImplicitlyDeclaredFunction()
|
||||
not arg.(Call).mayBeFromImplicitlyDeclaredFunction() and
|
||||
// Make sure that the format function definition is consistent
|
||||
count(ffc.getTarget().getFormatParameterIndex()) = 1
|
||||
select arg,
|
||||
"This format specifier for type '" + expected.getName() + "' does not match the argument type '" +
|
||||
actual.getUnspecifiedType().getName() + "'."
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
6
cpp/ql/src/change-notes/released/1.3.3.md
Normal file
6
cpp/ql/src/change-notes/released/1.3.3.md
Normal file
@@ -0,0 +1,6 @@
|
||||
## 1.3.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Wrong type of arguments to formatting function" query (`cpp/wrong-type-format-argument`) now produces fewer FPs if the formatting function has multiple definitions.
|
||||
* The "Call to memory access function may overflow buffer" query (`cpp/overflow-buffer`) now produces fewer FPs involving non-static member variables.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.3.2
|
||||
lastReleaseVersion: 1.3.3
|
||||
|
||||
1
cpp/ql/src/codeql-suites/cpp-ccr.qls
Normal file
1
cpp/ql/src/codeql-suites/cpp-ccr.qls
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.3.3-dev
|
||||
version: 1.3.4-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
| blocks.c:17:11:17:33 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.c:17:11:17:11 | <unnamed> | file://:0:0:0:0 | void | void | |
|
||||
| blocks.c:20:11:20:28 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.c:20:11:20:11 | <unnamed> | file://:0:0:0:0 | void | void | |
|
||||
| blocks.c:23:11:23:21 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.c:23:11:23:11 | <unnamed> | file://:0:0:0:0 | void | void | |
|
||||
| blocks.c:27:8:27:37 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments (int,char)} | blocks.c:27:11:27:11 | <unnamed> | file://:0:0:0:0 | void | void | y(int), z(char) |
|
||||
| blocks.c:31:8:31:51 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments (int,char)} | blocks.c:31:11:31:11 | <unnamed> | file://:0:0:0:0 | void | void | y(int), z(char) |
|
||||
| blocks.c:35:8:35:49 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {double} with arguments (int,char)} | blocks.c:35:11:35:11 | <unnamed> | file://:0:0:0:0 | double | double | y(int), z(char) |
|
||||
| blocks.c:39:8:39:75 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {double} with arguments (int,char)} | blocks.c:39:11:39:11 | <unnamed> | file://:0:0:0:0 | double | double | y(int), z(char) |
|
||||
| blocks.c:43:8:43:54 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {char} with arguments (int,char)} | blocks.c:43:11:43:11 | <unnamed> | file://:0:0:0:0 | char | char | y(int), z(char) |
|
||||
| blocks.c:47:8:47:64 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {pointer to {const {char}}} with arguments (int,char)} | blocks.c:47:11:47:11 | <unnamed> | file://:0:0:0:0 | const char * | pointer to {const {char}} | y(int), z(char) |
|
||||
| blocks.c:51:8:51:73 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {pointer to {const {pointer to {const {char}}}}} with arguments (int,char)} | blocks.c:51:11:51:11 | <unnamed> | file://:0:0:0:0 | const char *const * | pointer to {const {pointer to {const {char}}}} | y(int), z(char) |
|
||||
| blocks.c:63:16:65:2 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {int} with arguments ()} | blocks.c:63:16:63:16 | <unnamed> | file://:0:0:0:0 | int | int | |
|
||||
| blocks.c:69:19:69:39 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {int} with arguments ()} | blocks.c:69:22:69:22 | <unnamed> | file://:0:0:0:0 | int | int | |
|
||||
| blocks.c:74:60:74:111 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {typedef {pointer to {function returning {int} with arguments (char)}} as "pointerToFunctionThatReturnsIntWithCharArg"} with arguments (float)} | blocks.c:74:62:74:62 | <unnamed> | file://:0:0:0:0 | ..(*)(..) | pointer to {function returning {int} with arguments (char)} | x(float) |
|
||||
| blocks.c:79:7:79:9 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.c:79:7:79:7 | <unnamed> | file://:0:0:0:0 | void | void | |
|
||||
| blocks.c:80:7:80:9 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.c:80:7:80:7 | <unnamed> | file://:0:0:0:0 | void | void | |
|
||||
| blocks.c:17:11:17:33 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.c:17:11:17:11 | (unnamed codeblock) | file://:0:0:0:0 | void | void | |
|
||||
| blocks.c:20:11:20:28 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.c:20:11:20:11 | (unnamed codeblock) | file://:0:0:0:0 | void | void | |
|
||||
| blocks.c:23:11:23:21 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.c:23:11:23:11 | (unnamed codeblock) | file://:0:0:0:0 | void | void | |
|
||||
| blocks.c:27:8:27:37 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments (int,char)} | blocks.c:27:11:27:11 | (unnamed codeblock) | file://:0:0:0:0 | void | void | y(int), z(char) |
|
||||
| blocks.c:31:8:31:51 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments (int,char)} | blocks.c:31:11:31:11 | (unnamed codeblock) | file://:0:0:0:0 | void | void | y(int), z(char) |
|
||||
| blocks.c:35:8:35:49 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {double} with arguments (int,char)} | blocks.c:35:11:35:11 | (unnamed codeblock) | file://:0:0:0:0 | double | double | y(int), z(char) |
|
||||
| blocks.c:39:8:39:75 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {double} with arguments (int,char)} | blocks.c:39:11:39:11 | (unnamed codeblock) | file://:0:0:0:0 | double | double | y(int), z(char) |
|
||||
| blocks.c:43:8:43:54 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {char} with arguments (int,char)} | blocks.c:43:11:43:11 | (unnamed codeblock) | file://:0:0:0:0 | char | char | y(int), z(char) |
|
||||
| blocks.c:47:8:47:64 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {pointer to {const {char}}} with arguments (int,char)} | blocks.c:47:11:47:11 | (unnamed codeblock) | file://:0:0:0:0 | const char * | pointer to {const {char}} | y(int), z(char) |
|
||||
| blocks.c:51:8:51:73 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {pointer to {const {pointer to {const {char}}}}} with arguments (int,char)} | blocks.c:51:11:51:11 | (unnamed codeblock) | file://:0:0:0:0 | const char *const * | pointer to {const {pointer to {const {char}}}} | y(int), z(char) |
|
||||
| blocks.c:63:16:65:2 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {int} with arguments ()} | blocks.c:63:16:63:16 | (unnamed codeblock) | file://:0:0:0:0 | int | int | |
|
||||
| blocks.c:69:19:69:39 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {int} with arguments ()} | blocks.c:69:22:69:22 | (unnamed codeblock) | file://:0:0:0:0 | int | int | |
|
||||
| blocks.c:74:60:74:111 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {typedef {pointer to {function returning {int} with arguments (char)}} as "pointerToFunctionThatReturnsIntWithCharArg"} with arguments (float)} | blocks.c:74:62:74:62 | (unnamed codeblock) | file://:0:0:0:0 | ..(*)(..) | pointer to {function returning {int} with arguments (char)} | x(float) |
|
||||
| blocks.c:79:7:79:9 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.c:79:7:79:7 | (unnamed codeblock) | file://:0:0:0:0 | void | void | |
|
||||
| blocks.c:80:7:80:9 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.c:80:7:80:7 | (unnamed codeblock) | file://:0:0:0:0 | void | void | |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| capture.c:18:23:20:6 | ^ { ... } | capture.c:19:27:19:27 | x | capture.c:6:5:6:5 | x | capture.c:18:23:18:23 | <unnamed> |
|
||||
| capture.c:18:23:20:6 | ^ { ... } | capture.c:19:30:19:30 | y | capture.c:13:17:13:17 | y | capture.c:18:23:18:23 | <unnamed> |
|
||||
| capture.c:22:23:25:6 | ^ { ... } | capture.c:23:9:23:9 | x | capture.c:6:5:6:5 | x | capture.c:22:23:22:23 | <unnamed> |
|
||||
| capture.c:22:23:25:6 | ^ { ... } | capture.c:24:9:24:9 | y | capture.c:13:17:13:17 | y | capture.c:22:23:22:23 | <unnamed> |
|
||||
| capture.c:18:23:20:6 | ^ { ... } | capture.c:19:27:19:27 | x | capture.c:6:5:6:5 | x | capture.c:18:23:18:23 | (unnamed codeblock) |
|
||||
| capture.c:18:23:20:6 | ^ { ... } | capture.c:19:30:19:30 | y | capture.c:13:17:13:17 | y | capture.c:18:23:18:23 | (unnamed codeblock) |
|
||||
| capture.c:22:23:25:6 | ^ { ... } | capture.c:23:9:23:9 | x | capture.c:6:5:6:5 | x | capture.c:22:23:22:23 | (unnamed codeblock) |
|
||||
| capture.c:22:23:25:6 | ^ { ... } | capture.c:24:9:24:9 | y | capture.c:13:17:13:17 | y | capture.c:22:23:22:23 | (unnamed codeblock) |
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
| blocks.cpp:17:11:17:33 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.cpp:17:11:17:11 | <unnamed> | file://:0:0:0:0 | void | void | |
|
||||
| blocks.cpp:20:11:20:28 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.cpp:20:11:20:11 | <unnamed> | file://:0:0:0:0 | void | void | |
|
||||
| blocks.cpp:23:11:23:21 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.cpp:23:11:23:11 | <unnamed> | file://:0:0:0:0 | void | void | |
|
||||
| blocks.cpp:27:8:27:37 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments (int,char)} | blocks.cpp:27:11:27:11 | <unnamed> | file://:0:0:0:0 | void | void | y(int), z(char) |
|
||||
| blocks.cpp:31:8:31:51 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments (int,char)} | blocks.cpp:31:11:31:11 | <unnamed> | file://:0:0:0:0 | void | void | y(int), z(char) |
|
||||
| blocks.cpp:35:8:35:49 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {char} with arguments (int,char)} | blocks.cpp:35:11:35:11 | <unnamed> | file://:0:0:0:0 | char | char | y(int), z(char) |
|
||||
| blocks.cpp:39:8:39:75 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {char} with arguments (int,char)} | blocks.cpp:39:11:39:11 | <unnamed> | file://:0:0:0:0 | char | char | y(int), z(char) |
|
||||
| blocks.cpp:43:8:43:54 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {char} with arguments (int,char)} | blocks.cpp:43:11:43:11 | <unnamed> | file://:0:0:0:0 | char | char | y(int), z(char) |
|
||||
| blocks.cpp:57:14:57:30 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {int} with arguments ()} | blocks.cpp:57:14:57:14 | <unnamed> | file://:0:0:0:0 | int | int | |
|
||||
| blocks.cpp:17:11:17:33 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.cpp:17:11:17:11 | (unnamed codeblock) | file://:0:0:0:0 | void | void | |
|
||||
| blocks.cpp:20:11:20:28 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.cpp:20:11:20:11 | (unnamed codeblock) | file://:0:0:0:0 | void | void | |
|
||||
| blocks.cpp:23:11:23:21 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments ()} | blocks.cpp:23:11:23:11 | (unnamed codeblock) | file://:0:0:0:0 | void | void | |
|
||||
| blocks.cpp:27:8:27:37 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments (int,char)} | blocks.cpp:27:11:27:11 | (unnamed codeblock) | file://:0:0:0:0 | void | void | y(int), z(char) |
|
||||
| blocks.cpp:31:8:31:51 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {void} with arguments (int,char)} | blocks.cpp:31:11:31:11 | (unnamed codeblock) | file://:0:0:0:0 | void | void | y(int), z(char) |
|
||||
| blocks.cpp:35:8:35:49 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {char} with arguments (int,char)} | blocks.cpp:35:11:35:11 | (unnamed codeblock) | file://:0:0:0:0 | char | char | y(int), z(char) |
|
||||
| blocks.cpp:39:8:39:75 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {char} with arguments (int,char)} | blocks.cpp:39:11:39:11 | (unnamed codeblock) | file://:0:0:0:0 | char | char | y(int), z(char) |
|
||||
| blocks.cpp:43:8:43:54 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {char} with arguments (int,char)} | blocks.cpp:43:11:43:11 | (unnamed codeblock) | file://:0:0:0:0 | char | char | y(int), z(char) |
|
||||
| blocks.cpp:57:14:57:30 | ^ { ... } | file://:0:0:0:0 | ..(^)(..) | block of {function returning {int} with arguments ()} | blocks.cpp:57:14:57:14 | (unnamed codeblock) | file://:0:0:0:0 | int | int | |
|
||||
|
||||
@@ -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 | ... == ... |
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user