mirror of
https://github.com/github/codeql.git
synced 2026-06-19 20:01:09 +02:00
Compare commits
2 Commits
bazookamus
...
idrissrio/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cc361bf35 | ||
|
|
749a40153d |
208
.github/workflows/go-version-update.yml
vendored
208
.github/workflows/go-version-update.yml
vendored
@@ -1,208 +0,0 @@
|
||||
name: Update Go version
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 3 * * 1" # Run weekly on Mondays at 3 AM UTC (1 = Monday)
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
update-go-version:
|
||||
name: Check and update Go version
|
||||
if: github.repository == 'github/codeql'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Git
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Fetch latest Go version
|
||||
id: fetch-version
|
||||
run: |
|
||||
LATEST_GO_VERSION=$(curl -s https://go.dev/dl/?mode=json | jq -r '.[0].version')
|
||||
|
||||
if [ -z "$LATEST_GO_VERSION" ] || [ "$LATEST_GO_VERSION" = "null" ]; then
|
||||
echo "Error: Failed to fetch latest Go version from go.dev"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Latest Go version from go.dev: $LATEST_GO_VERSION"
|
||||
echo "version=$LATEST_GO_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
# Extract version numbers (e.g., go1.26.0 -> 1.26.0)
|
||||
LATEST_VERSION_NUM=$(echo $LATEST_GO_VERSION | sed 's/^go//')
|
||||
echo "version_num=$LATEST_VERSION_NUM" >> $GITHUB_OUTPUT
|
||||
|
||||
# Extract major.minor version (e.g., 1.26.0 -> 1.26)
|
||||
LATEST_MAJOR_MINOR=$(echo $LATEST_VERSION_NUM | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
|
||||
echo "major_minor=$LATEST_MAJOR_MINOR" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Check current Go version
|
||||
id: current-version
|
||||
run: |
|
||||
CURRENT_VERSION=$(sed -n 's/.*go_sdk\.download(version = \"\([^\"]*\)\".*/\1/p' MODULE.bazel)
|
||||
|
||||
if [ -z "$CURRENT_VERSION" ]; then
|
||||
echo "Error: Could not extract Go version from MODULE.bazel"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Current Go version in MODULE.bazel: $CURRENT_VERSION"
|
||||
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
# Extract major.minor version
|
||||
CURRENT_MAJOR_MINOR=$(echo $CURRENT_VERSION | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
|
||||
echo "major_minor=$CURRENT_MAJOR_MINOR" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Compare versions
|
||||
id: compare
|
||||
run: |
|
||||
LATEST="${{ steps.fetch-version.outputs.version_num }}"
|
||||
CURRENT="${{ steps.current-version.outputs.version }}"
|
||||
|
||||
echo "Latest: $LATEST"
|
||||
echo "Current: $CURRENT"
|
||||
|
||||
if [ "$LATEST" = "$CURRENT" ]; then
|
||||
echo "Go version is up to date"
|
||||
echo "needs_update=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Go version needs update from $CURRENT to $LATEST"
|
||||
echo "needs_update=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Update Go version in files
|
||||
if: steps.compare.outputs.needs_update == 'true'
|
||||
run: |
|
||||
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
|
||||
LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}"
|
||||
CURRENT_VERSION="${{ steps.current-version.outputs.version }}"
|
||||
CURRENT_MAJOR_MINOR="${{ steps.current-version.outputs.major_minor }}"
|
||||
|
||||
echo "Updating from $CURRENT_VERSION to $LATEST_VERSION_NUM"
|
||||
|
||||
# Escape dots in current version strings for use in sed patterns
|
||||
CURRENT_VERSION_ESCAPED=$(echo "$CURRENT_VERSION" | sed 's/\./\\./g')
|
||||
CURRENT_MAJOR_MINOR_ESCAPED=$(echo "$CURRENT_MAJOR_MINOR" | sed 's/\./\\./g')
|
||||
|
||||
# Update MODULE.bazel
|
||||
sed -i "s/go_sdk\.download(version = \"$CURRENT_VERSION_ESCAPED\")/go_sdk.download(version = \"$LATEST_VERSION_NUM\")/" MODULE.bazel
|
||||
if ! grep -q "go_sdk.download(version = \"$LATEST_VERSION_NUM\")" MODULE.bazel; then
|
||||
echo "Error: Failed to update MODULE.bazel"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update go/extractor/go.mod
|
||||
if ! sed -i "s/^go $CURRENT_MAJOR_MINOR_ESCAPED\$/go $LATEST_MAJOR_MINOR/" go/extractor/go.mod; then
|
||||
echo "Warning: Failed to update go directive in go.mod"
|
||||
fi
|
||||
if ! sed -i "s/^toolchain go$CURRENT_VERSION_ESCAPED\$/toolchain go$LATEST_VERSION_NUM/" go/extractor/go.mod; then
|
||||
echo "Warning: Failed to update toolchain in go.mod"
|
||||
fi
|
||||
|
||||
# Update go/extractor/autobuilder/build-environment.go
|
||||
if ! sed -i "s/var maxGoVersion = util\.NewSemVer(\"$CURRENT_MAJOR_MINOR_ESCAPED\")/var maxGoVersion = util.NewSemVer(\"$LATEST_MAJOR_MINOR\")/" go/extractor/autobuilder/build-environment.go; then
|
||||
echo "Warning: Failed to update build-environment.go"
|
||||
fi
|
||||
|
||||
# Update go/actions/test/action.yml
|
||||
if ! sed -i "s/default: \"~$CURRENT_VERSION_ESCAPED\"/default: \"~$LATEST_VERSION_NUM\"/" go/actions/test/action.yml; then
|
||||
echo "Warning: Failed to update action.yml"
|
||||
fi
|
||||
|
||||
# Show what changed
|
||||
git diff
|
||||
|
||||
- name: Check for changes
|
||||
id: check-changes
|
||||
if: steps.compare.outputs.needs_update == 'true'
|
||||
run: |
|
||||
if git diff --quiet; then
|
||||
echo "No changes detected"
|
||||
echo "has_changes=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Changes detected"
|
||||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Check for existing PR
|
||||
if: steps.check-changes.outputs.has_changes == 'true'
|
||||
id: check-pr
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
BRANCH_NAME="workflow/go-version-update"
|
||||
PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number')
|
||||
|
||||
if [ -n "$PR_NUMBER" ]; then
|
||||
echo "Existing PR found: #$PR_NUMBER"
|
||||
echo "pr_exists=true" >> $GITHUB_OUTPUT
|
||||
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "No existing PR found"
|
||||
echo "pr_exists=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Commit and push changes
|
||||
if: steps.check-changes.outputs.has_changes == 'true'
|
||||
run: |
|
||||
BRANCH_NAME="workflow/go-version-update"
|
||||
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
|
||||
LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}"
|
||||
|
||||
# Create or switch to branch
|
||||
git checkout -B "$BRANCH_NAME"
|
||||
|
||||
# Stage and commit changes
|
||||
git add MODULE.bazel go/extractor/go.mod go/extractor/autobuilder/build-environment.go go/actions/test/action.yml
|
||||
git commit -m "Go: Update to $LATEST_VERSION_NUM"
|
||||
|
||||
# Push changes
|
||||
git push --force-with-lease origin "$BRANCH_NAME"
|
||||
|
||||
- name: Create or update PR
|
||||
if: steps.check-changes.outputs.has_changes == 'true'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
BRANCH_NAME="workflow/go-version-update"
|
||||
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
|
||||
CURRENT_VERSION="${{ steps.current-version.outputs.version }}"
|
||||
|
||||
PR_TITLE="Go: Update to $LATEST_VERSION_NUM"
|
||||
|
||||
PR_BODY=$(cat <<EOF
|
||||
This PR updates Go from $CURRENT_VERSION to $LATEST_VERSION_NUM.
|
||||
|
||||
Updated files:
|
||||
- \`MODULE.bazel\` - go_sdk.download version
|
||||
- \`go/extractor/go.mod\` - go directive and toolchain
|
||||
- \`go/extractor/autobuilder/build-environment.go\` - maxGoVersion (only if MAJOR.MINOR changes)
|
||||
- \`go/actions/test/action.yml\` - default go-test-version
|
||||
|
||||
This PR was automatically created by the [Go version update workflow](https://github.com/${{ github.repository }}/blob/main/.github/workflows/go-version-update.yml).
|
||||
EOF
|
||||
)
|
||||
|
||||
if [ "${{ steps.check-pr.outputs.pr_exists }}" = "true" ]; then
|
||||
echo "Updating existing PR #${{ steps.check-pr.outputs.pr_number }}"
|
||||
gh pr edit "${{ steps.check-pr.outputs.pr_number }}" --title "$PR_TITLE" --body "$PR_BODY"
|
||||
else
|
||||
echo "Creating new PR"
|
||||
gh pr create \
|
||||
--title "$PR_TITLE" \
|
||||
--body "$PR_BODY" \
|
||||
--base main \
|
||||
--head "$BRANCH_NAME" \
|
||||
--label "Go"
|
||||
fi
|
||||
@@ -2,7 +2,7 @@
|
||||
* @github/code-scanning-alert-coverage
|
||||
|
||||
# CodeQL language libraries
|
||||
/actions/ @github/code-scanning-alert-coverage
|
||||
/actions/ @github/codeql-dynamic
|
||||
/cpp/ @github/codeql-c-analysis
|
||||
/csharp/ @github/codeql-csharp
|
||||
/csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor @github/code-scanning-language-coverage
|
||||
@@ -59,5 +59,9 @@ MODULE.bazel @github/codeql-ci-reviewers
|
||||
/.github/workflows/rust.yml @github/codeql-rust
|
||||
/.github/workflows/swift.yml @github/codeql-swift
|
||||
|
||||
# Misc
|
||||
/misc/scripts/accept-expected-changes-from-ci.py @RasmusWL
|
||||
/misc/scripts/generate-code-scanning-query-list.py @RasmusWL
|
||||
|
||||
# .devcontainer
|
||||
/.devcontainer/ @github/codeql-ci-reviewers
|
||||
|
||||
@@ -273,7 +273,7 @@ use_repo(
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.26.4")
|
||||
go_sdk.download(version = "1.26.0")
|
||||
|
||||
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//go/extractor:go.mod")
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
## 0.4.37
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
|
||||
|
||||
## 0.4.36
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* The query `actions/pr-on-self-hosted-runner` was updated to the latest standard runner labels reducing false positive results.
|
||||
@@ -1,5 +0,0 @@
|
||||
## 0.4.37
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.37
|
||||
lastReleaseVersion: 0.4.36
|
||||
|
||||
@@ -1920,5 +1920,3 @@ private YamlMappingLikeNode resolveMatrixAccessPath(
|
||||
else result = resolveMatrixAccessPath(newRoot, rest)
|
||||
)
|
||||
}
|
||||
|
||||
class Comment = YamlComment;
|
||||
|
||||
@@ -52,12 +52,6 @@ private module YamlSig implements LibYaml::InputSig {
|
||||
class ParseErrorBase extends LocatableBase, @yaml_error {
|
||||
string getMessage() { yaml_errors(this, result) }
|
||||
}
|
||||
|
||||
class CommentBase extends LocatableBase, @yaml_comment {
|
||||
string getText() { yaml_comments(this, result, _) }
|
||||
|
||||
override string toString() { yaml_comments(this, _, result) }
|
||||
}
|
||||
}
|
||||
|
||||
import LibYaml::Make<YamlSig>
|
||||
|
||||
@@ -2,12 +2,10 @@ import actions
|
||||
|
||||
bindingset[runner]
|
||||
predicate isGithubHostedRunner(string runner) {
|
||||
// The list of github hosted repos:
|
||||
// https://github.com/actions/runner-images/blob/main/README.md#available-images
|
||||
// https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/write-workflows/choose-where-workflows-run/choose-the-runner-for-a-job#standard-github-hosted-runners-for-public-repositories
|
||||
runner.toLowerCase().regexpMatch("^ubuntu-([0-9.]+|latest|slim)(-arm)?$") or
|
||||
runner.toLowerCase().regexpMatch("^macos-([0-9]+|latest)(-x?large|-intel)?$") or
|
||||
runner.toLowerCase().regexpMatch("^windows-([0-9.]+|latest)(-vs[0-9.]+)?(-arm)?$")
|
||||
// list of github hosted repos: https://github.com/actions/runner-images/blob/main/README.md#available-images
|
||||
runner
|
||||
.toLowerCase()
|
||||
.regexpMatch("^(ubuntu-([0-9.]+|latest)|macos-([0-9]+|latest)(-x?large)?|windows-([0-9.]+|latest))$")
|
||||
}
|
||||
|
||||
bindingset[runner]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.38-dev
|
||||
version: 0.4.37-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,22 +1,3 @@
|
||||
## 0.6.29
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`.
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`.
|
||||
* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
|
||||
|
||||
## 0.6.28
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @name Checkout of untrusted code in a non-privileged context
|
||||
* @description Checking out and running the build script from a fork executes untrusted code. Even in a
|
||||
* non-privileged workflow, this can be abused, for example to compromise self-hosted runners
|
||||
* or to poison caches and artifacts that are later consumed by privileged workflows.
|
||||
* @name Checkout of untrusted code in a trusted context
|
||||
* @description Privileged workflows have read/write access to the base repository and access to secrets.
|
||||
* By explicitly checking out and running the build script from a fork the untrusted code is running in an environment
|
||||
* that is able to push to the base repository and to access secrets.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
@@ -20,4 +20,4 @@ from PRHeadCheckoutStep checkout
|
||||
where
|
||||
// the checkout occurs in a non-privileged context
|
||||
inNonPrivilegedContext(checkout)
|
||||
select checkout, "Potential unsafe checkout of untrusted pull request on non-privileged workflow."
|
||||
select checkout, "Potential unsafe checkout of untrusted pull request on privileged workflow."
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
* The name, description, and alert message of `actions/untrusted-checkout/medium` have been corrected to describe a non-privileged context.
|
||||
@@ -1,18 +0,0 @@
|
||||
## 0.6.29
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`.
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`.
|
||||
* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.29
|
||||
lastReleaseVersion: 0.6.28
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.30-dev
|
||||
version: 0.6.29-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
name: test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- ubuntu-24.04
|
||||
- ubuntu-24.04-arm
|
||||
- ubuntu-22.04
|
||||
- ubuntu-22.04-arm
|
||||
- ubuntu-26.04
|
||||
- ubuntu-26.04-arm
|
||||
- ubuntu-slim
|
||||
- macos-26
|
||||
- macos-26-xlarge
|
||||
- macos-26-intel
|
||||
- macos-26-large
|
||||
- macos-latest-large
|
||||
- macos-15-large
|
||||
- macos-15
|
||||
- macos-15-intel
|
||||
- macos-latest
|
||||
- macos-15
|
||||
- macos-15-xlarge
|
||||
- macos-14-large
|
||||
- macos-14
|
||||
- macos-14-xlarge
|
||||
- windows-2025-vs2026
|
||||
- windows-latest
|
||||
- windows-2025
|
||||
- windows-2022
|
||||
- windows-11
|
||||
- windows-11-arm
|
||||
- windows-11-vs2026-arm
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- run: cmd
|
||||
@@ -1,10 +1,10 @@
|
||||
| .github/workflows/artifactpoisoning81.yml:11:9:14:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/dependabot2.yml:33:9:38:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/mend.yml:22:9:29:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/poc3.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/poc.yml:30:9:36:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/priv_pull_request_checkout.yml:14:9:20:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/test3.yml:28:9:33:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/test4.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/test8.yml:20:9:26:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/test9.yml:11:9:16:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/artifactpoisoning81.yml:11:9:14:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/dependabot2.yml:33:9:38:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/mend.yml:22:9:29:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/poc3.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/poc.yml:30:9:36:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/priv_pull_request_checkout.yml:14:9:20:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/test3.yml:28:9:33:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/test4.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/test8.yml:20:9:26:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/test9.yml:11:9:16:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll"
|
||||
],
|
||||
"Bound Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/Bound.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll"
|
||||
],
|
||||
"ModulusAnalysis Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/ModulusAnalysis.qll"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
description: Fix NameQualifier inconsistency
|
||||
compatibility: full
|
||||
@@ -1,19 +1,3 @@
|
||||
## 10.2.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations.
|
||||
* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow source models for `scanf_s` and related functions.
|
||||
* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported.
|
||||
|
||||
## 10.1.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -30,6 +30,8 @@ class Options extends string {
|
||||
predicate overrideReturnsNull(Call call) {
|
||||
// Used in CVS:
|
||||
call.(FunctionCall).getTarget().hasGlobalName("Xstrdup")
|
||||
or
|
||||
CustomOptions::overrideReturnsNull(call) // old Options.qll
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,6 +45,8 @@ class Options extends string {
|
||||
// Used in CVS:
|
||||
call.(FunctionCall).getTarget().hasGlobalName("Xstrdup") and
|
||||
nullValue(call.getArgument(0))
|
||||
or
|
||||
CustomOptions::returnsNull(call) // old Options.qll
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,6 +65,8 @@ class Options extends string {
|
||||
f.hasGlobalOrStdName([
|
||||
"exit", "_exit", "_Exit", "abort", "__assert_fail", "longjmp", "__builtin_unreachable"
|
||||
])
|
||||
or
|
||||
CustomOptions::exits(f) // old Options.qll
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +79,8 @@ class Options extends string {
|
||||
* runtime, the program's behavior is undefined)
|
||||
*/
|
||||
predicate exprExits(Expr e) {
|
||||
e.(AssumeExpr).getChild(0).(CompileTimeConstantInt).getIntValue() = 0
|
||||
e.(AssumeExpr).getChild(0).(CompileTimeConstantInt).getIntValue() = 0 or
|
||||
CustomOptions::exprExits(e) // old Options.qll
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +88,10 @@ class Options extends string {
|
||||
*
|
||||
* By default holds only for `fgets`.
|
||||
*/
|
||||
predicate alwaysCheckReturnValue(Function f) { f.hasGlobalOrStdName("fgets") }
|
||||
predicate alwaysCheckReturnValue(Function f) {
|
||||
f.hasGlobalOrStdName("fgets") or
|
||||
CustomOptions::alwaysCheckReturnValue(f) // old Options.qll
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if it is reasonable to ignore the return value of function
|
||||
@@ -97,6 +107,8 @@ class Options extends string {
|
||||
// common way of sleeping using select:
|
||||
fc.getTarget().hasGlobalName("select") and
|
||||
fc.getArgument(0).getValue() = "0"
|
||||
or
|
||||
CustomOptions::okToIgnoreReturnValue(fc) // old Options.qll
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,3 +98,57 @@ class CustomMutexType extends MutexType {
|
||||
*/
|
||||
override predicate unlockAccess(FunctionCall fc, Expr arg) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: customize `CustomOptions.overrideReturnsNull` instead.
|
||||
*
|
||||
* This predicate is required to support backwards compatibility for
|
||||
* older `Options.qll` files. It should not be removed or modified by
|
||||
* end users.
|
||||
*/
|
||||
predicate overrideReturnsNull(Call call) { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: customize `CustomOptions.returnsNull` instead.
|
||||
*
|
||||
* This predicate is required to support backwards compatibility for
|
||||
* older `Options.qll` files. It should not be removed or modified by
|
||||
* end users.
|
||||
*/
|
||||
predicate returnsNull(Call call) { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: customize `CustomOptions.exits` instead.
|
||||
*
|
||||
* This predicate is required to support backwards compatibility for
|
||||
* older `Options.qll` files. It should not be removed or modified by
|
||||
* end users.
|
||||
*/
|
||||
predicate exits(Function f) { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: customize `CustomOptions.exprExits` instead.
|
||||
*
|
||||
* This predicate is required to support backwards compatibility for
|
||||
* older `Options.qll` files. It should not be removed or modified by
|
||||
* end users.
|
||||
*/
|
||||
predicate exprExits(Expr e) { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: customize `CustomOptions.alwaysCheckReturnValue` instead.
|
||||
*
|
||||
* This predicate is required to support backwards compatibility for
|
||||
* older `Options.qll` files. It should not be removed or modified by
|
||||
* end users.
|
||||
*/
|
||||
predicate alwaysCheckReturnValue(Function f) { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: customize `CustomOptions.okToIgnoreReturnValue` instead.
|
||||
*
|
||||
* This predicate is required to support backwards compatibility for
|
||||
* older `Options.qll` files. It should not be removed or modified by
|
||||
* end users.
|
||||
*/
|
||||
predicate okToIgnoreReturnValue(FunctionCall fc) { none() }
|
||||
|
||||
5
cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md
Normal file
5
cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added flow source models for `scanf_s` and related functions.
|
||||
* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported.
|
||||
4
cpp/ql/lib/change-notes/2026-05-16-alias-template.md
Normal file
4
cpp/ql/lib/change-notes/2026-05-16-alias-template.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations.
|
||||
4
cpp/ql/lib/change-notes/2026-05-18-alias-type.md
Normal file
4
cpp/ql/lib/change-notes/2026-05-18-alias-type.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead.
|
||||
4
cpp/ql/lib/change-notes/2026-05-21-generated-from.md
Normal file
4
cpp/ql/lib/change-notes/2026-05-21-generated-from.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations.
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* Removed the deprecated `overrideReturnsNull` predicate from `Options.qll`. Use `CustomOptions.overrideReturnsNull` instead.
|
||||
* Removed the deprecated `returnsNull` predicate from `Options.qll`. Use `CustomOptions.returnsNull` instead.
|
||||
* Removed the deprecated `exits` predicate from `Options.qll`. Use `CustomOptions.exits` instead.
|
||||
* Removed the deprecated `exprExits` predicate from `Options.qll`. Use `CustomOptions.exprExits` instead.
|
||||
* Removed the deprecated `alwaysCheckReturnValue` predicate from `Options.qll`. Use `CustomOptions.alwaysCheckReturnValue` instead.
|
||||
* Removed the deprecated `okToIgnoreReturnValue` predicate from `Options.qll`. Use `CustomOptions.okToIgnoreReturnValue` instead.
|
||||
* Removed the deprecated `semmle.code.cpp.Member`. Import `semmle.code.cpp.Element` and/or `semmle.code.cpp.Type` directly.
|
||||
* Removed the deprecated `UnknownDefaultLocation` class. Use `UnknownLocation` instead.
|
||||
* Removed the deprecated `UnknownExprLocation` class. Use `UnknownLocation` instead.
|
||||
* Removed the deprecated `UnknownStmtLocation` class. Use `UnknownLocation` instead.
|
||||
* Removed the deprecated `TemplateParameter` class. Use `TypeTemplateParameter` instead.
|
||||
* Support for class resolution across link targets has been removed for databases which were created with CodeQL versions before 1.23.0.
|
||||
@@ -1,15 +0,0 @@
|
||||
## 10.2.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations.
|
||||
* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow source models for `scanf_s` and related functions.
|
||||
* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 10.2.0
|
||||
lastReleaseVersion: 10.1.1
|
||||
|
||||
@@ -32,6 +32,7 @@ import semmle.code.cpp.Class
|
||||
import semmle.code.cpp.Struct
|
||||
import semmle.code.cpp.Union
|
||||
import semmle.code.cpp.Enum
|
||||
import semmle.code.cpp.Member
|
||||
import semmle.code.cpp.Field
|
||||
import semmle.code.cpp.Function
|
||||
import semmle.code.cpp.MemberFunction
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 10.2.1-dev
|
||||
version: 10.1.2-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -148,3 +148,28 @@ class UnknownLocation extends Location {
|
||||
this.getFile().getAbsolutePath() = "" and locations_default(this, _, 0, 0, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A dummy location which is used when something doesn't have a location in
|
||||
* the source code but needs to have a `Location` associated with it.
|
||||
*
|
||||
* DEPRECATED: use `UnknownLocation`
|
||||
*/
|
||||
deprecated class UnknownDefaultLocation extends UnknownLocation { }
|
||||
|
||||
/**
|
||||
* A dummy location which is used when an expression doesn't have a
|
||||
* location in the source code but needs to have a `Location` associated
|
||||
* with it.
|
||||
*
|
||||
* DEPRECATED: use `UnknownLocation`
|
||||
*/
|
||||
deprecated class UnknownExprLocation extends UnknownLocation { }
|
||||
|
||||
/**
|
||||
* A dummy location which is used when a statement doesn't have a location
|
||||
* in the source code but needs to have a `Location` associated with it.
|
||||
*
|
||||
* DEPRECATED: use `UnknownLocation`
|
||||
*/
|
||||
deprecated class UnknownStmtLocation extends UnknownLocation { }
|
||||
|
||||
6
cpp/ql/lib/semmle/code/cpp/Member.qll
Normal file
6
cpp/ql/lib/semmle/code/cpp/Member.qll
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: import `semmle.code.cpp.Element` and/or `semmle.code.cpp.Type` directly as required.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.Element
|
||||
import semmle.code.cpp.Type
|
||||
@@ -35,6 +35,13 @@ class NonTypeTemplateParameter extends Literal, TemplateParameterImpl {
|
||||
override string getAPrimaryQlClass() { result = "NonTypeTemplateParameter" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `typename` (or `class`) template parameter.
|
||||
*
|
||||
* DEPRECATED: Use `TypeTemplateParameter` instead.
|
||||
*/
|
||||
deprecated class TemplateParameter = TypeTemplateParameter;
|
||||
|
||||
/**
|
||||
* A C++ `typename` (or `class`) template parameter.
|
||||
*
|
||||
|
||||
@@ -1071,7 +1071,7 @@ class NullPointerType extends BuiltInType {
|
||||
* const float fa[40];
|
||||
* ```
|
||||
*/
|
||||
class DerivedType extends Type, NameQualifyingElement, @derivedtype {
|
||||
class DerivedType extends Type, @derivedtype {
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override string getName() { derivedtypes(underlyingElement(this), result, _, _) }
|
||||
|
||||
@@ -276,45 +276,6 @@ private predicate isClassConstructedFrom(Class c, Class templateClass) {
|
||||
not c.isConstructedFrom(_) and c = templateClass
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `c`. */
|
||||
private Class getFullyTemplatedClassOld(Class c) {
|
||||
not c.isFromUninstantiatedTemplate(_) and
|
||||
isClassConstructedFrom(c, result)
|
||||
}
|
||||
|
||||
private TemplateClass getOriginalClassTemplate(TemplateClass tc) {
|
||||
result = tc.getOriginalTemplate()
|
||||
or
|
||||
not exists(tc.getOriginalTemplate()) and
|
||||
result = tc
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `c`. */
|
||||
private Class getFullyTemplatedClassNew(Class c) {
|
||||
not c.isFromUninstantiatedTemplate(_) and
|
||||
exists(Class mid |
|
||||
c.isConstructedFrom(mid)
|
||||
or
|
||||
not c.isConstructedFrom(_) and c = mid
|
||||
|
|
||||
result = getOriginalClassTemplate(mid)
|
||||
or
|
||||
not mid instanceof TemplateClass and mid = result
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `c`. */
|
||||
private Class getFullyTemplatedClass(Class c) {
|
||||
// The `Class::getOriginalTemplate` predicate was introduced in CodeQL
|
||||
// version 2.25.6 and the upgrade script leaves the
|
||||
// `class_template_generated_from` extensionals empty if the database
|
||||
// was generated with an older extractor. So we use the old implementation
|
||||
// if the `class_template_generated_from` extensional is empty.
|
||||
if class_template_generated_from(_, _)
|
||||
then result = getFullyTemplatedClassNew(c)
|
||||
else result = getFullyTemplatedClassOld(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `f` is an instantiation of a function template `templateFunc`, or
|
||||
* holds with `f = templateFunc` if `f` is not an instantiation of any function
|
||||
@@ -331,7 +292,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) {
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `f`. */
|
||||
private Function getFullyTemplatedFunctionOld(Function f) {
|
||||
Function getFullyTemplatedFunction(Function f) {
|
||||
not f.isFromUninstantiatedTemplate(_) and
|
||||
(
|
||||
exists(Class c, Class templateClass, int i |
|
||||
@@ -345,46 +306,13 @@ private Function getFullyTemplatedFunctionOld(Function f) {
|
||||
)
|
||||
}
|
||||
|
||||
private TemplateFunction getOriginalFunctionTemplate(TemplateFunction tf) {
|
||||
result = tf.getOriginalTemplate()
|
||||
or
|
||||
not exists(tf.getOriginalTemplate()) and
|
||||
result = tf
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `f`. */
|
||||
private Function getFullyTemplatedFunctionNew(Function f) {
|
||||
not f.isFromUninstantiatedTemplate(_) and
|
||||
exists(Function mid |
|
||||
f.isConstructedFrom(mid)
|
||||
or
|
||||
not f.isConstructedFrom(_) and f = mid
|
||||
|
|
||||
result = getOriginalFunctionTemplate(mid)
|
||||
or
|
||||
not mid instanceof TemplateFunction and mid = result
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `f`. */
|
||||
Function getFullyTemplatedFunction(Function f) {
|
||||
// The `Function::getOriginalTemplate` predicate was introduced in CodeQL
|
||||
// version 2.25.6 and the upgrade script leaves the
|
||||
// `function_template_generated_from` extensionals empty if the database
|
||||
// was generated with an older extractor. So we use the old implementation
|
||||
// if the `function_template_generated_from` extensional is empty.
|
||||
if function_template_generated_from(_, _)
|
||||
then result = getFullyTemplatedFunctionNew(f)
|
||||
else result = getFullyTemplatedFunctionOld(f)
|
||||
}
|
||||
|
||||
/** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */
|
||||
bindingset[s, t]
|
||||
private string withConst(string s, Type t) {
|
||||
if t.isConst() then result = "const " + s else result = s
|
||||
}
|
||||
|
||||
/** Prefixes `volatile` to `s` if `t` is volatile, or returns `s` otherwise. */
|
||||
/** Prefixes `volatile` to `s` if `t` is const, or returns `s` otherwise. */
|
||||
bindingset[s, t]
|
||||
private string withVolatile(string s, Type t) {
|
||||
if t.isVolatile() then result = "volatile " + s else result = s
|
||||
@@ -562,7 +490,7 @@ pragma[nomagic]
|
||||
private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) {
|
||||
// If there is a declaring type then we start by expanding the function templates
|
||||
exists(Class template |
|
||||
template = getFullyTemplatedClass(f.getDeclaringType()) and
|
||||
isClassConstructedFrom(f.getDeclaringType(), template) and
|
||||
remaining = getNumberOfSupportedClassTemplateArguments(template) and
|
||||
result = getTypeNameWithoutFunctionTemplates(f, n, 0)
|
||||
)
|
||||
@@ -574,7 +502,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining
|
||||
or
|
||||
exists(string mid, TypeTemplateParameter tp, Class template |
|
||||
mid = getTypeNameWithoutClassTemplates(f, n, remaining + 1) and
|
||||
template = getFullyTemplatedClass(f.getDeclaringType()) and
|
||||
isClassConstructedFrom(f.getDeclaringType(), template) and
|
||||
tp = getSupportedClassTemplateArgument(template, remaining)
|
||||
|
|
||||
result = mid.replaceAll(tp.getName(), "class:" + remaining.toString())
|
||||
|
||||
@@ -1,5 +1,59 @@
|
||||
import semmle.code.cpp.Type
|
||||
|
||||
/** For upgraded databases without mangled name info. */
|
||||
pragma[noinline]
|
||||
private string getTopLevelClassName(@usertype c) {
|
||||
not mangled_name(_, _, _) and
|
||||
isClass(c) and
|
||||
usertypes(c, result, _) and
|
||||
not namespacembrs(_, c) and // not in a namespace
|
||||
not member(_, _, c) and // not in some structure
|
||||
not class_instantiation(c, _) // not a template instantiation
|
||||
}
|
||||
|
||||
/**
|
||||
* For upgraded databases without mangled name info.
|
||||
* Holds if `d` is a unique complete class named `name`.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate existsCompleteWithName(string name, @usertype d) {
|
||||
not mangled_name(_, _, _) and
|
||||
is_complete(d) and
|
||||
name = getTopLevelClassName(d) and
|
||||
onlyOneCompleteClassExistsWithName(name)
|
||||
}
|
||||
|
||||
/** For upgraded databases without mangled name info. */
|
||||
pragma[noinline]
|
||||
private predicate onlyOneCompleteClassExistsWithName(string name) {
|
||||
not mangled_name(_, _, _) and
|
||||
strictcount(@usertype c | is_complete(c) and getTopLevelClassName(c) = name) = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* For upgraded databases without mangled name info.
|
||||
* Holds if `c` is an incomplete class named `name`.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate existsIncompleteWithName(string name, @usertype c) {
|
||||
not mangled_name(_, _, _) and
|
||||
not is_complete(c) and
|
||||
name = getTopLevelClassName(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* For upgraded databases without mangled name info.
|
||||
* Holds if `c` is an incomplete class, and there exists a unique complete class `d`
|
||||
* with the same name.
|
||||
*/
|
||||
private predicate oldHasCompleteTwin(@usertype c, @usertype d) {
|
||||
not mangled_name(_, _, _) and
|
||||
exists(string name |
|
||||
existsIncompleteWithName(name, c) and
|
||||
existsCompleteWithName(name, d)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private @mangledname getClassMangledName(@usertype c) {
|
||||
isClass(c) and
|
||||
@@ -49,7 +103,10 @@ private module Cached {
|
||||
@usertype resolveClass(@usertype c) {
|
||||
hasCompleteTwin(c, result)
|
||||
or
|
||||
oldHasCompleteTwin(c, result)
|
||||
or
|
||||
not hasCompleteTwin(c, _) and
|
||||
not oldHasCompleteTwin(c, _) and
|
||||
result = c
|
||||
}
|
||||
|
||||
|
||||
@@ -1430,8 +1430,7 @@ specialnamequalifyingelements(
|
||||
@namequalifyingelement = @namespace
|
||||
| @specialnamequalifyingelement
|
||||
| @usertype
|
||||
| @decltype
|
||||
| @derivedtype;
|
||||
| @decltype;
|
||||
|
||||
namequalifiers(
|
||||
unique int id: @namequalifier,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
description: Fix NameQualifier inconsistency
|
||||
compatibility: full
|
||||
@@ -1,7 +1,3 @@
|
||||
## 1.6.4
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.6.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.6.4
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.6.4
|
||||
lastReleaseVersion: 1.6.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.6.5-dev
|
||||
version: 1.6.4-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
| common.h:5:12:5:18 | myArray | int[1] |
|
||||
| common.h:5:12:5:18 | myArray | int[8] |
|
||||
|
||||
@@ -51,16 +51,13 @@ models
|
||||
| 50 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||
| 51 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 52 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 53 | Summary: ; TemplateClass1; true; templateFunction2<U,V>; (U,V); ; Argument[1]; ReturnValue; value; manual |
|
||||
| 54 | Summary: ; TemplateClass1<T>; false; templateFunction<U>; (T,U); ; Argument[0]; ReturnValue; value; manual |
|
||||
| 55 | Summary: ; TemplateClass2<T,U>; true; function; (U,T); ; Argument[1]; ReturnValue; value; manual |
|
||||
| 56 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 57 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 58 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
||||
| 59 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
||||
| 60 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
| 53 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 54 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 55 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
||||
| 56 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
||||
| 57 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
edges
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:60 |
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:57 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:32 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:32 Sink:MaD:2 |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
|
||||
@@ -69,24 +66,24 @@ edges
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:60 |
|
||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:59 |
|
||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:56 |
|
||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:57 |
|
||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:58 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:57 |
|
||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:56 |
|
||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:53 |
|
||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:54 |
|
||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:55 |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:29 |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:56 |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:53 |
|
||||
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:57 |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:54 |
|
||||
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:58 |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:55 |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
|
||||
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
|
||||
@@ -103,11 +100,11 @@ edges
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:58 |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:55 |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:59 |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:56 |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:30 |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
|
||||
@@ -183,39 +180,6 @@ edges
|
||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:48 |
|
||||
| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | provenance | MaD:54 |
|
||||
| test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | provenance | MaD:53 |
|
||||
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:133:10:133:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:134:45:134:45 | x | provenance | |
|
||||
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:134:13:134:43 | call to templateFunction | provenance | |
|
||||
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:135:10:135:10 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:134:45:134:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | provenance | |
|
||||
| test.cpp:134:45:134:45 | x | test.cpp:134:13:134:43 | call to templateFunction | provenance | MaD:54 |
|
||||
| test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | provenance | MaD:55 |
|
||||
| test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | provenance | MaD:55 |
|
||||
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:146:10:146:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:148:26:148:26 | x | provenance | |
|
||||
| test.cpp:148:10:148:27 | call to function | test.cpp:148:10:148:27 | call to function | provenance | |
|
||||
| test.cpp:148:10:148:27 | call to function | test.cpp:149:10:149:10 | z | provenance | Sink:MaD:1 |
|
||||
| test.cpp:148:26:148:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | provenance | |
|
||||
| test.cpp:148:26:148:26 | x | test.cpp:148:10:148:27 | call to function | provenance | MaD:55 |
|
||||
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:155:10:155:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:157:26:157:26 | x | provenance | |
|
||||
| test.cpp:157:13:157:20 | call to function | test.cpp:157:13:157:20 | call to function | provenance | |
|
||||
| test.cpp:157:13:157:20 | call to function | test.cpp:158:10:158:10 | z | provenance | Sink:MaD:1 |
|
||||
| test.cpp:157:26:157:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | provenance | |
|
||||
| test.cpp:157:26:157:26 | x | test.cpp:157:13:157:20 | call to function | provenance | MaD:55 |
|
||||
| test.cpp:164:34:164:34 | x | test.cpp:165:69:165:69 | x | provenance | |
|
||||
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:164:7:164:7 | *templateFunction3 | provenance | |
|
||||
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | |
|
||||
| test.cpp:165:69:165:69 | x | test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | provenance | |
|
||||
| test.cpp:165:69:165:69 | x | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | MaD:53 |
|
||||
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:170:10:170:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:172:51:172:51 | x | provenance | |
|
||||
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | |
|
||||
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:173:10:173:10 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | provenance | |
|
||||
| test.cpp:172:51:172:51 | x | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | MaD:53 |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:33 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
|
||||
@@ -519,43 +483,6 @@ nodes
|
||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | semmle.label | call to callWithNonTypeTemplate |
|
||||
| test.cpp:118:44:118:44 | *x | semmle.label | *x |
|
||||
| test.cpp:119:10:119:11 | y2 | semmle.label | y2 |
|
||||
| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | semmle.label | [summary param] 0 in templateFunction |
|
||||
| test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | semmle.label | [summary] to write: ReturnValue in templateFunction |
|
||||
| test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | semmle.label | [summary param] 1 in templateFunction2 |
|
||||
| test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | semmle.label | [summary] to write: ReturnValue in templateFunction2 |
|
||||
| test.cpp:133:10:133:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:133:10:133:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:134:13:134:43 | call to templateFunction | semmle.label | call to templateFunction |
|
||||
| test.cpp:134:13:134:43 | call to templateFunction | semmle.label | call to templateFunction |
|
||||
| test.cpp:134:45:134:45 | x | semmle.label | x |
|
||||
| test.cpp:135:10:135:10 | y | semmle.label | y |
|
||||
| test.cpp:140:4:140:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function |
|
||||
| test.cpp:140:4:140:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function |
|
||||
| test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function |
|
||||
| test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function |
|
||||
| test.cpp:146:10:146:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:146:10:146:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:148:10:148:27 | call to function | semmle.label | call to function |
|
||||
| test.cpp:148:10:148:27 | call to function | semmle.label | call to function |
|
||||
| test.cpp:148:26:148:26 | x | semmle.label | x |
|
||||
| test.cpp:149:10:149:10 | z | semmle.label | z |
|
||||
| test.cpp:155:10:155:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:155:10:155:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:157:13:157:20 | call to function | semmle.label | call to function |
|
||||
| test.cpp:157:13:157:20 | call to function | semmle.label | call to function |
|
||||
| test.cpp:157:26:157:26 | x | semmle.label | x |
|
||||
| test.cpp:158:10:158:10 | z | semmle.label | z |
|
||||
| test.cpp:164:7:164:7 | *templateFunction3 | semmle.label | *templateFunction3 |
|
||||
| test.cpp:164:34:164:34 | x | semmle.label | x |
|
||||
| test.cpp:165:12:165:64 | call to templateFunction2 | semmle.label | call to templateFunction2 |
|
||||
| test.cpp:165:12:165:64 | call to templateFunction2 | semmle.label | call to templateFunction2 |
|
||||
| test.cpp:165:69:165:69 | x | semmle.label | x |
|
||||
| test.cpp:170:10:170:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:170:10:170:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:172:13:172:44 | call to templateFunction3 | semmle.label | call to templateFunction3 |
|
||||
| test.cpp:172:13:172:44 | call to templateFunction3 | semmle.label | call to templateFunction3 |
|
||||
| test.cpp:172:51:172:51 | x | semmle.label | x |
|
||||
| test.cpp:173:10:173:10 | y | semmle.label | y |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA |
|
||||
| windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
|
||||
@@ -761,11 +688,6 @@ subpaths
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
||||
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate |
|
||||
| test.cpp:134:45:134:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | test.cpp:134:13:134:43 | call to templateFunction |
|
||||
| test.cpp:148:26:148:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | test.cpp:148:10:148:27 | call to function |
|
||||
| test.cpp:157:26:157:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | test.cpp:157:13:157:20 | call to function |
|
||||
| test.cpp:165:69:165:69 | x | test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 |
|
||||
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | test.cpp:164:7:164:7 | *templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument |
|
||||
|
||||
@@ -18,7 +18,4 @@ extensions:
|
||||
- ["", "", False, "ymlStepManual_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["", "", False, "ymlStepGenerated_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
|
||||
- ["", "", False, "callWithArgument", "", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"]
|
||||
- ["", "", False, "callWithNonTypeTemplate<T>", "(const T &)", "", "Argument[*0]", "ReturnValue", "value", "manual"]
|
||||
- ["", "TemplateClass1<T>", False, "templateFunction<U>", "(T,U)", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- ["", "TemplateClass1", True, "templateFunction2<U,V>", "(U,V)", "", "Argument[1]", "ReturnValue", "value", "manual"]
|
||||
- ["", "TemplateClass2<T,U>", True, "function", "(U,T)", "", "Argument[1]", "ReturnValue", "value", "manual"]
|
||||
- ["", "", False, "callWithNonTypeTemplate<T>", "(const T &)", "", "Argument[*0]", "ReturnValue", "value", "manual"]
|
||||
@@ -15,7 +15,3 @@
|
||||
| test.cpp:89:11:89:11 | y | test-sink |
|
||||
| test.cpp:116:10:116:11 | y1 | test-sink |
|
||||
| test.cpp:119:10:119:11 | y2 | test-sink |
|
||||
| test.cpp:135:10:135:10 | y | test-sink |
|
||||
| test.cpp:149:10:149:10 | z | test-sink |
|
||||
| test.cpp:158:10:158:10 | z | test-sink |
|
||||
| test.cpp:173:10:173:10 | y | test-sink |
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | local |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | local |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | local |
|
||||
| test.cpp:133:10:133:18 | call to ymlSource | local |
|
||||
| test.cpp:146:10:146:18 | call to ymlSource | local |
|
||||
| test.cpp:155:10:155:18 | call to ymlSource | local |
|
||||
| test.cpp:170:10:170:18 | call to ymlSource | local |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | local |
|
||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local |
|
||||
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local |
|
||||
|
||||
@@ -118,57 +118,3 @@ void test_callWithNonTypeTemplate() {
|
||||
int y2 = callWithNonTypeTemplate<int, 10>(x);
|
||||
ymlSink(y2); // $ ir
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct TemplateClass1 {
|
||||
template<class U>
|
||||
U templateFunction(T, U);
|
||||
|
||||
template<class U, class V>
|
||||
V templateFunction2(U, V);
|
||||
};
|
||||
|
||||
void test_template_function_in_template_class() {
|
||||
TemplateClass1<int> b;
|
||||
int x = ymlSource();
|
||||
auto y = b.templateFunction<unsigned long>(x, 0UL);
|
||||
ymlSink(y); // $ ir
|
||||
}
|
||||
|
||||
template<class S, class T>
|
||||
struct TemplateClass2 {
|
||||
T function(T, S);
|
||||
};
|
||||
|
||||
template<class V> using PartialInstantiationOfTemplateClass2 = TemplateClass2<int, V>;
|
||||
|
||||
void test_partial_class_instantiation() {
|
||||
int x = ymlSource();
|
||||
PartialInstantiationOfTemplateClass2<unsigned long> y;
|
||||
int z = y.function(0UL, x);
|
||||
ymlSink(z); // $ ir
|
||||
}
|
||||
|
||||
template<class V> struct DeriveFromFromPartialTemplateInstantiation : TemplateClass2<int, V> { };
|
||||
|
||||
void test_inheritance() {
|
||||
int x = ymlSource();
|
||||
DeriveFromFromPartialTemplateInstantiation<long> y;
|
||||
auto z = y.function(0L, x);
|
||||
ymlSink(z); // $ ir
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct Class1 : TemplateClass1<T> {
|
||||
template<class U>
|
||||
int templateFunction3(U u, int x) {
|
||||
return TemplateClass1<T>::template templateFunction2<U, int>(u, x);
|
||||
}
|
||||
};
|
||||
|
||||
void test_class1() {
|
||||
int x = ymlSource();
|
||||
Class1<int> c;
|
||||
auto y = c.templateFunction3<unsigned long>(0UL, x);
|
||||
ymlSink(y); // $ ir
|
||||
}
|
||||
@@ -27383,55 +27383,54 @@ getParameterTypeName
|
||||
| stl.h:91:24:91:33 | operator++ | 0 | int |
|
||||
| stl.h:95:44:95:44 | back_inserter | 0 | func:0 & |
|
||||
| stl.h:95:44:95:44 | back_inserter | 0 | func:0 & |
|
||||
| stl.h:147:12:147:23 | basic_string | 0 | const class:2 & |
|
||||
| stl.h:148:3:148:14 | basic_string | 0 | const class:0 * |
|
||||
| stl.h:148:3:148:14 | basic_string | 1 | const class:2 & |
|
||||
| stl.h:149:33:149:44 | basic_string | 0 | func:0 |
|
||||
| stl.h:149:33:149:44 | basic_string | 1 | func:0 |
|
||||
| stl.h:149:33:149:44 | basic_string | 2 | const class:2 & |
|
||||
| stl.h:165:8:165:16 | push_back | 0 | class:0 |
|
||||
| stl.h:148:3:148:14 | basic_string | 0 | const class:2 & |
|
||||
| stl.h:149:33:149:44 | basic_string | 0 | const class:0 * |
|
||||
| stl.h:149:33:149:44 | basic_string | 1 | const class:2 & |
|
||||
| stl.h:151:16:151:20 | c_str | 0 | func:0 |
|
||||
| stl.h:151:16:151:20 | c_str | 1 | func:0 |
|
||||
| stl.h:151:16:151:20 | c_str | 2 | const class:2 & |
|
||||
| stl.h:173:13:173:22 | operator[] | 0 | size_type |
|
||||
| stl.h:175:13:175:14 | at | 0 | size_type |
|
||||
| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & |
|
||||
| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & |
|
||||
| stl.h:177:17:177:26 | operator+= | 0 | const class:0 * |
|
||||
| stl.h:178:17:178:22 | append | 0 | const basic_string & |
|
||||
| stl.h:179:17:179:22 | append | 0 | const class:0 * |
|
||||
| stl.h:180:17:180:22 | append | 0 | size_type |
|
||||
| stl.h:180:17:180:22 | append | 1 | class:0 |
|
||||
| stl.h:181:47:181:52 | append | 0 | func:0 |
|
||||
| stl.h:181:47:181:52 | append | 1 | func:0 |
|
||||
| stl.h:182:17:182:22 | assign | 0 | const basic_string & |
|
||||
| stl.h:183:17:183:22 | assign | 0 | size_type |
|
||||
| stl.h:183:17:183:22 | assign | 1 | class:0 |
|
||||
| stl.h:184:47:184:52 | assign | 0 | func:0 |
|
||||
| stl.h:184:47:184:52 | assign | 1 | func:0 |
|
||||
| stl.h:185:17:185:22 | insert | 0 | size_type |
|
||||
| stl.h:185:17:185:22 | insert | 1 | const basic_string & |
|
||||
| stl.h:176:35:176:44 | operator+= | 0 | size_type |
|
||||
| stl.h:176:35:176:44 | operator+= | 0 | size_type |
|
||||
| stl.h:177:17:177:26 | operator+= | 0 | const func:0 & |
|
||||
| stl.h:178:17:178:22 | append | 0 | const class:0 * |
|
||||
| stl.h:179:17:179:22 | append | 0 | const basic_string & |
|
||||
| stl.h:180:17:180:22 | append | 0 | const class:0 * |
|
||||
| stl.h:181:47:181:52 | append | 0 | size_type |
|
||||
| stl.h:181:47:181:52 | append | 1 | class:0 |
|
||||
| stl.h:182:17:182:22 | assign | 0 | func:0 |
|
||||
| stl.h:182:17:182:22 | assign | 1 | func:0 |
|
||||
| stl.h:183:17:183:22 | assign | 0 | const basic_string & |
|
||||
| stl.h:184:47:184:52 | assign | 0 | size_type |
|
||||
| stl.h:184:47:184:52 | assign | 1 | class:0 |
|
||||
| stl.h:185:17:185:22 | insert | 0 | func:0 |
|
||||
| stl.h:185:17:185:22 | insert | 1 | func:0 |
|
||||
| stl.h:186:17:186:22 | insert | 0 | size_type |
|
||||
| stl.h:186:17:186:22 | insert | 1 | size_type |
|
||||
| stl.h:186:17:186:22 | insert | 2 | class:0 |
|
||||
| stl.h:186:17:186:22 | insert | 1 | const basic_string & |
|
||||
| stl.h:187:17:187:22 | insert | 0 | size_type |
|
||||
| stl.h:187:17:187:22 | insert | 1 | const class:0 * |
|
||||
| stl.h:188:12:188:17 | insert | 0 | const_iterator |
|
||||
| stl.h:188:12:188:17 | insert | 1 | size_type |
|
||||
| stl.h:188:12:188:17 | insert | 2 | class:0 |
|
||||
| stl.h:187:17:187:22 | insert | 1 | size_type |
|
||||
| stl.h:187:17:187:22 | insert | 2 | class:0 |
|
||||
| stl.h:188:12:188:17 | insert | 0 | size_type |
|
||||
| stl.h:188:12:188:17 | insert | 1 | const class:0 * |
|
||||
| stl.h:189:42:189:47 | insert | 0 | const_iterator |
|
||||
| stl.h:189:42:189:47 | insert | 1 | func:0 |
|
||||
| stl.h:189:42:189:47 | insert | 2 | func:0 |
|
||||
| stl.h:190:17:190:23 | replace | 0 | size_type |
|
||||
| stl.h:190:17:190:23 | replace | 1 | size_type |
|
||||
| stl.h:190:17:190:23 | replace | 2 | const basic_string & |
|
||||
| stl.h:189:42:189:47 | insert | 1 | size_type |
|
||||
| stl.h:189:42:189:47 | insert | 2 | class:0 |
|
||||
| stl.h:190:17:190:23 | replace | 0 | const_iterator |
|
||||
| stl.h:190:17:190:23 | replace | 1 | func:0 |
|
||||
| stl.h:190:17:190:23 | replace | 2 | func:0 |
|
||||
| stl.h:191:17:191:23 | replace | 0 | size_type |
|
||||
| stl.h:191:17:191:23 | replace | 1 | size_type |
|
||||
| stl.h:191:17:191:23 | replace | 2 | size_type |
|
||||
| stl.h:191:17:191:23 | replace | 3 | class:0 |
|
||||
| stl.h:192:13:192:16 | copy | 0 | class:0 * |
|
||||
| stl.h:191:17:191:23 | replace | 2 | const basic_string & |
|
||||
| stl.h:192:13:192:16 | copy | 0 | size_type |
|
||||
| stl.h:192:13:192:16 | copy | 1 | size_type |
|
||||
| stl.h:192:13:192:16 | copy | 2 | size_type |
|
||||
| stl.h:194:16:194:21 | substr | 0 | size_type |
|
||||
| stl.h:194:16:194:21 | substr | 1 | size_type |
|
||||
| stl.h:195:8:195:11 | swap | 0 | basic_string & |
|
||||
| stl.h:192:13:192:16 | copy | 3 | class:0 |
|
||||
| stl.h:193:8:193:12 | clear | 0 | class:0 * |
|
||||
| stl.h:193:8:193:12 | clear | 1 | size_type |
|
||||
| stl.h:193:8:193:12 | clear | 2 | size_type |
|
||||
| stl.h:195:8:195:11 | swap | 0 | size_type |
|
||||
| stl.h:195:8:195:11 | swap | 1 | size_type |
|
||||
| stl.h:198:94:198:102 | operator+ | 0 | const basic_string & |
|
||||
| stl.h:198:94:198:102 | operator+ | 1 | const basic_string & |
|
||||
| stl.h:199:94:199:102 | operator+ | 0 | const basic_string & |
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
| extracted_once.h:11:14:11:22 | intMember | file1.c:6:18:6:25 | intAlias | 1 |
|
||||
| extracted_once.h:12:23:12:40 | qualifiedIntMember | file1.c:7:13:7:29 | qualifiedIntAlias | 1 |
|
||||
| extracted_once.h:16:28:16:32 | param | file1.c:6:18:6:25 | intAlias | 1 |
|
||||
| extracted_once.h:11:14:11:22 | intMember | file://:0:0:0:0 | int | 1 |
|
||||
| extracted_once.h:12:23:12:40 | qualifiedIntMember | file://:0:0:0:0 | int | 1 |
|
||||
| extracted_once.h:16:28:16:32 | param | file1.c:6:18:6:25 | intAlias | 2 |
|
||||
| extracted_once.h:16:28:16:32 | param | file2.c:1:13:1:20 | intAlias | 2 |
|
||||
| extracted_twice.h:14:14:14:22 | intMember | file://:0:0:0:0 | int | 1 |
|
||||
| extracted_twice.h:15:23:15:40 | qualifiedIntMember | file://:0:0:0:0 | int | 1 |
|
||||
| extracted_twice.h:24:17:24:28 | structMember | file1.c:8:33:8:43 | structAlias | 1 |
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
| inconsistency2.cpp:3:3:3:5 | T:: | inconsistency2.cpp:3:3:3:6 | x | inconsistency2.cpp:2:20:2:20 | T |
|
||||
| inconsistency2.cpp:3:3:3:11 | const s:: | inconsistency2.cpp:3:3:3:6 | x | file://:0:0:0:0 | const s |
|
||||
| inconsistency.cpp:7:20:7:22 | S:: | inconsistency.cpp:7:20:7:23 | (int)... | inconsistency.cpp:4:8:4:8 | S |
|
||||
| inconsistency.cpp:7:20:7:22 | S:: | inconsistency.cpp:7:20:7:23 | A | inconsistency.cpp:4:8:4:8 | S |
|
||||
| name_qualifiers.cpp:29:7:29:8 | :: | name_qualifiers.cpp:29:7:29:9 | x | file://:0:0:0:0 | (global namespace) |
|
||||
| name_qualifiers.cpp:31:7:31:10 | N1:: | name_qualifiers.cpp:31:7:31:12 | nx | name_qualifiers.cpp:4:11:4:12 | N1 |
|
||||
| name_qualifiers.cpp:34:7:34:8 | :: | name_qualifiers.cpp:34:9:34:12 | N1:: | file://:0:0:0:0 | (global namespace) |
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import cpp
|
||||
|
||||
from NameQualifier nq, Location l
|
||||
where l = nq.getQualifiedElement().getLocation()
|
||||
where
|
||||
l = nq.getQualifiedElement().getLocation() and
|
||||
l.getFile().getShortName() = "name_qualifiers"
|
||||
select nq, nq.getQualifiedElement(), nq.getQualifyingElement()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// This file is present to test whether name-qualifying an enum constant leads to a database inconsistency.
|
||||
|
||||
// As such, there is no QL part of the test.
|
||||
|
||||
struct S { enum E { A }; };
|
||||
|
||||
static void f() {
|
||||
static int f() {
|
||||
switch(0) { case S::A: break; }
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace {
|
||||
template <typename T> T f() {
|
||||
T::x;
|
||||
return {};
|
||||
}
|
||||
struct s {
|
||||
static int x;
|
||||
};
|
||||
struct t {
|
||||
s x = f<const s>();
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
| a.c:4:5:4:6 | definition of is | array of {int} | 1 |
|
||||
| a.h:2:12:2:13 | declaration of is | array of 4 {int} | 1 |
|
||||
| a.h:2:12:2:13 | declaration of is | array of 4 {int} | 1 |
|
||||
| c.c:2:5:2:6 | definition of js | array of {int} | 1 |
|
||||
| c.c:4:5:4:6 | definition of ks | array of 4 {int} | 1 |
|
||||
| c.c:6:5:6:6 | definition of ls | array of 4 {int} | 1 |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
description: Restructure and rename types related to operations.
|
||||
compatibility: full
|
||||
@@ -0,0 +1,304 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
/// <summary>
|
||||
/// Manage the downloading of NuGet packages with nuget.exe.
|
||||
/// Locates packages in a source tree and downloads all of the
|
||||
/// referenced assemblies to a temp folder.
|
||||
/// </summary>
|
||||
internal class NugetExeWrapper : IDisposable
|
||||
{
|
||||
private readonly string? nugetExe;
|
||||
private readonly Semmle.Util.Logging.ILogger logger;
|
||||
|
||||
public int PackageCount => fileProvider.PackagesConfigs.Count;
|
||||
|
||||
private readonly string? backupNugetConfig;
|
||||
private readonly string? nugetConfigPath;
|
||||
private readonly FileProvider fileProvider;
|
||||
|
||||
/// <summary>
|
||||
/// The packages directory.
|
||||
/// This will be in the user-specified or computed Temp location
|
||||
/// so as to not trample the source tree.
|
||||
/// </summary>
|
||||
private readonly DependencyDirectory packageDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// Create the package manager for a specified source tree.
|
||||
/// </summary>
|
||||
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
|
||||
{
|
||||
this.fileProvider = fileProvider;
|
||||
this.packageDirectory = packageDirectory;
|
||||
this.logger = logger;
|
||||
|
||||
if (fileProvider.PackagesConfigs.Count > 0)
|
||||
{
|
||||
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
|
||||
nugetExe = ResolveNugetExe();
|
||||
if (HasNoPackageSource() && useDefaultFeed())
|
||||
{
|
||||
// We only modify or add a top level nuget.config file
|
||||
nugetConfigPath = Path.Combine(fileProvider.SourceDir.FullName, "nuget.config");
|
||||
try
|
||||
{
|
||||
if (File.Exists(nugetConfigPath))
|
||||
{
|
||||
var tempFolderPath = FileUtils.GetTemporaryWorkingDirectory(out _);
|
||||
|
||||
do
|
||||
{
|
||||
backupNugetConfig = Path.Combine(tempFolderPath, Path.GetRandomFileName());
|
||||
}
|
||||
while (File.Exists(backupNugetConfig));
|
||||
File.Copy(nugetConfigPath, backupNugetConfig, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText(nugetConfigPath,
|
||||
"""
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
</packageSources>
|
||||
</configuration>
|
||||
""");
|
||||
}
|
||||
AddDefaultPackageSource(nugetConfigPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError($"Failed to add default package source to {nugetConfigPath}: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the location of `nuget.exe`. It looks for
|
||||
/// - the environment variable specifying a location,
|
||||
/// - files in the repository,
|
||||
/// - tries to resolve nuget from the PATH, or
|
||||
/// - downloads it if it is not found.
|
||||
/// </summary>
|
||||
private string ResolveNugetExe()
|
||||
{
|
||||
var envVarPath = Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetExePath);
|
||||
if (!string.IsNullOrEmpty(envVarPath))
|
||||
{
|
||||
logger.LogInfo($"Using nuget.exe from environment variable: '{envVarPath}'");
|
||||
return envVarPath;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return DownloadNugetExe(fileProvider.SourceDir.FullName);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogInfo($"Download of nuget.exe failed: {exc.Message}");
|
||||
}
|
||||
|
||||
var nugetExesInRepo = fileProvider.NugetExes;
|
||||
if (nugetExesInRepo.Count > 1)
|
||||
{
|
||||
logger.LogInfo($"Found multiple nuget.exe files in the repository: {string.Join(", ", nugetExesInRepo.OrderBy(s => s))}");
|
||||
}
|
||||
|
||||
if (nugetExesInRepo.Count > 0)
|
||||
{
|
||||
var path = nugetExesInRepo.First();
|
||||
logger.LogInfo($"Using nuget.exe from path '{path}'");
|
||||
return path;
|
||||
}
|
||||
|
||||
var executableName = Win32.IsWindows() ? "nuget.exe" : "nuget";
|
||||
var nugetPath = FileUtils.FindProgramOnPath(executableName);
|
||||
if (nugetPath is not null)
|
||||
{
|
||||
nugetPath = Path.Combine(nugetPath, executableName);
|
||||
logger.LogInfo($"Using nuget.exe from PATH: {nugetPath}");
|
||||
return nugetPath;
|
||||
}
|
||||
|
||||
throw new Exception("Could not find or download nuget.exe.");
|
||||
}
|
||||
|
||||
private string DownloadNugetExe(string sourceDir)
|
||||
{
|
||||
var directory = Path.Combine(sourceDir, ".nuget");
|
||||
var nuget = Path.Combine(directory, "nuget.exe");
|
||||
|
||||
// Nuget.exe already exists in the .nuget directory.
|
||||
if (File.Exists(nuget))
|
||||
{
|
||||
logger.LogInfo($"Found nuget.exe at {nuget}");
|
||||
return nuget;
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(directory);
|
||||
logger.LogInfo("Attempting to download nuget.exe");
|
||||
FileUtils.DownloadFile(FileUtils.NugetExeUrl, nuget, logger);
|
||||
logger.LogInfo($"Downloaded nuget.exe to {nuget}");
|
||||
return nuget;
|
||||
}
|
||||
|
||||
private bool RunWithMono => !Win32.IsWindows() && !string.IsNullOrEmpty(Path.GetExtension(nugetExe));
|
||||
|
||||
/// <summary>
|
||||
/// Restore all packages in the specified packages.config file.
|
||||
/// </summary>
|
||||
/// <param name="packagesConfig">The packages.config file.</param>
|
||||
private bool TryRestoreNugetPackage(string packagesConfig)
|
||||
{
|
||||
logger.LogInfo($"Restoring file \"{packagesConfig}\"...");
|
||||
|
||||
/* Use nuget.exe to install a package.
|
||||
* Note that there is a clutch of NuGet assemblies which could be used to
|
||||
* invoke this directly, which would arguably be nicer. However they are
|
||||
* really unwieldy and this solution works for now.
|
||||
*/
|
||||
|
||||
string exe, args;
|
||||
if (RunWithMono)
|
||||
{
|
||||
exe = "mono";
|
||||
args = $"\"{nugetExe}\" install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
exe = nugetExe!;
|
||||
args = $"install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
|
||||
}
|
||||
|
||||
var pi = new ProcessStartInfo(exe, args)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
var threadId = Environment.CurrentManagedThreadId;
|
||||
void onOut(string s) => logger.LogDebug(s, threadId);
|
||||
void onError(string s) => logger.LogError(s, threadId);
|
||||
var exitCode = pi.ReadOutput(out _, onOut, onError);
|
||||
if (exitCode != 0)
|
||||
{
|
||||
logger.LogError($"Command {pi.FileName} {pi.Arguments} failed with exit code {exitCode}");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInfo($"Restored file \"{packagesConfig}\"");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Download the packages to the temp folder.
|
||||
/// </summary>
|
||||
public int InstallPackages()
|
||||
{
|
||||
return fileProvider.PackagesConfigs.Count(TryRestoreNugetPackage);
|
||||
}
|
||||
|
||||
private bool HasNoPackageSource()
|
||||
{
|
||||
if (Win32.IsWindows())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
logger.LogInfo("Checking if default package source is available...");
|
||||
RunMonoNugetCommand("sources list -ForceEnglishOutput", out var stdout);
|
||||
if (stdout.All(line => line != "No sources found."))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogWarning($"Failed to check if default package source is added: {e}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void RunMonoNugetCommand(string command, out IList<string> stdout)
|
||||
{
|
||||
string exe, args;
|
||||
if (RunWithMono)
|
||||
{
|
||||
exe = "mono";
|
||||
args = $"\"{nugetExe}\" {command}";
|
||||
}
|
||||
else
|
||||
{
|
||||
exe = nugetExe!;
|
||||
args = command;
|
||||
}
|
||||
|
||||
var pi = new ProcessStartInfo(exe, args)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
var threadId = Environment.CurrentManagedThreadId;
|
||||
void onOut(string s) => logger.LogDebug(s, threadId);
|
||||
void onError(string s) => logger.LogError(s, threadId);
|
||||
pi.ReadOutput(out stdout, onOut, onError);
|
||||
}
|
||||
|
||||
private void AddDefaultPackageSource(string nugetConfig)
|
||||
{
|
||||
logger.LogInfo("Adding default package source...");
|
||||
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {NugetPackageRestorer.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (nugetConfigPath is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (backupNugetConfig is null)
|
||||
{
|
||||
logger.LogInfo("Removing nuget.config file");
|
||||
File.Delete(nugetConfigPath);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInfo("Reverting nuget.config file content");
|
||||
// The content of the original nuget.config file is reverted without changing the file's attributes or casing:
|
||||
using (var backup = File.OpenRead(backupNugetConfig))
|
||||
using (var current = File.OpenWrite(nugetConfigPath))
|
||||
{
|
||||
current.SetLength(0); // Truncate file
|
||||
backup.CopyTo(current); // Restore original content
|
||||
}
|
||||
|
||||
logger.LogInfo("Deleting backup nuget.config file");
|
||||
File.Delete(backupNugetConfig);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogError($"Failed to restore original nuget.config file: {exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,13 +161,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
reachableFeeds.UnionWith(reachableInheritedFeeds);
|
||||
}
|
||||
|
||||
using (var packagesConfigRestore = PackagesConfigRestoreFactory.Create(fileProvider, legacyPackageDirectory, logger, IsDefaultFeedReachable))
|
||||
using (var nuget = new NugetExeWrapper(fileProvider, legacyPackageDirectory, logger, IsDefaultFeedReachable))
|
||||
{
|
||||
var count = packagesConfigRestore.InstallPackages();
|
||||
var count = nuget.InstallPackages();
|
||||
|
||||
if (packagesConfigRestore.PackageCount > 0)
|
||||
if (nuget.PackageCount > 0)
|
||||
{
|
||||
compilationInfoContainer.CompilationInfos.Add(("packages.config files", packagesConfigRestore.PackageCount.ToString()));
|
||||
compilationInfoContainer.CompilationInfos.Add(("packages.config files", nuget.PackageCount.ToString()));
|
||||
compilationInfoContainer.CompilationInfos.Add(("Successfully restored packages.config files", count.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,368 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal interface IPackagesConfigRestore : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The number of packages.config files found in the source tree.
|
||||
/// </summary>
|
||||
int PackageCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Download the packages to the temp folder.
|
||||
/// </summary>
|
||||
int InstallPackages();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory for creating a package manager to restore NuGet packages referenced in packages.config files.
|
||||
/// If the environment doesn't support using nuget.exe to restore packages from packages.config files, a no-op implementation is returned.
|
||||
/// It is worth noting that for macOS and Linux, nuget.exe is used with mono. However, mono is being deprecated and the last GitHub images
|
||||
/// to contain mono are:
|
||||
/// - Ubuntu 22.04
|
||||
/// - macOS 14
|
||||
///
|
||||
/// If the packages from the packages.config files are not restored with the packages.config restore functionality below, there is a subsequent
|
||||
/// step that still may succeed in restoring the packages without the help of nuget.exe (by attempting to restore using dotnet).
|
||||
/// </summary>
|
||||
internal class PackagesConfigRestoreFactory
|
||||
{
|
||||
public static IPackagesConfigRestore Create(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
|
||||
{
|
||||
if (SystemBuildActions.Instance.IsWindows() || SystemBuildActions.Instance.IsMonoInstalled())
|
||||
{
|
||||
return new NugetExeWrapper(fileProvider, packageDirectory, logger, useDefaultFeed);
|
||||
}
|
||||
|
||||
return new NoOpPackagesConfig(fileProvider, logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manage the downloading of NuGet packages with nuget.exe.
|
||||
/// Locates packages in a source tree and downloads all of the
|
||||
/// referenced assemblies to a temp folder.
|
||||
/// </summary>
|
||||
private class NugetExeWrapper : IPackagesConfigRestore
|
||||
{
|
||||
private readonly string? nugetExe;
|
||||
private readonly Semmle.Util.Logging.ILogger logger;
|
||||
|
||||
public int PackageCount => fileProvider.PackagesConfigs.Count;
|
||||
|
||||
private readonly string? backupNugetConfig;
|
||||
private readonly string? nugetConfigPath;
|
||||
private readonly FileProvider fileProvider;
|
||||
|
||||
/// <summary>
|
||||
/// The packages directory.
|
||||
/// This will be in the user-specified or computed Temp location
|
||||
/// so as to not trample the source tree.
|
||||
/// </summary>
|
||||
private readonly DependencyDirectory packageDirectory;
|
||||
|
||||
private bool IsWindows => SystemBuildActions.Instance.IsWindows();
|
||||
|
||||
/// <summary>
|
||||
/// Create the package manager for a specified source tree.
|
||||
/// </summary>
|
||||
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
|
||||
{
|
||||
this.fileProvider = fileProvider;
|
||||
this.packageDirectory = packageDirectory;
|
||||
this.logger = logger;
|
||||
|
||||
if (fileProvider.PackagesConfigs.Count > 0)
|
||||
{
|
||||
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
|
||||
nugetExe = ResolveNugetExe();
|
||||
if (!HasPackageSource() && useDefaultFeed())
|
||||
{
|
||||
// We only modify or add a top level nuget.config file
|
||||
nugetConfigPath = Path.Join(fileProvider.SourceDir.FullName, "nuget.config");
|
||||
try
|
||||
{
|
||||
if (File.Exists(nugetConfigPath))
|
||||
{
|
||||
var tempFolderPath = FileUtils.GetTemporaryWorkingDirectory(out _);
|
||||
|
||||
do
|
||||
{
|
||||
backupNugetConfig = Path.Join(tempFolderPath, Path.GetRandomFileName());
|
||||
}
|
||||
while (File.Exists(backupNugetConfig));
|
||||
File.Copy(nugetConfigPath, backupNugetConfig, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText(nugetConfigPath,
|
||||
"""
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
</packageSources>
|
||||
</configuration>
|
||||
""");
|
||||
}
|
||||
AddDefaultPackageSource(nugetConfigPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError($"Failed to add default package source to {nugetConfigPath}: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the location of `nuget.exe`. It looks for
|
||||
/// - the environment variable specifying a location,
|
||||
/// - files in the repository,
|
||||
/// - tries to resolve nuget from the PATH, or
|
||||
/// - downloads it if it is not found.
|
||||
/// </summary>
|
||||
private string ResolveNugetExe()
|
||||
{
|
||||
var envVarPath = Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetExePath);
|
||||
if (!string.IsNullOrEmpty(envVarPath))
|
||||
{
|
||||
logger.LogInfo($"Using nuget.exe from environment variable: '{envVarPath}'");
|
||||
return envVarPath;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return DownloadNugetExe(fileProvider.SourceDir.FullName);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogInfo($"Download of nuget.exe failed: {exc.Message}");
|
||||
}
|
||||
|
||||
var nugetExesInRepo = fileProvider.NugetExes;
|
||||
if (nugetExesInRepo.Count > 1)
|
||||
{
|
||||
logger.LogInfo($"Found multiple nuget.exe files in the repository: {string.Join(", ", nugetExesInRepo.OrderBy(s => s))}");
|
||||
}
|
||||
|
||||
if (nugetExesInRepo.Count > 0)
|
||||
{
|
||||
var path = nugetExesInRepo.First();
|
||||
logger.LogInfo($"Using nuget.exe from path '{path}'");
|
||||
return path;
|
||||
}
|
||||
|
||||
var executableName = IsWindows ? "nuget.exe" : "nuget";
|
||||
var nugetPath = FileUtils.FindProgramOnPath(executableName);
|
||||
if (nugetPath is not null)
|
||||
{
|
||||
nugetPath = Path.Join(nugetPath, executableName);
|
||||
logger.LogInfo($"Using nuget.exe from PATH: {nugetPath}");
|
||||
return nugetPath;
|
||||
}
|
||||
|
||||
throw new Exception("Could not find or download nuget.exe.");
|
||||
}
|
||||
|
||||
private string DownloadNugetExe(string sourceDir)
|
||||
{
|
||||
var directory = Path.Join(sourceDir, ".nuget");
|
||||
var nuget = Path.Join(directory, "nuget.exe");
|
||||
|
||||
// Nuget.exe already exists in the .nuget directory.
|
||||
if (File.Exists(nuget))
|
||||
{
|
||||
logger.LogInfo($"Found nuget.exe at {nuget}");
|
||||
return nuget;
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(directory);
|
||||
logger.LogInfo("Attempting to download nuget.exe");
|
||||
FileUtils.DownloadFile(FileUtils.NugetExeUrl, nuget, logger);
|
||||
logger.LogInfo($"Downloaded nuget.exe to {nuget}");
|
||||
return nuget;
|
||||
}
|
||||
|
||||
private bool RunWithMono => !IsWindows && !string.IsNullOrEmpty(Path.GetExtension(nugetExe));
|
||||
|
||||
/// <summary>
|
||||
/// Restore all packages in the specified packages.config file.
|
||||
/// </summary>
|
||||
/// <param name="packagesConfig">The packages.config file.</param>
|
||||
private bool TryRestoreNugetPackage(string packagesConfig)
|
||||
{
|
||||
logger.LogInfo($"Restoring file \"{packagesConfig}\"...");
|
||||
|
||||
/* Use nuget.exe to install a package.
|
||||
* Note that there is a clutch of NuGet assemblies which could be used to
|
||||
* invoke this directly, which would arguably be nicer. However they are
|
||||
* really unwieldy and this solution works for now.
|
||||
*/
|
||||
|
||||
string exe, args;
|
||||
if (RunWithMono)
|
||||
{
|
||||
exe = "mono";
|
||||
args = $"\"{nugetExe}\" install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
exe = nugetExe!;
|
||||
args = $"install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
|
||||
}
|
||||
|
||||
var pi = new ProcessStartInfo(exe, args)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
var threadId = Environment.CurrentManagedThreadId;
|
||||
void onOut(string s) => logger.LogDebug(s, threadId);
|
||||
void onError(string s) => logger.LogError(s, threadId);
|
||||
var exitCode = pi.ReadOutput(out _, onOut, onError);
|
||||
if (exitCode != 0)
|
||||
{
|
||||
logger.LogError($"Command {pi.FileName} {pi.Arguments} failed with exit code {exitCode}");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInfo($"Restored file \"{packagesConfig}\"");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Download the packages to the temp folder.
|
||||
/// </summary>
|
||||
public int InstallPackages()
|
||||
{
|
||||
return fileProvider.PackagesConfigs.Count(TryRestoreNugetPackage);
|
||||
}
|
||||
|
||||
private bool HasPackageSource()
|
||||
{
|
||||
if (IsWindows)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
logger.LogInfo("Checking if default package source is available...");
|
||||
RunMonoNugetCommand("sources list -ForceEnglishOutput", out var stdout);
|
||||
if (stdout.All(line => line != "No sources found."))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogWarning($"Failed to check if default package source is added: {e}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void RunMonoNugetCommand(string command, out IList<string> stdout)
|
||||
{
|
||||
string exe, args;
|
||||
if (RunWithMono)
|
||||
{
|
||||
exe = "mono";
|
||||
args = $"\"{nugetExe}\" {command}";
|
||||
}
|
||||
else
|
||||
{
|
||||
exe = nugetExe!;
|
||||
args = command;
|
||||
}
|
||||
|
||||
var pi = new ProcessStartInfo(exe, args)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
var threadId = Environment.CurrentManagedThreadId;
|
||||
void onOut(string s) => logger.LogDebug(s, threadId);
|
||||
void onError(string s) => logger.LogError(s, threadId);
|
||||
pi.ReadOutput(out stdout, onOut, onError);
|
||||
}
|
||||
|
||||
private void AddDefaultPackageSource(string nugetConfig)
|
||||
{
|
||||
logger.LogInfo("Adding default package source...");
|
||||
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {NugetPackageRestorer.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (nugetConfigPath is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (backupNugetConfig is null)
|
||||
{
|
||||
logger.LogInfo("Removing nuget.config file");
|
||||
File.Delete(nugetConfigPath);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInfo("Reverting nuget.config file content");
|
||||
// The content of the original nuget.config file is reverted without changing the file's attributes or casing:
|
||||
using (var backup = File.OpenRead(backupNugetConfig))
|
||||
using (var current = File.OpenWrite(nugetConfigPath))
|
||||
{
|
||||
current.SetLength(0); // Truncate file
|
||||
backup.CopyTo(current); // Restore original content
|
||||
}
|
||||
|
||||
logger.LogInfo("Deleting backup nuget.config file");
|
||||
File.Delete(backupNugetConfig);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogError($"Failed to restore original nuget.config file: {exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class NoOpPackagesConfig : IPackagesConfigRestore
|
||||
{
|
||||
private readonly Semmle.Util.Logging.ILogger logger;
|
||||
private readonly FileProvider fileProvider;
|
||||
|
||||
public NoOpPackagesConfig(FileProvider fileProvider, Semmle.Util.Logging.ILogger logger)
|
||||
{
|
||||
this.fileProvider = fileProvider;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public int PackageCount => fileProvider.PackagesConfigs.Count;
|
||||
|
||||
public int InstallPackages()
|
||||
{
|
||||
if (PackageCount > 0)
|
||||
{
|
||||
logger.LogInfo("Found packages.config files, but nuget.exe cannot be used to restore packages on this platform. Skipping restore of packages.config files.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -664,7 +664,7 @@ namespace Semmle.Extraction.CSharp
|
||||
// Find the (possibly unbound) original extension method that maps to this implementation (if any).
|
||||
var unboundDeclaration = extensions.SelectMany(e => e.GetMembers())
|
||||
.OfType<IMethodSymbol>()
|
||||
.FirstOrDefault(m => SymbolEqualityComparer.Default.Equals(m.AssociatedExtensionImplementation?.ConstructedFrom, method.ConstructedFrom));
|
||||
.FirstOrDefault(m => SymbolEqualityComparer.Default.Equals(m.AssociatedExtensionImplementation, method.ConstructedFrom));
|
||||
|
||||
var isFullyConstructed = method.IsBoundGenericMethod();
|
||||
if (isFullyConstructed && unboundDeclaration?.ContainingType is INamedTypeSymbol extensionType)
|
||||
|
||||
@@ -69,7 +69,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
|
||||
Overrides(trapFile);
|
||||
ExtractRefReturn(trapFile, Symbol, this);
|
||||
|
||||
if (Symbol.FromSource() && !HasBody)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
@@ -9,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
internal abstract class ElementAccess : Expression<ExpressionSyntax>
|
||||
{
|
||||
protected ElementAccess(ExpressionNodeInfo info, ExpressionSyntax qualifier, BracketedArgumentListSyntax argumentList)
|
||||
: base(info.SetKind(GetKind(info.Context, info.Node, qualifier)))
|
||||
: base(info.SetKind(GetKind(info.Context, qualifier)))
|
||||
{
|
||||
this.qualifier = qualifier;
|
||||
this.argumentList = argumentList;
|
||||
@@ -18,125 +17,6 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
private readonly ExpressionSyntax qualifier;
|
||||
private readonly BracketedArgumentListSyntax argumentList;
|
||||
|
||||
|
||||
private ISymbol? GetTargetSymbol()
|
||||
{
|
||||
return Context.GetSymbolInfo(base.Syntax).Symbol;
|
||||
}
|
||||
|
||||
private static void SetExprArgument(TextWriter trapFile, Expression left, Expression right)
|
||||
{
|
||||
trapFile.expr_argument(left, 0);
|
||||
trapFile.expr_argument(right, 0);
|
||||
}
|
||||
|
||||
private Expression MakeZeroFromEndExpression(IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var info = new ExpressionInfo(
|
||||
Context,
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(Context.Compilation.GetSpecialType(SpecialType.System_Int32)),
|
||||
Location,
|
||||
ExprKind.INDEX,
|
||||
parent,
|
||||
child,
|
||||
isCompilerGenerated: true,
|
||||
null);
|
||||
|
||||
var index = new Expression(info);
|
||||
|
||||
MakeZeroLiteral(index, 0);
|
||||
return index;
|
||||
}
|
||||
|
||||
private Expression MakeZeroLiteral(IExpressionParentEntity parent, int child)
|
||||
{
|
||||
return Literal.CreateGenerated(Context, parent, child, Context.Compilation.GetSpecialType(SpecialType.System_Int32), 0, Location);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// It is assumed that either the input is
|
||||
/// 1. A normal expression that can be used as endpoint (e.g a constant like "3").
|
||||
/// 2. An index expression indicating that we should read from the end (e.g "^1").
|
||||
/// </summary>
|
||||
/// <param name="syntax">The syntax node representing the range endpoint.</param>
|
||||
/// <param name="parent">The parent expression entity.</param>
|
||||
/// <param name="child">The child index within the parent.</param>
|
||||
/// <returns>An expression representing the endpoint of a range to be used in conjunction with a slice operation.</returns>
|
||||
private Expression MakeFromRangeEndpoint(ExpressionSyntax syntax, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var info = new ExpressionNodeInfo(Context, syntax, parent, child);
|
||||
|
||||
return syntax.Kind() == SyntaxKind.IndexExpression
|
||||
? PrefixUnary.Create(info.SetKind(ExprKind.INDEX))
|
||||
: Factory.Create(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given method is a slice method, which is defined as a method with
|
||||
/// the name "Slice" or "Substring" and two parameters.
|
||||
/// </summary>
|
||||
/// <param name="method">The method symbol to check.</param>
|
||||
/// <returns>True if the method is a slice method; false otherwise.</returns>
|
||||
private bool IsSlice(IMethodSymbol method, out RangeExpressionSyntax? range)
|
||||
{
|
||||
range = null;
|
||||
|
||||
if (argumentList.Arguments.Count == 1)
|
||||
{
|
||||
range = argumentList.Arguments[0].Expression as RangeExpressionSyntax;
|
||||
}
|
||||
|
||||
return (method.Name == "Slice" || method.Name == "Substring")
|
||||
&& method.Parameters.Length == 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates a slice method call based on the given range.
|
||||
/// Roslyn translates indexer accesses with range expressions in the following way.
|
||||
/// 1. s[a..b] -> s.Slice(a, b - a)
|
||||
/// 2. s[..b] -> s.Slice(0, b)
|
||||
/// 3. s[a..] -> s.Slice(a, s.Length - a)
|
||||
/// 4. s[..] -> s.Slice(0, s.Length)
|
||||
/// However, it is possible that both the qualifier or the index endpoints may contain method calls.
|
||||
/// If we want to translate this accurately, we would need to introduce synthetic statements for qualifier and
|
||||
/// the endpoints, which should then be used in the slice method call.
|
||||
/// To avoid this, we translate as follows.
|
||||
/// 1. s[a..b] -> s.Slice(a, b)
|
||||
/// 2. s[..b] -> s.Slice(0, b)
|
||||
/// 3. s[a..] -> s.Slice(a, ^0)
|
||||
/// 4. s[..] -> s.Slice(0, ^0)
|
||||
///
|
||||
/// Even though index expressions can't technically be used in this way, they signal that we
|
||||
/// could perceive ^b as "length - b".
|
||||
///
|
||||
/// Call arguments are only populated when a range expression is directly available in
|
||||
/// the list of arguments.
|
||||
/// This means that cases like below are not handled.
|
||||
/// System.Range x = 1..3;
|
||||
/// s[x]
|
||||
/// </summary>
|
||||
/// <param name="trapFile">The trap file to write to.</param>
|
||||
/// <param name="slice">The slice method symbol.</param>
|
||||
/// <param name="range">The range expression syntax.</param>
|
||||
private void PopulateSlice(TextWriter trapFile, IMethodSymbol slice, RangeExpressionSyntax? range)
|
||||
{
|
||||
if (range is not null)
|
||||
{
|
||||
// Populate the call arguments
|
||||
var left = range.LeftOperand is ExpressionSyntax lsyntax
|
||||
? MakeFromRangeEndpoint(lsyntax, this, 0)
|
||||
: MakeZeroLiteral(this, 0);
|
||||
|
||||
var right = range.RightOperand is ExpressionSyntax rsyntax
|
||||
? MakeFromRangeEndpoint(rsyntax, this, 1)
|
||||
: MakeZeroFromEndExpression(this, 1);
|
||||
|
||||
SetExprArgument(trapFile, left, right);
|
||||
}
|
||||
trapFile.expr_call(this, Method.Create(Context, slice));
|
||||
}
|
||||
|
||||
protected override void PopulateExpression(TextWriter trapFile)
|
||||
{
|
||||
if (Kind == ExprKind.POINTER_INDIRECTION)
|
||||
@@ -150,19 +30,11 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
else
|
||||
{
|
||||
Create(Context, qualifier, this, -1);
|
||||
|
||||
var target = GetTargetSymbol();
|
||||
if (target is IMethodSymbol method && IsSlice(method, out var range))
|
||||
{
|
||||
// When an indexer on a span or string is used in conjunction with a range expression, the compiler translates
|
||||
// this into a call to the "Slice" or "Substring" method.
|
||||
// In this case, we want to populate a slice/substring method call instead of an indexer access.
|
||||
PopulateSlice(trapFile, method, range);
|
||||
return;
|
||||
}
|
||||
|
||||
PopulateArguments(trapFile, argumentList, 0);
|
||||
if (target is IPropertySymbol { IsIndexer: true } indexer)
|
||||
|
||||
var symbolInfo = Context.GetSymbolInfo(base.Syntax);
|
||||
|
||||
if (symbolInfo.Symbol is IPropertySymbol indexer)
|
||||
{
|
||||
trapFile.expr_access(this, Indexer.Create(Context, indexer));
|
||||
}
|
||||
@@ -174,11 +46,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
private static bool IsArray(ITypeSymbol symbol) =>
|
||||
symbol.TypeKind == Microsoft.CodeAnalysis.TypeKind.Array || symbol.IsInlineArray();
|
||||
|
||||
private static ExprKind GetKind(Context cx, ExpressionSyntax syntax, ExpressionSyntax qualifier)
|
||||
private static ExprKind GetKind(Context cx, ExpressionSyntax qualifier)
|
||||
{
|
||||
if (cx.GetSymbolInfo(syntax).Symbol is IMethodSymbol)
|
||||
return ExprKind.METHOD_INVOCATION;
|
||||
|
||||
var qualifierType = cx.GetType(qualifier);
|
||||
|
||||
// This is a compilation error, so make a guess and continue.
|
||||
|
||||
@@ -4,7 +4,7 @@ source https://api.nuget.org/v3/index.json
|
||||
# behave like nuget in choosing transitive dependency versions
|
||||
strategy: max
|
||||
|
||||
nuget Basic.CompilerLog.Util 0.9.39
|
||||
nuget Basic.CompilerLog.Util 0.9.25
|
||||
nuget Mono.Posix.NETStandard
|
||||
nuget Newtonsoft.Json
|
||||
nuget NuGet.Versioning
|
||||
@@ -12,7 +12,7 @@ nuget xunit
|
||||
nuget xunit.runner.visualstudio
|
||||
nuget xunit.runner.utility
|
||||
nuget Microsoft.NET.Test.Sdk
|
||||
nuget Microsoft.CodeAnalysis.CSharp 5.3.0
|
||||
nuget Microsoft.CodeAnalysis 5.3.0
|
||||
nuget Microsoft.Build 18.6.3
|
||||
nuget Microsoft.CodeAnalysis.CSharp 5.0.0
|
||||
nuget Microsoft.CodeAnalysis 5.0.0
|
||||
nuget Microsoft.Build 18.0.2
|
||||
nuget Microsoft.VisualStudio.SolutionPersistence
|
||||
|
||||
100
csharp/paket.lock
generated
100
csharp/paket.lock
generated
@@ -3,42 +3,45 @@ STRATEGY: MAX
|
||||
RESTRICTION: == net10.0
|
||||
NUGET
|
||||
remote: https://api.nuget.org/v3/index.json
|
||||
Basic.CompilerLog.Util (0.9.39)
|
||||
Basic.CompilerLog.Util (0.9.25)
|
||||
MessagePack (>= 3.1.4)
|
||||
Microsoft.Bcl.Memory (>= 10.0.7)
|
||||
Microsoft.Bcl.Memory (>= 9.0.10)
|
||||
Microsoft.CodeAnalysis (>= 4.8)
|
||||
Microsoft.CodeAnalysis.CSharp (>= 4.8)
|
||||
Microsoft.CodeAnalysis.VisualBasic (>= 4.8)
|
||||
Microsoft.Extensions.ObjectPool (>= 10.0.7)
|
||||
MSBuild.StructuredLogger (>= 2.3.178)
|
||||
Microsoft.Extensions.ObjectPool (>= 9.0.10)
|
||||
MSBuild.StructuredLogger (>= 2.3.71)
|
||||
NaturalSort.Extension (>= 4.4)
|
||||
NuGet.Versioning (>= 6.14)
|
||||
Humanizer.Core (3.0.10)
|
||||
MessagePack (3.1.6)
|
||||
MessagePack.Annotations (>= 3.1.6)
|
||||
MessagePackAnalyzer (>= 3.1.6)
|
||||
MessagePack (3.1.4)
|
||||
MessagePack.Annotations (>= 3.1.4)
|
||||
MessagePackAnalyzer (>= 3.1.4)
|
||||
Microsoft.NET.StringTools (>= 17.11.4)
|
||||
MessagePack.Annotations (3.1.6)
|
||||
MessagePackAnalyzer (3.1.6)
|
||||
MessagePack.Annotations (3.1.4)
|
||||
MessagePackAnalyzer (3.1.4)
|
||||
Microsoft.Bcl.AsyncInterfaces (10.0.8)
|
||||
Microsoft.Bcl.Memory (10.0.8)
|
||||
Microsoft.Build (18.6.3)
|
||||
Microsoft.Build.Framework (>= 18.6.3)
|
||||
System.Configuration.ConfigurationManager (>= 10.0.3)
|
||||
System.Diagnostics.EventLog (>= 10.0.3)
|
||||
System.Reflection.MetadataLoadContext (>= 10.0.3)
|
||||
System.Security.Cryptography.ProtectedData (>= 10.0.3)
|
||||
Microsoft.Build.Framework (18.6.3)
|
||||
Microsoft.NET.StringTools (>= 18.6.3)
|
||||
Microsoft.Build.Utilities.Core (18.6.3)
|
||||
Microsoft.Build.Framework (>= 18.6.3)
|
||||
System.Configuration.ConfigurationManager (>= 10.0.3)
|
||||
System.Diagnostics.EventLog (>= 10.0.3)
|
||||
System.Security.Cryptography.ProtectedData (>= 10.0.3)
|
||||
Microsoft.CodeAnalysis (5.3)
|
||||
Microsoft.Build (18.0.2)
|
||||
Microsoft.Build.Framework (>= 18.0.2)
|
||||
Microsoft.NET.StringTools (>= 18.0.2)
|
||||
System.Configuration.ConfigurationManager (>= 9.0)
|
||||
System.Diagnostics.EventLog (>= 9.0)
|
||||
System.Reflection.MetadataLoadContext (>= 9.0)
|
||||
System.Security.Cryptography.ProtectedData (>= 9.0.6)
|
||||
Microsoft.Build.Framework (18.4)
|
||||
Microsoft.Build.Utilities.Core (18.4)
|
||||
Microsoft.Build.Framework (>= 18.4)
|
||||
Microsoft.NET.StringTools (>= 18.4)
|
||||
System.Configuration.ConfigurationManager (>= 10.0.1)
|
||||
System.Diagnostics.EventLog (>= 10.0.1)
|
||||
System.Security.Cryptography.ProtectedData (>= 10.0.1)
|
||||
Microsoft.CodeAnalysis (5.0)
|
||||
Humanizer.Core (>= 2.14.1)
|
||||
Microsoft.Bcl.AsyncInterfaces (>= 9.0)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||
Microsoft.CodeAnalysis.CSharp.Workspaces (5.3)
|
||||
Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.3)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.CSharp.Workspaces (5.0)
|
||||
Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.0)
|
||||
System.Buffers (>= 4.6)
|
||||
System.Collections.Immutable (>= 9.0)
|
||||
System.Composition (>= 9.0)
|
||||
@@ -51,36 +54,36 @@ NUGET
|
||||
System.Threading.Channels (>= 8.0)
|
||||
System.Threading.Tasks.Extensions (>= 4.6)
|
||||
Microsoft.CodeAnalysis.Analyzers (5.3)
|
||||
Microsoft.CodeAnalysis.Common (5.3)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||
Microsoft.CodeAnalysis.CSharp (5.3)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||
Microsoft.CodeAnalysis.Common (5.3)
|
||||
Microsoft.CodeAnalysis.CSharp.Workspaces (5.3)
|
||||
Microsoft.CodeAnalysis.Common (5.0)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.CSharp (5.0)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.Common (5.0)
|
||||
Microsoft.CodeAnalysis.CSharp.Workspaces (5.0)
|
||||
Humanizer.Core (>= 2.14.1)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||
Microsoft.CodeAnalysis.Common (5.3)
|
||||
Microsoft.CodeAnalysis.CSharp (5.3)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (5.3)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.Common (5.0)
|
||||
Microsoft.CodeAnalysis.CSharp (5.0)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (5.0)
|
||||
System.Composition (>= 9.0)
|
||||
Microsoft.CodeAnalysis.VisualBasic (5.3)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||
Microsoft.CodeAnalysis.Common (5.3)
|
||||
Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.3)
|
||||
Microsoft.CodeAnalysis.VisualBasic (5.0)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.Common (5.0)
|
||||
Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.0)
|
||||
Humanizer.Core (>= 2.14.1)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||
Microsoft.CodeAnalysis.Common (5.3)
|
||||
Microsoft.CodeAnalysis.VisualBasic (5.3)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (5.3)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.Common (5.0)
|
||||
Microsoft.CodeAnalysis.VisualBasic (5.0)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (5.0)
|
||||
System.Composition (>= 9.0)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (5.3)
|
||||
Microsoft.CodeAnalysis.Workspaces.Common (5.0)
|
||||
Humanizer.Core (>= 2.14.1)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||
Microsoft.CodeAnalysis.Common (5.3)
|
||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
||||
Microsoft.CodeAnalysis.Common (5.0)
|
||||
System.Composition (>= 9.0)
|
||||
Microsoft.CodeCoverage (18.5.1)
|
||||
Microsoft.Extensions.ObjectPool (10.0.8)
|
||||
Microsoft.NET.StringTools (18.6.3)
|
||||
Microsoft.NET.StringTools (18.4)
|
||||
Microsoft.NET.Test.Sdk (18.5.1)
|
||||
Microsoft.CodeCoverage (>= 18.5.1)
|
||||
Microsoft.TestPlatform.TestHost (>= 18.5.1)
|
||||
@@ -94,6 +97,7 @@ NUGET
|
||||
MSBuild.StructuredLogger (2.3.204)
|
||||
Microsoft.Build.Framework (>= 17.5)
|
||||
Microsoft.Build.Utilities.Core (>= 17.5)
|
||||
NaturalSort.Extension (4.4.1)
|
||||
Newtonsoft.Json (13.0.4)
|
||||
NuGet.Versioning (7.6)
|
||||
System.Buffers (4.6.1)
|
||||
|
||||
31
csharp/paket.main.bzl
generated
31
csharp/paket.main.bzl
generated
File diff suppressed because one or more lines are too long
@@ -1,7 +1,3 @@
|
||||
## 1.7.68
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.67
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.7.68
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.68
|
||||
lastReleaseVersion: 1.7.67
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.7.69-dev
|
||||
version: 1.7.68-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
## 1.7.68
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.67
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.7.68
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.68
|
||||
lastReleaseVersion: 1.7.67
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.7.69-dev
|
||||
version: 1.7.68-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
| [...]/csharp/tools/[...]/Microsoft.Win32.Primitives.dll |
|
||||
| [...]/csharp/tools/[...]/Microsoft.Win32.Registry.dll |
|
||||
| [...]/csharp/tools/[...]/Mono.Posix.NETStandard.dll |
|
||||
| [...]/csharp/tools/[...]/NaturalSort.Extension.dll |
|
||||
| [...]/csharp/tools/[...]/Newtonsoft.Json.dll |
|
||||
| [...]/csharp/tools/[...]/NuGet.Versioning.dll |
|
||||
| [...]/csharp/tools/[...]/StructuredLogger.dll |
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
## 6.0.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime.
|
||||
* C# 14: Added support for user-defined instance increment/decrement operators.
|
||||
|
||||
## 6.0.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* C# 14: Added support for user-defined instance increment/decrement operators.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved call target resolution for ref-return properties and indexers.
|
||||
@@ -1,6 +1,4 @@
|
||||
## 6.0.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime.
|
||||
* C# 14: Added support for user-defined instance increment/decrement operators.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved extraction of range-access expressions on spans and strings (for example, `a[0..3]`). These expressions are now extracted as `Slice` (span) or `Substring` (string) calls.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved property and indexer call target resolution for partially overridden properties and indexers.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Added Razor Page handler method parameters (e.g., `OnGet`, `OnPost`, `OnPostAsync`) as remote flow sources, enabling security queries such as `cs/sql-injection` to detect vulnerabilities in `PageModel` subclasses.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* Renamed types related to *operation* expressions. The QL classes `BinaryArithmeticOperation`, `BinaryBitwiseOperation`, and `BinaryLogicalOperation` now include compound assignments; for example, `BinaryArithmeticOperation` now includes `a += b`.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 6.0.2
|
||||
lastReleaseVersion: 6.0.1
|
||||
|
||||
@@ -50,15 +50,15 @@ private predicate maybeUsedInElfHashFunction(Variable v, Operation xor, Operatio
|
||||
|
|
||||
add instanceof AddOperation and
|
||||
e1.getAChild*() = add.getAnOperand() and
|
||||
e1 instanceof BinaryBitwiseExpr and
|
||||
e2 = e1.(BinaryBitwiseExpr).getLeftOperand() and
|
||||
e1 instanceof BinaryBitwiseOperation and
|
||||
e2 = e1.(BinaryBitwiseOperation).getLeftOperand() and
|
||||
v = addAssign.getTargetVariable() and
|
||||
addAssign.getAChild*() = add and
|
||||
(xor instanceof BitwiseXorExpr or xor instanceof AssignXorExpr) and
|
||||
addAssign.getControlFlowNode().getASuccessor*() = xor.getControlFlowNode() and
|
||||
xorAssign.getAChild*() = xor and
|
||||
v = xorAssign.getTargetVariable() and
|
||||
(notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseExpr) and
|
||||
(notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseOperation) and
|
||||
xor.getControlFlowNode().getASuccessor*() = notOp.getControlFlowNode() and
|
||||
notAssign.getAChild*() = notOp and
|
||||
v = notAssign.getTargetVariable() and
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 6.0.3-dev
|
||||
version: 6.0.2-dev
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
@@ -9,7 +9,6 @@ dependencies:
|
||||
codeql/controlflow: ${workspace}
|
||||
codeql/dataflow: ${workspace}
|
||||
codeql/mad: ${workspace}
|
||||
codeql/rangeanalysis: ${workspace}
|
||||
codeql/ssa: ${workspace}
|
||||
codeql/threat-models: ${workspace}
|
||||
codeql/tutorial: ${workspace}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user