Compare commits

..

15 Commits

Author SHA1 Message Date
Andrew Eisenberg
7ccb803dd1 Merge pull request #6375 from github/aeisenberg/pack/python
Packaging: Refactor Python into separate library and query packs
2021-08-16 10:59:19 -07:00
Andrew Eisenberg
016eed8e5c Packaging: Fix more suite references 2021-08-12 16:14:04 -07:00
Andrew Eisenberg
c75f65c493 Packaging: Fix identical-files.json 2021-08-11 19:21:04 -07:00
Andrew Eisenberg
210128e2ae Packaging: Update csharp libraries from main 2021-08-11 16:33:32 -07:00
Andrew Eisenberg
1e36706f4c Packaging: Fix libraryPathDependencies for legacy-support packs
Adds both *-all and *-queries to all.
2021-08-11 13:24:21 -07:00
Andrew Eisenberg
056f9b9471 Packaging: Update references to moved files 2021-08-11 13:23:50 -07:00
Andrew Eisenberg
8cc2201335 Packaging: Update identical files check 2021-08-11 13:23:50 -07:00
Andrew Eisenberg
3f5f73d730 Packaging: Refactor Python into separate library and query packs 2021-08-11 13:23:50 -07:00
Dave Bartolomeo
411a451798 Packaging: Move one more file into library pack 2021-07-28 11:30:11 -04:00
Dave Bartolomeo
b6f0a5dea9 Packaging: Refactor JavaScript into separate query and library packs 2021-07-28 09:46:24 -04:00
Dave Bartolomeo
7079cecdb0 Packaging: Refactor Java packs into separate query and library packs 2021-07-28 00:32:30 -04:00
Dave Bartolomeo
0a24667567 Packaging: Bump pack versions 2021-07-28 00:20:50 -04:00
Dave Bartolomeo
b12771069a Packaging: Mark C# library as a library 2021-07-27 16:22:21 -04:00
Dave Bartolomeo
38f892b120 Packaging: Refactor C# into separate library and query packs 2021-07-27 15:51:33 -04:00
Dave Bartolomeo
3e7bb7c296 Packaging C++: Refactor codeql-cpp into separate library and query packs
This commit does the following:

- creates a new cpp/ql/lib folder and moves the majority of `.qll` files
  from C++ into it.
- updates references to these files from the relevant `.ql` files.
- updates and adds `qlpack.yml` files to create publishable qlpacks
  for cpp.
- updates the ``misc/suite-helpers/qlpack.yml` file to make it
  publishable
- adds qlpack.lock.yml files for each published pack.
2021-07-27 15:03:53 -04:00
40373 changed files with 619974 additions and 3992710 deletions

View File

@@ -1,35 +0,0 @@
common --enable_platform_specific_config
# because we use --override_module with `%workspace%`, the lock file is not stable
common --lockfile_mode=off
# when building from this repository in isolation, the internal repository will not be found at ..
# where `MODULE.bazel` looks for it. The following will get us past the module loading phase, so
# that we can build things that do not rely on that
common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
build --repo_env=CC=clang --repo_env=CXX=clang++
# we use transitions that break builds of `...`, so for `test` to work with that we need the following
test --build_tests_only
# this requires developer mode, but is required to have pack installer functioning
startup --windows_enable_symlinks
common --enable_runfiles
# with the above, we can avoid building python zips which is the default on windows as that's expensive
build --nobuild_python_zip
common --registry=file:///%workspace%/misc/bazel/registry
common --registry=https://bcr.bazel.build
common --@rules_dotnet//dotnet/settings:strict_deps=false
# Reduce this eventually to empty, once we've fixed all our usages of java, and https://github.com/bazel-contrib/rules_go/issues/4193 is fixed
common --incompatible_autoload_externally="+@rules_java,+@rules_shell"
build --java_language_version=17
build --tool_java_language_version=17
build --tool_java_runtime_version=remotejdk_17
build --java_runtime_version=remotejdk_17
try-import %workspace%/local.bazelrc

View File

@@ -1,10 +0,0 @@
# this file should contain bazel settings required to build things from `semmle-code`
common --registry=file:///%workspace%/ql/misc/bazel/registry
common --registry=https://bcr.bazel.build
# See bazelbuild/rules_dotnet#413: strict_deps in C# also appliy to 3rd-party deps, and when we pull
# in (for example) the xunit package, there's no code in this at all, it just depends transitively on
# its implementation packages without providing any code itself.
# We either can depend on internal implementation details, or turn of strict deps.
common --@rules_dotnet//dotnet/settings:strict_deps=false

View File

@@ -1 +0,0 @@
8.0.0

View File

@@ -1 +0,0 @@
DisableFormat: true

8
.codeqlmanifest.json Normal file
View File

@@ -0,0 +1,8 @@
{ "provide": [ "*/ql/lib/qlpack.yml",
"*/ql/src/qlpack.yml",
"*/ql/test/qlpack.yml",
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
"*/ql/examples/qlpack.yml",
"*/upgrades/qlpack.yml",
"misc/legacy-support/*/qlpack.yml",
"misc/suite-helpers/qlpack.yml" ] }

View File

@@ -1,17 +1,9 @@
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
"extensions": [
"rust-lang.rust-analyzer",
"bungcip.better-toml",
"github.vscode-codeql",
"hbenl.vscode-test-explorer",
"ms-vscode.test-adapter-converter",
"slevesque.vscode-zipexplorer"
],
"settings": {
"files.watcherExclude": {
"**/target/**": true
},
"codeQL.runningQueries.memory": 2048
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,21 +0,0 @@
# .git-blame-ignore-revs
# Auto-formatted Java
730eae952139209fe9fdf598541d608f4c0c0c84
# Auto-formatted C#
5ad7ed49dd3de03ec6dcfcb6848758a6a987e11c
# Auto-formatted C/C++
ef97e539ec1971494d4bba5cafe82e00bc8217ac
# Auto-formatted Python
21d5fa836b3a7d020ba45e8b8168b145a9772131
# Auto-formatted JavaScript
8d97fe9ed327a9546ff2eaf515cf0f5214deddd9
# Auto-formatted Ruby
a5d229903d2f12d45f2c2c38822f1d0e7504ae7f
# Auto-formatted Go
08c658e66bf867090033ea096e244a93d46c0aa7
# Auto-formatted Swift
711d7057f79fb7d72fc3b35e010bd018f9009169
# Auto-formatted shared ql packs
3640b6d3a8ce9edf8e1d3ed106fe8526cf255bc0
# Auto-formatted taint tracking files
159d8e978c51959b380838c080d891b66e763b19

40
.gitattributes vendored
View File

@@ -39,7 +39,6 @@
*.py text
*.lua text
*.expected text
*.go text
# Explicitly set a bunch of known extensions to binary, because Git < 2.10 will treat
# `* text=auto eol=lf` as `* text eol=lf`
@@ -49,42 +48,3 @@
*.gif -text
*.dll -text
*.pdb -text
/java/ql/test/stubs/**/*.java linguist-generated=true
/java/ql/test/experimental/stubs/**/*.java linguist-generated=true
/java/kotlin-extractor/deps/*.jar filter=lfs diff=lfs merge=lfs -text
# Force git not to modify line endings for go or html files under the go/ql directory
/go/ql/**/*.go -text
/go/ql/**/*.html -text
# Force git not to modify line endings for go dbschemes
/go/*.dbscheme -text
# Preserve unusual line ending from codeql-go merge
/go/extractor/opencsv/CSVReader.java -text
# For some languages, upgrade script testing references really old dbscheme
# files from legacy upgrades that have CRLF line endings. Since upgrade
# resolution relies on object hashes, we must suppress line ending conversion
# for those testing dbscheme files.
/*/ql/lib/upgrades/initial/*.dbscheme -text
# Auto-generated modeling for Python
/python/ql/lib/semmle/python/frameworks/data/internal/subclass-capture/*.yml linguist-generated=true
# auto-generated bazel lock file
/ruby/extractor/cargo-bazel-lock.json linguist-generated=true
/ruby/extractor/cargo-bazel-lock.json -merge
# auto-generated files for the C# build
/csharp/paket.lock linguist-generated=true
# needs eol=crlf, as `paket` touches this file and saves it as crlf
/csharp/.paket/Paket.Restore.targets linguist-generated=true eol=crlf
/csharp/paket.main.bzl linguist-generated=true
/csharp/paket.main_extension.bzl linguist-generated=true
# ripunzip tool
/misc/ripunzip/ripunzip-* filter=lfs diff=lfs merge=lfs -text
# swift prebuilt resources
/swift/third_party/resources/*.zip filter=lfs diff=lfs merge=lfs -text
/swift/third_party/resources/*.tar.zst filter=lfs diff=lfs merge=lfs -text

View File

@@ -0,0 +1,24 @@
---
name: LGTM.com - false positive
about: Tell us about an alert that shouldn't be reported
title: LGTM.com - false positive
labels: false-positive
assignees: ''
---
**Description of the false positive**
<!-- Please explain briefly why you think it shouldn't be included. -->
**URL to the alert on the project page on LGTM.com**
<!--
1. Open the project on LGTM.com.
For example, https://lgtm.com/projects/g/pallets/click/.
2. Switch to the `Alerts` tab. For example, https://lgtm.com/projects/g/pallets/click/alerts/.
3. Scroll to the alert that you would like to report.
4. Click on the right most icon `View this alert within the complete file`.
5. A new browser tab opens. Copy and paste the page URL here.
For example, https://lgtm.com/projects/g/pallets/click/snapshot/719fb7d8322b0767cdd1e5903ba3eb3233ba8dd5/files/click/_winconsole.py#xa08d213ab3289f87:1.
-->

View File

@@ -10,5 +10,5 @@ assignees: ''
**Description of the issue**
<!-- Please explain briefly what is the problem.
If it is about a GitHub project, please include its URL. -->
If it is about an LGTM project, please include its URL.-->

View File

@@ -1,36 +0,0 @@
---
name: CodeQL false positive
about: Report CodeQL alerts that you think should not have been detected (not applicable, not exploitable, etc.)
title: False positive
labels: false-positive
assignees: ''
---
**Description of the false positive**
<!-- Please explain briefly why you think it shouldn't be included. -->
**Code samples or links to source code**
<!--
For open source code: file links with line numbers on GitHub, for example:
https://github.com/github/codeql/blob/dc440aaee6695deb0d9676b87e06ea984e1b4ae5/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/exec-sh2.js#L10
For closed source code: (redacted) code samples that illustrate the problem, for example:
```
function execSh(command, options) {
return cp.spawn(getShell(), ["-c", command], options) // <- command line injection
};
```
-->
**URL to the alert on GitHub code scanning (optional)**
<!--
1. Open the project on GitHub.com.
2. Switch to the `Security` tab.
3. Browse to the alert that you would like to report.
4. Copy and paste the page URL here.
-->

View File

@@ -1,149 +0,0 @@
name: Cache query compilation
description: Caches CodeQL compilation caches - should be run both on PRs and pushes to main.
inputs:
key:
description: 'The cache key to use - should be unique to the workflow'
required: true
outputs:
cache-dir:
description: "The directory where the cache was stored"
value: ${{ steps.output-compilation-dir.outputs.compdir }}
runs:
using: composite
steps:
# calculate the merge-base with main, in a way that works both on PRs and pushes to main.
- name: Calculate merge-base
shell: bash
if: ${{ github.event_name == 'pull_request' }}
env:
BASE_BRANCH: ${{ github.base_ref }}
run: |
MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ")
echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV
- name: Restore cache (PR)
if: ${{ github.event_name == 'pull_request' }}
uses: actions/cache/restore@v3
with:
path: |
**/.cache
~/.codeql/compile-cache
key: codeql-compile-${{ inputs.key }}-pr-${{ github.sha }}
restore-keys: |
codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }}
codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-
codeql-compile-${{ inputs.key }}-main-
- name: Fill cache (only branch push)
if: ${{ github.event_name != 'pull_request' }}
uses: actions/cache@v3
with:
path: |
**/.cache
~/.codeql/compile-cache
key: codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main
restore-keys: | # restore the latest cache if the exact cache is unavailable, to speed up compilation.
codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-
codeql-compile-${{ inputs.key }}-main-
- name: Output-compilationdir
id: output-compilation-dir
shell: bash
run: |
echo "compdir=${COMBINED_CACHE_DIR}" >> $GITHUB_OUTPUT
env:
COMBINED_CACHE_DIR: ${{ runner.temp }}/compilation-dir
- name: Fill compilation cache directory
id: fill-compilation-dir
uses: actions/github-script@v6
env:
COMBINED_CACHE_DIR: ${{ runner.temp }}/compilation-dir
with:
script: |
// # Move all the existing cache into another folder, so we only preserve the cache for the current queries.
// mkdir -p ${COMBINED_CACHE_DIR}
// rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty.
// # copy the contents of the .cache folders into the combined cache folder.
// cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files
// # clean up the .cache folders
// rm -rf **/.cache/*
const fs = require("fs");
const path = require("path");
const os = require("os");
// the first argv is the cache folder to create.
const COMBINED_CACHE_DIR = process.env.COMBINED_CACHE_DIR;
function* walkCaches(dir) {
const files = fs.readdirSync(dir, { withFileTypes: true });
for (const file of files) {
if (file.isDirectory()) {
const filePath = path.join(dir, file.name);
yield* walkCaches(filePath);
if (file.name === ".cache") {
yield filePath;
}
}
}
}
async function copyDir(src, dest) {
for await (const file of await fs.promises.readdir(src, { withFileTypes: true })) {
const srcPath = path.join(src, file.name);
const destPath = path.join(dest, file.name);
if (file.isDirectory()) {
if (!fs.existsSync(destPath)) {
fs.mkdirSync(destPath);
}
await copyDir(srcPath, destPath);
} else {
await fs.promises.copyFile(srcPath, destPath);
}
}
}
async function main() {
const cacheDirs = [...walkCaches(".")];
for (const dir of cacheDirs) {
console.log(`Found .cache dir at ${dir}`);
}
const globalCacheDir = path.join(os.homedir(), ".codeql", "compile-cache");
if (fs.existsSync(globalCacheDir)) {
console.log("Found global home dir: " + globalCacheDir);
cacheDirs.push(globalCacheDir);
}
if (cacheDirs.length === 0) {
console.log("No cache dirs found");
return;
}
// mkdir -p ${COMBINED_CACHE_DIR}
fs.mkdirSync(COMBINED_CACHE_DIR, { recursive: true });
// rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty.
await Promise.all(
cacheDirs.map((cacheDir) =>
(async function () {
await fs.promises.rm(path.join(cacheDir, "lock"), { force: true });
await fs.promises.rm(path.join(cacheDir, "size"), { force: true });
})()
)
);
// # copy the contents of the .cache folders into the combined cache folder.
// cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files
await Promise.all(
cacheDirs.map((cacheDir) => copyDir(cacheDir, COMBINED_CACHE_DIR))
);
// # clean up the .cache folders
// rm -rf **/.cache/*
await Promise.all(
cacheDirs.map((cacheDir) => fs.promises.rm(cacheDir, { recursive: true }))
);
}
main();

View File

@@ -1,24 +0,0 @@
name: Fetch CodeQL
description: Fetches the latest version of CodeQL
inputs:
channel:
description: 'The CodeQL channel to use'
required: false
default: 'nightly'
runs:
using: composite
steps:
- name: Fetch CodeQL
shell: bash
env:
GITHUB_TOKEN: ${{ github.token }}
CHANNEL: ${{ inputs.channel }}
run: |
gh extension install github/gh-codeql
gh codeql set-channel "$CHANNEL"
gh codeql version
printf "CODEQL_FETCHED_CODEQL_PATH=" >> "${GITHUB_ENV}"
gh codeql version --format=json | jq -r .unpackedLocation >> "${GITHUB_ENV}"
gh codeql version --format=json | jq -r .unpackedLocation >> "${GITHUB_PATH}"

View File

@@ -1,32 +0,0 @@
name: OS Version
description: Get OS version.
outputs:
version:
description: "OS version"
value: ${{ steps.version.outputs.version }}
runs:
using: composite
steps:
- if: runner.os == 'Linux'
shell: bash
run: |
. /etc/os-release
echo "VERSION=${NAME} ${VERSION}" >> $GITHUB_ENV
- if: runner.os == 'Windows'
shell: powershell
run: |
$objects = systeminfo.exe /FO CSV | ConvertFrom-Csv
"VERSION=$($objects.'OS Name') $($objects.'OS Version')" >> $env:GITHUB_ENV
- if: runner.os == 'macOS'
shell: bash
run: |
echo "VERSION=$(sw_vers -productName) $(sw_vers -productVersion)" >> $GITHUB_ENV
- name: Emit OS version
id: version
shell: bash
run: |
echo "$VERSION"
echo "version=${VERSION}" >> $GITHUB_OUTPUT

View File

@@ -9,4 +9,3 @@ paths-ignore:
- '/python/'
- '/javascript/ql/test'
- '/javascript/extractor/tests'
- '/rust/ql'

View File

@@ -1,42 +0,0 @@
version: 2
updates:
- package-ecosystem: "cargo"
directory: "ruby"
schedule:
interval: "daily"
- package-ecosystem: "cargo"
directory: "ql"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
ignore:
- dependency-name: '*'
update-types: ['version-update:semver-patch', 'version-update:semver-minor']
- package-ecosystem: "gomod"
directory: "go/extractor"
schedule:
interval: "daily"
allow:
- dependency-name: "golang.org/x/mod"
- dependency-name: "golang.org/x/tools"
groups:
extractor-dependencies:
patterns:
- "golang.org/x/*"
reviewers:
- "github/codeql-go"
- package-ecosystem: "gomod"
directory: "go/ql/test"
schedule:
interval: "monthly"
ignore:
- dependency-name: "*"
reviewers:
- "github/codeql-go"

36
.github/labeler.yml vendored
View File

@@ -6,51 +6,19 @@
- csharp/**/*
- change-notes/**/*csharp*
Go:
- go/**/*
- change-notes/**/*go.*
Java:
- any: [ 'java/**/*', '!java/kotlin-extractor/**/*', '!java/ql/test/kotlin/**/*' ]
- java/**/*
- change-notes/**/*java.*
JS:
- any: [ 'javascript/**/*' ]
- javascript/**/*
- change-notes/**/*javascript*
Kotlin:
- java/kotlin-extractor/**/*
- java/ql/test-kotlin*/**/*
Python:
- python/**/*
- change-notes/**/*python*
Ruby:
- ruby/**/*
- change-notes/**/*ruby*
Rust:
- rust/**/*
- change-notes/**/*rust*
Swift:
- swift/**/*
- change-notes/**/*swift*
Actions:
- actions/**/*
- change-notes/**/*actions*
documentation:
- "**/*.qhelp"
- "**/*.md"
- docs/**/*
"QL-for-QL":
- ql/**/*
- .github/workflows/ql-for-ql*
# Since these are all shared files that need to be synced, just pick _one_ copy of each.
"DataFlow Library":
- "shared/dataflow/**/*"

View File

@@ -1,14 +0,0 @@
{
"problemMatcher": [
{
"owner": "codeql-query-format",
"pattern": [
{
"regexp": "^((.*) would change by autoformatting\\.)$",
"file": 2,
"message": 1
}
]
}
]
}

View File

@@ -1,17 +0,0 @@
{
"problemMatcher": [
{
"owner": "codeql-syntax-check",
"pattern": [
{
"regexp": "^((ERROR|WARNING): .* \\((.*):(\\d+),(\\d+)-\\d+\\))$",
"message": 1,
"file": 3,
"line": 4,
"col": 5,
"severity": 2
}
]
}
]
}

View File

@@ -1,14 +0,0 @@
{
"problemMatcher": [
{
"owner": "codeql-test-run",
"pattern": [
{
"regexp": "(\\[.*\\] FAILED\\((RESULT|COMPILATION)\\) (.*))$",
"file": 3,
"message": 1
}
]
}
]
}

View File

@@ -1,13 +0,0 @@
{
"problemMatcher": [
{
"owner": "make",
"pattern": [
{
"regexp": "^(make: \\*\\*\\* .*)$",
"message": 1
}
]
}
]
}

View File

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

View File

@@ -1,74 +0,0 @@
name: Build runzip
on:
workflow_dispatch:
inputs:
ripunzip-version:
description: "what reference to checktout from google/runzip"
required: false
default: v1.2.1
openssl-version:
description: "what reference to checkout from openssl/openssl for Linux"
required: false
default: openssl-3.3.0
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, macos-13, windows-2019]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
repository: google/ripunzip
ref: ${{ inputs.ripunzip-version }}
# we need to avoid ripunzip dynamically linking into libssl
# see https://github.com/sfackler/rust-openssl/issues/183
- if: runner.os == 'Linux'
name: checkout openssl
uses: actions/checkout@v4
with:
repository: openssl/openssl
path: openssl
ref: ${{ inputs.openssl-version }}
- if: runner.os == 'Linux'
name: build and install openssl with fPIC
shell: bash
working-directory: openssl
run: |
./config -fPIC --prefix=$HOME/.local --openssldir=$HOME/.local/ssl
make -j $(nproc)
make install_sw -j $(nproc)
- if: runner.os == 'Linux'
name: build (linux)
shell: bash
run: |
env OPENSSL_LIB_DIR=$HOME/.local/lib64 OPENSSL_INCLUDE_DIR=$HOME/.local/include OPENSSL_STATIC=yes cargo build --release
mv target/release/ripunzip ripunzip-linux
- if: runner.os == 'Windows'
name: build (windows)
shell: bash
run: |
cargo build --release
mv target/release/ripunzip ripunzip-windows
- name: build (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
rustup target install x86_64-apple-darwin
rustup target install aarch64-apple-darwin
cargo build --target x86_64-apple-darwin --release
cargo build --target aarch64-apple-darwin --release
lipo -create -output ripunzip-macos \
-arch x86_64 target/x86_64-apple-darwin/release/ripunzip \
-arch arm64 target/aarch64-apple-darwin/release/ripunzip
- uses: actions/upload-artifact@v4
with:
name: ripunzip-${{ runner.os }}
path: ripunzip-*
- name: Check built binary
shell: bash
run: |
./ripunzip-* --version

View File

@@ -1,28 +0,0 @@
name: Check bazel formatting
on:
pull_request:
paths:
- "**.bazel"
- "**.bzl"
branches:
- main
- "rc/*"
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check bazel formatting
uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
with:
extra_args: >
buildifier --all-files 2>&1 ||
(
echo -e "In order to format all bazel files, please run:\n bazel run //misc/bazel/buildifier"; exit 1
)

View File

@@ -1,54 +1,23 @@
name: Check change note
permissions:
pull-requests: read
on:
pull_request_target:
types: [labeled, unlabeled, opened, synchronize, reopened, ready_for_review]
paths:
- "*/ql/src/**/*.ql"
- "*/ql/src/**/*.qll"
- "*/ql/lib/**/*.ql"
- "*/ql/lib/**/*.qll"
- "*/ql/lib/**/*.yml"
- "shared/**/*.ql"
- "shared/**/*.qll"
- "!**/experimental/**"
- "!ql/**"
- "!rust/**"
- ".github/workflows/check-change-note.yml"
jobs:
check-change-note:
env:
REPO: ${{ github.repository }}
PULL_REQUEST_NUMBER: ${{ github.event.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
runs-on: ubuntu-latest
steps:
- name: Fail if no change note found. To fix, either add one, or add the `no-change-note-required` label.
if: |
github.event.pull_request.draft == false &&
!contains(github.event.pull_request.labels.*.name, 'no-change-note-required')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
change_note_files=$(gh api "repos/$REPO/pulls/$PULL_REQUEST_NUMBER/files" --paginate --jq '.[].filename | select(test("/change-notes/.*[.]md$"))')
if [ -z "$change_note_files" ]; then
echo "No change note found. Either add one, or add the 'no-change-note-required' label."
exit 1
fi
echo "Change notes found:"
echo "$change_note_files"
- name: Fail if the change note filename doesn't match the expected format. The file name must be of the form 'YYYY-MM-DD.md', 'YYYY-MM-DD-{title}.md', where '{title}' is arbitrary text, or released/x.y.z.md for released change-notes
run: |
bad_change_note_file_names=$(gh api "repos/$REPO/pulls/$PULL_REQUEST_NUMBER/files" --paginate --jq '[.[].filename | select(test("/change-notes/.*[.]md$"))][] | select((test("/change-notes/[0-9]{4}-[0-9]{2}-[0-9]{2}.*[.]md$") or test("/change-notes/released/[0-9]*[.][0-9]*[.][0-9]*[.]md$")) | not)')
if [ -n "$bad_change_note_file_names" ]; then
echo "The following change note file names are invalid:"
echo "$bad_change_note_file_names"
exit 1
fi
gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq 'any(.[].filename ; test("/change-notes/.*[.]md$"))' |
grep true -c

View File

@@ -1,32 +0,0 @@
name: "Check implicit this warnings"
on:
workflow_dispatch:
pull_request:
paths:
- "**qlpack.yml"
branches:
- main
- "rc/*"
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check that implicit this warnings is enabled for all packs
shell: bash
run: |
EXIT_CODE=0
packs="$(find . -iname 'qlpack.yml')"
for pack_file in ${packs}; do
option="$(yq '.warnOnImplicitThis' ${pack_file})"
if [ "${option}" != "true" ]; then
echo "::error file=${pack_file}::warnOnImplicitThis property must be set to 'true' for pack ${pack_file}"
EXIT_CODE=1
fi
done
exit "${EXIT_CODE}"

View File

@@ -1,54 +0,0 @@
name: "Check QLdoc coverage"
on:
pull_request:
paths:
- "*/ql/lib/**"
- .github/workflows/check-qldoc.yml
- .github/actions/fetch-codeql/action.yml
branches:
- main
- "rc/*"
permissions:
contents: read
jobs:
qldoc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Install CodeQL
uses: ./.github/actions/fetch-codeql
- name: Check QLdoc coverage
shell: bash
run: |
EXIT_CODE=0
# TODO: remove the shared exception from the regex when coverage of qlpacks without dbschemes is supported
# TODO: remove the actions exception once https://github.com/github/codeql-team/issues/3656 is fixed
changed_lib_packs="$(git diff --name-only --diff-filter=ACMRT HEAD^ HEAD | { grep -Po '^(?!(shared|actions))[a-z]*/ql/lib' || true; } | sort -u)"
for pack_dir in ${changed_lib_packs}; do
lang="${pack_dir%/ql/lib}"
codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-current.txt" --dir="${pack_dir}"
done
git checkout HEAD^
for pack_dir in ${changed_lib_packs}; do
# When we add a new language, pack_dir would not exist in HEAD^.
# In this case the right thing to do is to skip the check.
[[ ! -d "${pack_dir}" ]] && continue
lang="${pack_dir%/ql/lib}"
codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-baseline.txt" --dir="${pack_dir}"
awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-current.txt" | sort -u > "${RUNNER_TEMP}/current-undocumented.txt"
awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-baseline.txt" | sort -u > "${RUNNER_TEMP}/baseline-undocumented.txt"
UNDOCUMENTED="$(grep -f <(comm -13 "${RUNNER_TEMP}/baseline-undocumented.txt" "${RUNNER_TEMP}/current-undocumented.txt") "${RUNNER_TEMP}/${lang}-current.txt" || true)"
if [ -n "$UNDOCUMENTED" ]; then
echo "$UNDOCUMENTED" | awk -F, '{gsub(/"/,""); print "::warning file='"${pack_dir}"'/"$1",line="$2"::Missing QLdoc for "$5, $3 }'
EXIT_CODE=1
fi
done
exit "${EXIT_CODE}"

View File

@@ -1,24 +0,0 @@
name: Check query IDs
on:
pull_request:
paths:
- "**/src/**/*.ql"
- misc/scripts/check-query-ids.py
- .github/workflows/check-query-ids.yml
branches:
- main
- "rc/*"
workflow_dispatch:
permissions:
contents: read
jobs:
check:
name: Check query IDs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check for duplicate query IDs
run: python3 misc/scripts/check-query-ids.py

View File

@@ -5,9 +5,6 @@ on:
schedule:
- cron: "30 1 * * *"
permissions:
issues: write
jobs:
stale:
if: github.repository == 'github/codeql'
@@ -15,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue is stale because it has been open 14 days with no activity. Comment or remove the `Stale` label in order to avoid having this issue closed in 7 days.'

View File

@@ -11,8 +11,6 @@ on:
- 'rc/*'
paths:
- 'csharp/**'
- '.github/codeql/**'
- '.github/workflows/codeql-analysis.yml'
schedule:
- cron: '0 9 * * 1'
@@ -27,13 +25,8 @@ jobs:
pull-requests: read
steps:
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.100
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
@@ -45,20 +38,19 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
#- name: Autobuild
# uses: github/codeql-action/autobuild@main
- name: Autobuild
uses: github/codeql-action/autobuild@main
# Command-line programs to run using the OS shell.
# 📚 https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
- run: |
cd csharp
dotnet tool restore
dotnet build .
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@main

View File

@@ -1,46 +0,0 @@
name: "Compile all queries using the latest stable CodeQL CLI"
on:
push:
branches: # makes sure the cache gets populated - running on the branches people tend to merge into.
- main
- "rc/*"
- "codeql-cli-*"
pull_request:
paths:
- '**.ql'
- '**.qll'
- '**/qlpack.yml'
- '**.dbscheme'
permissions:
contents: read
jobs:
compile-queries:
if: github.repository_owner == 'github'
runs-on: ubuntu-latest-xl
steps:
- uses: actions/checkout@v4
- name: Setup CodeQL
uses: ./.github/actions/fetch-codeql
with:
channel: 'release'
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: all-queries
- name: check formatting
run: find shared */ql -type f \( -name "*.qll" -o -name "*.ql" \) -print0 | xargs -0 -n 3000 -P 10 codeql query format -q --check-only
- name: compile queries - check-only
# run with --check-only if running in a PR (github.sha != main)
if : ${{ github.event_name == 'pull_request' }}
shell: bash
run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --check-only --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500 --ram=56000
- name: compile queries - full
# do full compile if running on main - this populates the cache
if : ${{ github.event_name != 'pull_request' }}
shell: bash
run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500 --ram=56000

View File

@@ -1,53 +0,0 @@
name: "Code scanning - C++"
on:
push:
branches:
- main
- 'rc/*'
pull_request:
branches:
- main
- 'rc/*'
paths:
- 'swift/**'
- '.github/codeql/**'
- '.github/workflows/cpp-swift-analysis.yml'
schedule:
- cron: '0 9 * * 1'
jobs:
CodeQL-Build:
runs-on: ubuntu-24.04
permissions:
contents: read
security-events: write
pull-requests: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@main
# Override language selection by uncommenting this and choosing your languages
with:
languages: cpp
config-file: ./.github/codeql/codeql-config.yml
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y uuid-dev
- name: "Build Swift extractor using Bazel"
run: |
bazel clean --expunge
bazel run //swift:install --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results --spawn_strategy=local
bazel shutdown
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@main

View File

@@ -1,71 +0,0 @@
name: "C#: Run QL Tests"
on:
push:
paths:
- "csharp/**"
- "shared/**"
- "misc/bazel/**"
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
- "MODULE.bazel"
branches:
- main
- "rc/*"
pull_request:
paths:
- "csharp/**"
- "shared/**"
- "misc/bazel/**"
- .github/workflows/csharp-qltest.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
- "MODULE.bazel"
branches:
- main
- "rc/*"
defaults:
run:
working-directory: csharp
permissions:
contents: read
jobs:
unit-tests:
strategy:
matrix:
os: [ubuntu-latest, windows-2019]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.100
- name: Extractor unit tests
run: |
dotnet tool restore
dotnet test -p:RuntimeFrameworkVersion=9.0.0 extractor/Semmle.Util.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.0 extractor/Semmle.Extraction.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.0 autobuilder/Semmle.Autobuild.CSharp.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.0 autobuilder/Semmle.Autobuild.Cpp.Tests
shell: bash
stubgentest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./csharp/actions/create-extractor-pack
- name: Run stub generator tests
run: |
# Generate (Asp)NetCore stubs
STUBS_PATH=stubs_output
python3 scripts/stubs/make_stubs_nuget.py webapp Swashbuckle.AspNetCore.Swagger 6.5.0 "$STUBS_PATH"
rm -rf ql/test/resources/stubs/_frameworks
# Update existing stubs in the repo with the freshly generated ones
mv "$STUBS_PATH/output/stubs/_frameworks" ql/test/resources/stubs/
git status
codeql test run --threads=0 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries -- ql/test/library-tests/dataflow/flowsources/aspremote
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -1,75 +0,0 @@
name: "Publish framework coverage as metrics"
on:
schedule:
- cron: '5 0 * * *'
push:
branches:
- main
workflow_dispatch:
pull_request:
branches:
- main
paths:
- ".github/workflows/csv-coverage-metrics.yml"
- ".github/actions/fetch-codeql/action.yml"
permissions:
contents: read
security-events: write
jobs:
publish-java:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup CodeQL
uses: ./.github/actions/fetch-codeql
- name: Create empty database
run: |
DATABASE="${{ runner.temp }}/java-database"
PROJECT="${{ runner.temp }}/java-project"
mkdir -p "$PROJECT/src/tmp/empty"
echo "class Empty {}" >> "$PROJECT/src/tmp/empty/Empty.java"
codeql database create "$DATABASE" --language=java --source-root="$PROJECT" --command 'javac src/tmp/empty/Empty.java'
- name: Capture coverage information
run: |
DATABASE="${{ runner.temp }}/java-database"
codeql database analyze --format=sarif-latest --output=metrics-java.sarif -- "$DATABASE" ./java/ql/src/Metrics/Summaries/FrameworkCoverage.ql
- uses: actions/upload-artifact@v4
with:
name: metrics-java.sarif
path: metrics-java.sarif
retention-days: 20
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@main
with:
sarif_file: metrics-java.sarif
publish-csharp:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup CodeQL
uses: ./.github/actions/fetch-codeql
- name: Create empty database
run: |
DATABASE="${{ runner.temp }}/csharp-database"
PROJECT="${{ runner.temp }}/csharp-project"
dotnet new classlib --language=C# --output="$PROJECT"
codeql database create "$DATABASE" --language=csharp --source-root="$PROJECT" --command 'dotnet build /t:rebuild csharp-project.csproj'
- name: Capture coverage information
run: |
DATABASE="${{ runner.temp }}/csharp-database"
codeql database analyze --format=sarif-latest --output=metrics-csharp.sarif -- "$DATABASE" ./csharp/ql/src/Metrics/Summaries/FrameworkCoverage.ql
- uses: actions/upload-artifact@v4
with:
name: metrics-csharp.sarif
path: metrics-csharp.sarif
retention-days: 20
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@main
with:
sarif_file: metrics-csharp.sarif

View File

@@ -3,25 +3,16 @@ name: Check framework coverage changes
on:
pull_request:
paths:
- ".github/workflows/csv-coverage-pr-comment.yml"
- ".github/workflows/csv-coverage-pr-artifacts.yml"
- ".github/actions/fetch-codeql/action.yml"
- "*/ql/src/**/*.ql"
- "*/ql/src/**/*.qll"
- "*/ql/lib/**/*.ql"
- "*/ql/lib/**/*.qll"
- "*/ql/lib/ext/**/*.yml"
- "misc/scripts/library-coverage/*.py"
- '.github/workflows/csv-coverage-pr-comment.yml'
- '*/ql/src/**/*.ql'
- '*/ql/src/**/*.qll'
- 'misc/scripts/library-coverage/*.py'
# input data files
- "*/documentation/library-coverage/cwe-sink.csv"
- "*/documentation/library-coverage/frameworks.csv"
- '*/documentation/library-coverage/cwe-sink.csv'
- '*/documentation/library-coverage/frameworks.csv'
branches:
- main
- "rc/*"
permissions:
contents: read
pull-requests: read
- 'rc/*'
jobs:
generate:
@@ -30,95 +21,77 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - MERGE
uses: actions/checkout@v4
with:
path: merge
- name: Clone self (github/codeql) - BASE
uses: actions/checkout@v4
with:
fetch-depth: 2
path: base
- run: |
git checkout HEAD^1
git log -1 --format='%H'
working-directory: base
- name: Set up Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Download CodeQL CLI
uses: ./merge/.github/actions/fetch-codeql
- name: Generate CSV files on merge commit of the PR
run: |
echo "Running generator on merge"
python merge/misc/scripts/library-coverage/generate-report.py ci merge merge
mkdir out_merge
cp framework-coverage-*.csv out_merge/
cp framework-coverage-*.rst out_merge/
- name: Generate CSV files on base commit of the PR
run: |
echo "Running generator on base"
python base/misc/scripts/library-coverage/generate-report.py ci base base
mkdir out_base
cp framework-coverage-*.csv out_base/
cp framework-coverage-*.rst out_base/
- name: Generate diff of coverage reports
run: |
python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md
- name: Upload CSV package list
uses: actions/upload-artifact@v4
with:
name: csv-framework-coverage-merge
path: |
out_merge/framework-coverage-*.csv
out_merge/framework-coverage-*.rst
- name: Upload CSV package list
uses: actions/upload-artifact@v4
with:
name: csv-framework-coverage-base
path: |
out_base/framework-coverage-*.csv
out_base/framework-coverage-*.rst
- name: Upload comparison results
uses: actions/upload-artifact@v4
with:
name: comparison
path: |
comparison.md
- name: Save PR number
run: |
mkdir -p pr
echo ${PR_NUMBER} > pr/NR
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
- name: Upload PR number
uses: actions/upload-artifact@v4
with:
name: pr
path: pr/
- name: Save comment ID (if it exists)
run: |
# Find the latest comment starting with COMMENT_PREFIX
COMMENT_PREFIX=":warning: The head of this PR and the base branch were compared for differences in the framework coverage reports."
COMMENT_ID=$(gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" --paginate | jq --arg prefix "${COMMENT_PREFIX}" 'map(select(.body|startswith($prefix)) | .id) | max // empty')
if [[ -z ${COMMENT_ID} ]]
then
echo "Comment not found. Not uploading 'comment/ID' artifact."
else
mkdir -p comment
echo ${COMMENT_ID} > comment/ID
fi
env:
GITHUB_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
- name: Upload comment ID (if it exists)
uses: actions/upload-artifact@v4
with:
name: comment
path: comment/
if-no-files-found: ignore
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - MERGE
uses: actions/checkout@v2
with:
path: merge
- name: Clone self (github/codeql) - BASE
uses: actions/checkout@v2
with:
fetch-depth: 2
path: base
- run: |
git checkout HEAD^1
git log -1 --format='%H'
working-directory: base
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Download CodeQL CLI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Generate CSV files on merge commit of the PR
run: |
echo "Running generator on merge"
PATH="$PATH:codeql-cli/codeql" python merge/misc/scripts/library-coverage/generate-report.py ci merge merge
mkdir out_merge
cp framework-coverage-*.csv out_merge/
cp framework-coverage-*.rst out_merge/
- name: Generate CSV files on base commit of the PR
run: |
echo "Running generator on base"
PATH="$PATH:codeql-cli/codeql" python base/misc/scripts/library-coverage/generate-report.py ci base base
mkdir out_base
cp framework-coverage-*.csv out_base/
cp framework-coverage-*.rst out_base/
- name: Generate diff of coverage reports
run: |
python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md
- name: Upload CSV package list
uses: actions/upload-artifact@v2
with:
name: csv-framework-coverage-merge
path: |
out_merge/framework-coverage-*.csv
out_merge/framework-coverage-*.rst
- name: Upload CSV package list
uses: actions/upload-artifact@v2
with:
name: csv-framework-coverage-base
path: |
out_base/framework-coverage-*.csv
out_base/framework-coverage-*.rst
- name: Upload comparison results
uses: actions/upload-artifact@v2
with:
name: comparison
path: |
comparison.md
- name: Save PR number
run: |
mkdir -p pr
echo ${{ github.event.pull_request.number }} > pr/NR
- name: Upload PR number
uses: actions/upload-artifact@v2
with:
name: pr
path: pr/

View File

@@ -6,10 +6,6 @@ on:
types:
- completed
permissions:
contents: read
pull-requests: write
jobs:
check:
name: Check framework coverage differences and comment
@@ -24,9 +20,9 @@ jobs:
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql)
uses: actions/checkout@v4
uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v4
uses: actions/setup-python@v2
with:
python-version: 3.8

View File

@@ -3,34 +3,40 @@ name: Build framework coverage timeseries reports
on:
workflow_dispatch:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Clone self (github/codeql)
uses: actions/checkout@v4
with:
path: script
- name: Clone self (github/codeql) for analysis
uses: actions/checkout@v4
with:
path: codeqlModels
fetch-depth: 0
- name: Set up Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Download CodeQL CLI
uses: ./script/.github/actions/fetch-codeql
- name: Build modeled package list
run: |
python script/misc/scripts/library-coverage/generate-timeseries.py codeqlModels
- name: Upload timeseries CSV
uses: actions/upload-artifact@v4
with:
name: framework-coverage-timeseries
path: framework-coverage-timeseries-*.csv
- name: Clone self (github/codeql)
uses: actions/checkout@v2
with:
path: script
- name: Clone self (github/codeql) for analysis
uses: actions/checkout@v2
with:
path: codeqlModels
fetch-depth: 0
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Download CodeQL CLI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Build modeled package list
run: |
CLI=$(realpath "codeql-cli/codeql")
echo $CLI
PATH="$PATH:$CLI" python script/misc/scripts/library-coverage/generate-timeseries.py codeqlModels
- name: Upload timeseries CSV
uses: actions/upload-artifact@v2
with:
name: framework-coverage-timeseries
path: framework-coverage-timeseries-*.csv

View File

@@ -5,38 +5,40 @@ on:
schedule:
- cron: "0 0 * * *"
permissions:
contents: write
pull-requests: write
jobs:
update:
name: Update framework coverage report
if: github.repository == 'github/codeql'
if: github.event.repository.fork == false
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql)
uses: actions/checkout@v4
with:
path: ql
fetch-depth: 0
- name: Set up Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Download CodeQL CLI
uses: ./ql/.github/actions/fetch-codeql
- name: Generate coverage files
run: |
python ql/misc/scripts/library-coverage/generate-report.py ci ql ql
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql)
uses: actions/checkout@v2
with:
path: ql
fetch-depth: 0
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Download CodeQL CLI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Create pull request with changes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python ql/misc/scripts/library-coverage/create-pr.py ql "$GITHUB_REPOSITORY"
- name: Generate coverage files
run: |
PATH="$PATH:codeql-cli/codeql" python ql/misc/scripts/library-coverage/generate-report.py ci ql ql
- name: Create pull request with changes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python ql/misc/scripts/library-coverage/create-pr.py ql "$GITHUB_REPOSITORY"

View File

@@ -4,42 +4,46 @@ on:
workflow_dispatch:
inputs:
qlModelShaOverride:
description: "github/codeql repo SHA used for looking up the CSV models"
description: 'github/codeql repo SHA used for looking up the CSV models'
required: false
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Clone self (github/codeql)
uses: actions/checkout@v4
with:
path: script
- name: Clone self (github/codeql) for analysis
uses: actions/checkout@v4
with:
path: codeqlModels
ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }}
- name: Set up Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Download CodeQL CLI
uses: ./script/.github/actions/fetch-codeql
- name: Build modeled package list
run: |
python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script
- name: Upload CSV package list
uses: actions/upload-artifact@v4
with:
name: framework-coverage-csv
path: framework-coverage-*.csv
- name: Upload RST package list
uses: actions/upload-artifact@v4
with:
name: framework-coverage-rst
path: framework-coverage-*.rst
- name: Clone self (github/codeql)
uses: actions/checkout@v2
with:
path: script
- name: Clone self (github/codeql) for analysis
uses: actions/checkout@v2
with:
path: codeqlModels
ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }}
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Download CodeQL CLI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Build modeled package list
run: |
PATH="$PATH:codeql-cli/codeql" python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script
- name: Upload CSV package list
uses: actions/upload-artifact@v2
with:
name: framework-coverage-csv
path: framework-coverage-*.csv
- name: Upload RST package list
uses: actions/upload-artifact@v2
with:
name: framework-coverage-rst
path: framework-coverage-*.rst

View File

@@ -1,51 +0,0 @@
# Fast-forwards the branch specified in BRANCH_NAME
# to the github.ref/sha that this workflow is run on.
# Used as part of the release process, to ensure
# external query writers can always access a branch of github/codeql
# that is compatible with the latest stable release.
name: Fast-forward tracking branch for selected CodeQL version
on:
workflow_dispatch:
permissions:
contents: write
jobs:
fast-forward:
name: Fast-forward tracking branch for selected CodeQL version
runs-on: ubuntu-latest
if: github.repository == 'github/codeql'
env:
BRANCH_NAME: 'lgtm.com'
steps:
- name: Validate chosen branch
if: ${{ !startsWith(github.ref_name, 'codeql-cli-') }}
shell: bash
run: |
echo "::error ::The $BRANCH_NAME tracking branch should only be fast-forwarded to the tip of a codeql-cli-* branch, got $GITHUB_REF_NAME instead."
exit 1
- name: Checkout
uses: actions/checkout@v4
- name: Git config
shell: bash
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Fetch
shell: bash
run: |
set -x
echo "Fetching $BRANCH_NAME"
# Explicitly unshallow and fetch to ensure the remote ref is available.
git fetch --unshallow origin "$BRANCH_NAME"
git checkout -b "$BRANCH_NAME" "origin/$BRANCH_NAME"
- name: Fast-forward
shell: bash
run: |
echo "Fast-forwarding $BRANCH_NAME to ${GITHUB_REF}@${GITHUB_SHA}"
git merge --ff-only "$GITHUB_SHA"
git push origin "$BRANCH_NAME"

View File

@@ -1,35 +0,0 @@
name: "Go: Run Tests - Other OS"
on:
pull_request:
paths:
- "go/**"
- "!go/ql/**" # don't run other-os if only ql/ files changed
- .github/workflows/go-tests-other-os.yml
- .github/actions/**
- codeql-workspace.yml
- MODULE.bazel
- .bazelrc
- misc/bazel/**
permissions:
contents: read
jobs:
test-mac:
name: Test MacOS
runs-on: macos-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Run tests
uses: ./go/actions/test
test-win:
if: github.repository_owner == 'github'
name: Test Windows
runs-on: windows-latest-xl
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Run tests
uses: ./go/actions/test

View File

@@ -1,38 +0,0 @@
name: "Go: Run Tests"
on:
push:
paths:
- "go/**"
- "shared/**"
- .github/workflows/go-tests.yml
- .github/actions/**
- codeql-workspace.yml
branches:
- main
- "rc/*"
pull_request:
paths:
- "go/**"
- "shared/**"
- .github/workflows/go-tests.yml
- .github/actions/**
- codeql-workspace.yml
- MODULE.bazel
- .bazelrc
- misc/bazel/**
permissions:
contents: read
jobs:
test-linux:
if: github.repository_owner == 'github'
name: Test Linux (Ubuntu)
runs-on: ubuntu-latest-xl
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Run tests
uses: ./go/actions/test
with:
run-code-checks: true

View File

@@ -1,28 +0,0 @@
name: "Kotlin Build"
on:
pull_request:
paths:
- "java/kotlin-extractor/**"
- "misc/bazel/**"
- "misc/codegen/**"
- "*.bazel*"
- .github/workflows/kotlin-build.yml
branches:
- main
- rc/*
- codeql-cli-*
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
bazel query //java/kotlin-extractor/...
# only build the default version as a quick check that we can build from `codeql`
# the full official build will be checked by QLucie
bazel build //java/kotlin-extractor

View File

@@ -2,14 +2,10 @@ name: "Pull Request Labeler"
on:
- pull_request_target
permissions:
contents: read
pull-requests: write
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4
- uses: actions/labeler@v2
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@@ -1,113 +0,0 @@
name: Models as Data - Diff
on:
workflow_dispatch:
inputs:
projects:
description: "The projects to generate models for"
required: true
default: '["netty/netty"]'
pull_request:
branches:
- main
paths:
- "java/ql/src/utils/modelgenerator/**/*.*"
- "misc/scripts/models-as-data/*.*"
- ".github/workflows/mad_modelDiff.yml"
permissions:
contents: read
jobs:
model-diff:
name: Model Difference
runs-on: ubuntu-latest
if: github.repository == 'github/codeql'
strategy:
matrix:
slug: ${{fromJson(github.event.inputs.projects || '["apache/commons-codec", "apache/commons-io", "apache/commons-beanutils", "apache/commons-logging", "apache/commons-fileupload", "apache/commons-lang", "apache/commons-validator", "apache/commons-csv", "apache/dubbo"]' )}}
steps:
- name: Clone github/codeql from PR
uses: actions/checkout@v4
if: github.event.pull_request
with:
path: codeql-pr
- name: Clone github/codeql from main
uses: actions/checkout@v4
with:
path: codeql-main
ref: main
- uses: ./codeql-main/.github/actions/fetch-codeql
# compute the shortname of the project that does not contain any special (disk) characters
- run: |
echo "SHORTNAME=${SLUG//[^a-zA-Z0-9_]/}" >> $GITHUB_OUTPUT
env:
SLUG: ${{ matrix.slug }}
id: shortname
- name: Download database
env:
SLUG: ${{ matrix.slug }}
GH_TOKEN: ${{ github.token }}
SHORTNAME: ${{ steps.shortname.outputs.SHORTNAME }}
run: |
set -x
mkdir lib-dbs
gh api -H "Accept: application/zip" "/repos/${SLUG}/code-scanning/codeql/databases/java" > "$SHORTNAME.zip"
unzip -q -d "${SHORTNAME}-db" "${SHORTNAME}.zip"
mkdir "lib-dbs/$SHORTNAME/"
mv "${SHORTNAME}-db/"$(ls -1 "${SHORTNAME}"-db)/* "lib-dbs/${SHORTNAME}/"
- name: Generate Models (PR and main)
run: |
set -x
mkdir tmp-models
MODELS=`pwd`/tmp-models
DATABASES=`pwd`/lib-dbs
analyzeDatabaseWithCheckout() {
QL_VARIANT=$1
DATABASE=$2
cd codeql-$QL_VARIANT
SHORTNAME=`basename $DATABASE`
python java/ql/src/utils/modelgenerator/GenerateFlowModel.py --with-summaries --with-sinks $DATABASE $SHORTNAME/$QL_VARIANT
mkdir -p $MODELS/$SHORTNAME
mv java/ql/lib/ext/generated/$SHORTNAME/$QL_VARIANT $MODELS/$SHORTNAME
cd ..
}
for d in $DATABASES/*/ ; do
ls -1 "$d"
analyzeDatabaseWithCheckout "main" $d
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]
then
analyzeDatabaseWithCheckout "pr" $d
fi
done
- name: Install diff2html
if: github.event.pull_request
run: |
npm install -g diff2html-cli
- name: Generate Model Diff
if: github.event.pull_request
run: |
set -x
MODELS=`pwd`/tmp-models
ls -1 tmp-models/
for m in $MODELS/*/main/*.model.yml ; do
t="${m/main/"pr"}"
basename=`basename $m`
name="diff_${basename/.model.yml/""}"
(diff -w -u $m $t | diff2html -i stdin -F $MODELS/$name.html) || true
done
- uses: actions/upload-artifact@v4
with:
name: models-${{ steps.shortname.outputs.SHORTNAME }}
path: tmp-models/**/**/*.model.yml
retention-days: 20
- uses: actions/upload-artifact@v4
with:
name: diffs-${{ steps.shortname.outputs.SHORTNAME }}
path: tmp-models/*.html
# An html file is only produced if the generated models differ.
if-no-files-found: ignore
retention-days: 20

View File

@@ -1,66 +0,0 @@
name: Regenerate framework models
on:
workflow_dispatch:
schedule:
- cron: "30 2 * * *"
pull_request:
branches:
- main
paths:
- ".github/workflows/mad_regenerate-models.yml"
- ".github/actions/fetch-codeql/action.yml"
permissions:
contents: read
jobs:
regenerate-models:
runs-on: ubuntu-latest
strategy:
matrix:
# placeholder required for each axis, excluded below, replaced by the actual combinations (see include)
slug: ["placeholder"]
ref: ["placeholder"]
include:
- slug: "apache/commons-io"
ref: "13258ce2d07aa0e764bbaa8020af4dcd3a02a620"
exclude:
- slug: "placeholder"
ref: "placeholder"
steps:
- name: Clone self (github/codeql)
uses: actions/checkout@v4
- name: Setup CodeQL binaries
uses: ./.github/actions/fetch-codeql
- name: Clone repositories
uses: actions/checkout@v4
with:
path: repos/${{ matrix.ref }}
ref: ${{ matrix.ref }}
repository: ${{ matrix.slug }}
- name: Build database
env:
SLUG: ${{ matrix.slug }}
REF: ${{ matrix.ref }}
run: |
mkdir dbs
cd repos/${REF}
SHORTNAME=${SLUG//[^a-zA-Z0-9_]/}
codeql database create --language=java ../../dbs/${SHORTNAME}
- name: Regenerate models in-place
env:
SLUG: ${{ matrix.slug }}
run: |
SHORTNAME=${SLUG//[^a-zA-Z0-9_]/}
java/ql/src/utils/modelgenerator/RegenerateModels.py "${SLUG}" dbs/${SHORTNAME}
- name: Stage changes
run: |
find java -name "*.model.yml" -print0 | xargs -0 git add
git status
git diff --cached > models.patch
- uses: actions/upload-artifact@v4
with:
name: patch
path: models.patch
retention-days: 7

View File

@@ -1,77 +0,0 @@
# This workflow is the second part of the process described in
# .github/workflows/qhelp-pr-preview.yml
# See that file for more info.
name: Post PR comment
on:
workflow_run:
workflows: [Render QHelp changes]
types:
- completed
permissions:
pull-requests: write
actions: read
jobs:
post_comment:
runs-on: ubuntu-latest
steps:
- name: Download artifacts
run: |
gh run download "${WORKFLOW_RUN_ID}" --repo "${GITHUB_REPOSITORY}" --name "comment-pr-number"
gh run download "${WORKFLOW_RUN_ID}" --repo "${GITHUB_REPOSITORY}" --name "comment-body"
gh run download "${WORKFLOW_RUN_ID}" --repo "${GITHUB_REPOSITORY}" --name "comment-id"
env:
GITHUB_TOKEN: ${{ github.token }}
WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }}
- name: Check that PR SHA matches workflow SHA
run: |
PR="$(grep -o '^[0-9]\+$' pr_number.txt)"
PR_HEAD_SHA="$(gh api "/repos/${GITHUB_REPOSITORY}/pulls/${PR}" --jq .head.sha)"
# Check that the pull-request head SHA matches the head SHA of the workflow run
if [ "${WORKFLOW_RUN_HEAD_SHA}" != "${PR_HEAD_SHA}" ]; then
echo "PR head SHA ${PR_HEAD_SHA} does not match workflow_run event SHA ${WORKFLOW_RUN_HEAD_SHA}. Stopping." 1>&2
exit 1
fi
env:
GITHUB_TOKEN: ${{ github.token }}
WORKFLOW_RUN_HEAD_SHA: ${{ github.event.workflow_run.head_commit.id }}
- name: Create or update comment
run: |
COMMENT_PREFIX="QHelp previews"
COMMENT_AUTHOR="github-actions[bot]"
PR_NUMBER="$(grep -o '^[0-9]\+$' pr_number.txt)"
# If there is no existing comment, comment_id.txt will contain just a
# newline (due to jq & gh behaviour). This will cause grep to fail, so
# we catch that.
RAW_COMMENT_ID=$(grep -o '^[0-9]\+$' comment_id.txt || true)
if [ $RAW_COMMENT_ID ]
then
# Fetch existing comment, and validate:
# - comment belongs to the PR with number $PR_NUMBER
# - comment starts with the expected prefix ("QHelp previews")
# - comment author is github-actions[bot]
FILTER='select(.issue_url | endswith($repo+"/issues/"+$pr))
| select(.body | startswith($prefix))
| select(.user.login == $author)
| .id'
COMMENT_ID=$(gh api "repos/${GITHUB_REPOSITORY}/issues/comments/${RAW_COMMENT_ID}" | jq --arg repo "${GITHUB_REPOSITORY}" --arg pr "${PR_NUMBER}" --arg prefix "${COMMENT_PREFIX}" --arg author "${COMMENT_AUTHOR}" "${FILTER}")
if [ $COMMENT_ID ]
then
# Update existing comment
jq --rawfile body comment_body.txt '{"body":$body}' -n | gh api "repos/${GITHUB_REPOSITORY}/issues/comments/${COMMENT_ID}" -X PATCH --input -
else
echo "Comment ${RAW_COMMENT_ID} did not pass validations: not editing." >&2
exit 1
fi
else
# Create new comment
jq --rawfile body comment_body.txt '{"body":$body}' -n | gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" -X POST --input -
fi
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -1,102 +0,0 @@
# This workflow checks for any changes in .qhelp files in pull requests.
# For any changed files, it renders them to markdown in a file called `comment_body.txt`.
# It then checks if there's an existing comment on the pull request generated by
# this workflow, and writes the comment ID to `comment_id.txt`.
# It also writes the PR number to `pr_number.txt`.
# These three files are uploaded as an artifact.
# When this workflow completes, the workflow "Post PR comment" runs.
# It downloads the artifact and adds a comment to the PR with the rendered
# QHelp.
# The task is split like this because creating PR comments requires extra
# permissions that we don't want to expose to PRs from external forks.
# For more info see:
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run
# https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
name: Render QHelp changes
permissions:
contents: read
pull-requests: read
on:
pull_request:
branches:
- main
- "rc/*"
paths:
- "**/*.qhelp"
jobs:
qhelp:
runs-on: ubuntu-latest
steps:
- run: echo "${PR_NUMBER}" > pr_number.txt
env:
PR_NUMBER: ${{ github.event.number }}
- uses: actions/upload-artifact@v4
with:
name: comment-pr-number
path: pr_number.txt
if-no-files-found: error
retention-days: 1
- uses: actions/checkout@v4
with:
fetch-depth: 2
persist-credentials: false
- uses: ./.github/actions/fetch-codeql
- name: Determine changed files
id: changes
run: |
(git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.qhelp$' | grep -z -v '.inc.qhelp';
git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.inc.qhelp$' | xargs --null -rn1 basename -z | xargs --null -rn1 git grep -z -l) |
grep -z '.qhelp$' | grep -z -v '^-' | sort -z -u > "${RUNNER_TEMP}/paths.txt"
- name: QHelp preview
run: |
EXIT_CODE=0
echo "QHelp previews:" > comment_body.txt
while read -r -d $'\0' path; do
if [ ! -f "${path}" ]; then
exit 1
fi
echo "<details> <summary>${path}</summary>"
echo
codeql generate query-help --format=markdown -- "./${path}" 2> errors.txt || EXIT_CODE="$?"
if [ -s errors.txt ]; then
echo "# errors/warnings:"
echo '```'
cat errors.txt
cat errors.txt 1>&2
echo '```'
fi
echo "</details>"
done < "${RUNNER_TEMP}/paths.txt" >> comment_body.txt
exit "${EXIT_CODE}"
- if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: comment-body
path: comment_body.txt
if-no-files-found: error
retention-days: 1
- name: Save ID of existing QHelp comment (if it exists)
run: |
# Find the latest comment starting with "QHelp previews"
COMMENT_PREFIX="QHelp previews"
gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" --paginate | jq --arg prefix "${COMMENT_PREFIX}" '[.[] | select(.body|startswith($prefix)) | .id] | max' > comment_id.txt
env:
GITHUB_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.number }}
- uses: actions/upload-artifact@v4
with:
name: comment-id
path: comment_id.txt
if-no-files-found: error
retention-days: 1

View File

@@ -1,91 +0,0 @@
name: Run QL for QL
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
permissions:
contents: read
security-events: write
jobs:
analyze:
if: github.repository_owner == 'github'
runs-on: ubuntu-latest-xl
steps:
### Build the queries ###
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@main
with:
languages: javascript # does not matter
- uses: ./.github/actions/os-version
id: os_version
### Build the extractor ###
- name: Cache entire extractor
id: cache-extractor
uses: actions/cache@v3
with:
path: |
ql/extractor-pack/
ql/target/release/buramu
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ql/**/*.rs') }}
- name: Cache cargo
if: steps.cache-extractor.outputs.cache-hit != 'true'
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
ql/target
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-rust-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
- name: Release build
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cd ql; ./scripts/create-extractor-pack.sh
env:
GH_TOKEN: ${{ github.token }}
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: run-ql-for-ql
- name: Make database and analyze
run: |
./ql/target/release/buramu | tee deprecated.blame # Add a blame file for the extractor to parse.
${CODEQL} database create -l=ql ${DB} --search-path "${{ github.workspace }}"
${CODEQL} database analyze -j0 --format=sarif-latest --output=ql-for-ql.sarif ${DB} ql/ql/src/codeql-suites/ql-code-scanning.qls --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
DB: ${{ runner.temp }}/DB
LGTM_INDEX_FILTERS: |
exclude:ql/ql/test
exclude:*/ql/lib/upgrades/
exclude:java/ql/integration-tests
- name: Upload sarif to code-scanning
uses: github/codeql-action/upload-sarif@main
with:
sarif_file: ql-for-ql.sarif
category: ql-for-ql
- name: Sarif as artifact
uses: actions/upload-artifact@v4
with:
name: ql-for-ql.sarif
path: ql-for-ql.sarif
- name: Split out the sarif file into langs
run: |
mkdir split-sarif
node ./ql/scripts/split-sarif.js ql-for-ql.sarif split-sarif
- name: Upload langs as artifacts
uses: actions/upload-artifact@v4
with:
name: ql-for-ql-langs
path: split-sarif
retention-days: 1

View File

@@ -1,89 +0,0 @@
name: Collect database stats for QL for QL
on:
push:
branches: [main]
paths:
- ql/ql/src/ql.dbscheme
pull_request:
branches: [main]
paths:
- ql/ql/src/ql.dbscheme
workflow_dispatch:
permissions:
contents: read
security-events: read
jobs:
measure:
env:
CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI
strategy:
matrix:
repo:
- github/codeql
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@main
with:
languages: javascript # does not matter
- uses: ./.github/actions/os-version
id: os_version
- uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
ql/target
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
- name: Build Extractor
run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./scripts/create-extractor-pack.sh
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Checkout ${{ matrix.repo }}
uses: actions/checkout@v4
with:
repository: ${{ matrix.repo }}
path: ${{ github.workspace }}/repo
- name: Create database
run: |
"${CODEQL}" database create \
--search-path "${{ github.workspace }}"
--threads 4 \
--language ql --source-root "${{ github.workspace }}/repo" \
"${{ runner.temp }}/database"
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Measure database
run: |
mkdir -p "stats/${{ matrix.repo }}"
"${CODEQL}" dataset measure --threads 4 --output "stats/${{ matrix.repo }}/stats.xml" "${{ runner.temp }}/database/db-ql"
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- uses: actions/upload-artifact@v4
with:
name: measurements
path: stats
retention-days: 1
merge:
runs-on: ubuntu-latest
needs: measure
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: measurements
path: stats
- run: |
python -m pip install --user lxml
find stats -name 'stats.xml' -print0 | sort -z | xargs -0 python ruby/scripts/merge_stats.py --output ql/ql/src/ql.dbscheme.stats --normalise ql_tokeninfo
- uses: actions/upload-artifact@v4
with:
name: ql.dbscheme.stats
path: ql/ql/src/ql.dbscheme.stats

View File

@@ -1,111 +0,0 @@
name: Run QL for QL Tests
on:
push:
branches: [main]
paths:
- "ql/**"
- codeql-workspace.yml
- .github/workflows/ql-for-ql-tests.yml
pull_request:
branches: [main]
paths:
- "ql/**"
- codeql-workspace.yml
- .github/workflows/ql-for-ql-tests.yml
env:
CARGO_TERM_COLOR: always
permissions:
contents: read
jobs:
qltest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@main
with:
languages: javascript # does not matter
- uses: ./.github/actions/os-version
id: os_version
- uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
ql/target
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-qltest-cargo-${{ hashFiles('ql/rust-toolchain.toml', 'ql/**/Cargo.lock') }}
- name: Check formatting
run: cd ql; cargo fmt -- --check
- name: Build extractor
run: |
cd ql;
codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }});
env "PATH=$PATH:$codeqlpath" ./scripts/create-extractor-pack.sh
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: ql-for-ql-tests
- name: Run QL tests
run: |
"${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}" --consistency-queries ql/ql/consistency-queries --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" ql/ql/test
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
other-os:
strategy:
matrix:
os: [macos-latest, windows-latest]
needs: [qltest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install GNU tar
if: runner.os == 'macOS'
run: |
brew install gnu-tar
echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@main
with:
languages: javascript # does not matter
- uses: ./.github/actions/os-version
id: os_version
- uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
ql/target
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-qltest-cargo-${{ hashFiles('ql/rust-toolchain.toml', 'ql/**/Cargo.lock') }}
- name: Build extractor
if: runner.os != 'Windows'
run: |
cd ql;
codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }});
env "PATH=$PATH:$codeqlpath" ./scripts/create-extractor-pack.sh
- name: Build extractor (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
cd ql;
$Env:PATH += ";$(dirname ${{ steps.find-codeql.outputs.codeql-path }})"
pwsh ./scripts/create-extractor-pack.ps1
- name: Run a single QL tests - Unix
if: runner.os != 'Windows'
run: |
"${CODEQL}" test run --check-databases --search-path "${{ github.workspace }}" ql/ql/test/queries/style/DeadCode/DeadCode.qlref
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Run a single QL tests - Windows
if: runner.os == 'Windows'
shell: pwsh
run: |
$Env:PATH += ";$(dirname ${{ steps.find-codeql.outputs.codeql-path }})"
codeql test run --check-databases --search-path "${{ github.workspace }}" ql/ql/test/queries/style/DeadCode/DeadCode.qlref

View File

@@ -5,17 +5,11 @@ on:
branches:
- main
- 'rc/**'
tags:
- 'codeql-cli/*'
pull_request:
paths:
- '.github/workflows/query-list.yml'
- '.github/actions/fetch-codeql/action.yml'
- 'misc/scripts/generate-code-scanning-query-list.py'
permissions:
contents: read
jobs:
build:
@@ -23,21 +17,33 @@ jobs:
steps:
- name: Clone self (github/codeql)
uses: actions/checkout@v4
uses: actions/checkout@v2
with:
path: codeql
- name: Clone github/codeql-go
uses: actions/checkout@v2
with:
repository: 'github/codeql-go'
path: codeql-go
- name: Set up Python 3.8
uses: actions/setup-python@v4
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Download CodeQL CLI
# Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo
uses: ./codeql/.github/actions/fetch-codeql
uses: dsaltares/fetch-gh-release-asset@aa37ae5c44d3c9820bc12fe675e8670ecd93bd1c
with:
repo: "github/codeql-cli-binaries"
version: "latest"
file: "codeql-linux64.zip"
token: ${{ secrets.GITHUB_TOKEN }}
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Build code scanning query list
run: |
python codeql/misc/scripts/generate-code-scanning-query-list.py > code-scanning-query-list.csv
PATH="$PATH:codeql-cli/codeql" python codeql/misc/scripts/generate-code-scanning-query-list.py > code-scanning-query-list.csv
- name: Upload code scanning query list
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
with:
name: code-scanning-query-list
path: code-scanning-query-list.csv

View File

@@ -1,236 +0,0 @@
name: "Ruby: Build"
on:
push:
paths:
- "ruby/**"
- .github/workflows/ruby-build.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
- "shared/tree-sitter-extractor/**"
branches:
- main
- "rc/*"
pull_request:
paths:
- "ruby/**"
- .github/workflows/ruby-build.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
- "shared/tree-sitter-extractor/**"
branches:
- main
- "rc/*"
workflow_dispatch:
inputs:
tag:
description: "Version tag to create"
required: false
env:
CARGO_TERM_COLOR: always
defaults:
run:
working-directory: ruby
permissions:
contents: read
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install GNU tar
if: runner.os == 'macOS'
run: |
brew install gnu-tar
echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
- name: Prepare Windows
if: runner.os == 'Windows'
shell: powershell
run: |
git config --global core.longpaths true
- uses: ./.github/actions/os-version
id: os_version
- name: Cache entire extractor
uses: actions/cache@v3
id: cache-extractor
with:
path: |
target/release/codeql-extractor-ruby
target/release/codeql-extractor-ruby.exe
ruby/extractor/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ruby/extractor/**/*.rs') }}
- uses: actions/cache@v3
if: steps.cache-extractor.outputs.cache-hit != 'true'
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-rust-cargo-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/**/Cargo.lock') }}
- name: Check formatting
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cd extractor && cargo fmt -- --check
- name: Build
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cd extractor && cargo build --verbose
- name: Run tests
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cd extractor && cargo test --verbose
- name: Release build
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cd extractor && cargo build --release
- name: Generate dbscheme
if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}}
run: ../target/release/codeql-extractor-ruby generate --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
- uses: actions/upload-artifact@v4
if: ${{ matrix.os == 'ubuntu-latest' }}
with:
name: ruby.dbscheme
path: ruby/ql/lib/ruby.dbscheme
- uses: actions/upload-artifact@v4
if: ${{ matrix.os == 'ubuntu-latest' }}
with:
name: TreeSitter.qll
path: ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
- uses: actions/upload-artifact@v4
with:
name: extractor-${{ matrix.os }}
path: |
target/release/codeql-extractor-ruby
target/release/codeql-extractor-ruby.exe
retention-days: 1
compile-queries:
if: github.repository_owner == 'github'
runs-on: ubuntu-latest-xl
steps:
- uses: actions/checkout@v4
- name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: ruby-build
- name: Build Query Pack
run: |
PACKS=${{ runner.temp }}/query-packs
rm -rf $PACKS
codeql pack create ../misc/suite-helpers --output "$PACKS"
codeql pack create ../shared/regex --output "$PACKS"
codeql pack create ../shared/ssa --output "$PACKS"
codeql pack create ../shared/tutorial --output "$PACKS"
codeql pack create ql/lib --output "$PACKS"
codeql pack create -j0 ql/src --output "$PACKS" --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
PACK_FOLDER=$(readlink -f "$PACKS"/codeql/ruby-queries/*)
codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
(cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;)
- uses: actions/upload-artifact@v4
with:
name: codeql-ruby-queries
path: |
${{ runner.temp }}/query-packs/*
retention-days: 1
include-hidden-files: true
package:
runs-on: ubuntu-latest
needs: [build, compile-queries]
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: ruby.dbscheme
path: ruby/ruby
- uses: actions/download-artifact@v4
with:
name: extractor-ubuntu-latest
path: ruby/linux64
- uses: actions/download-artifact@v4
with:
name: extractor-windows-latest
path: ruby/win64
- uses: actions/download-artifact@v4
with:
name: extractor-macos-latest
path: ruby/osx64
- run: |
mkdir -p ruby
cp -r codeql-extractor.yml tools ql/lib/ruby.dbscheme.stats ruby/
mkdir -p ruby/tools/{linux64,osx64,win64}
cp linux64/codeql-extractor-ruby ruby/tools/linux64/extractor
cp osx64/codeql-extractor-ruby ruby/tools/osx64/extractor
cp win64/codeql-extractor-ruby.exe ruby/tools/win64/extractor.exe
chmod +x ruby/tools/{linux64,osx64}/extractor
zip -rq codeql-ruby.zip ruby
- uses: actions/upload-artifact@v4
with:
name: codeql-ruby-pack
path: ruby/codeql-ruby.zip
retention-days: 1
include-hidden-files: true
- uses: actions/download-artifact@v4
with:
name: codeql-ruby-queries
path: ruby/qlpacks
- run: |
echo '{
"provide": [
"ruby/codeql-extractor.yml",
"qlpacks/*/*/*/qlpack.yml"
]
}' > .codeqlmanifest.json
zip -rq codeql-ruby-bundle.zip .codeqlmanifest.json ruby qlpacks
- uses: actions/upload-artifact@v4
with:
name: codeql-ruby-bundle
path: ruby/codeql-ruby-bundle.zip
retention-days: 1
include-hidden-files: true
test:
defaults:
run:
working-directory: ${{ github.workspace }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
needs: [package]
steps:
- uses: actions/checkout@v4
- name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql
- name: Download Ruby bundle
uses: actions/download-artifact@v4
with:
name: codeql-ruby-bundle
path: ${{ runner.temp }}
- name: Unzip Ruby bundle
shell: bash
run: unzip -q -d "${{ runner.temp }}/ruby-bundle" "${{ runner.temp }}/codeql-ruby-bundle.zip"
- name: Run QL test
shell: bash
run: |
codeql test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" ruby/ql/test/library-tests/ast/constants/
- name: Create database
shell: bash
run: |
codeql database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root ruby/ql/test/library-tests/ast/constants/ ../database
- name: Analyze database
shell: bash
run: |
codeql database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls

View File

@@ -1,75 +0,0 @@
name: "Ruby: Collect database stats"
on:
push:
branches:
- main
- "rc/*"
paths:
- ruby/ql/lib/ruby.dbscheme
- .github/workflows/ruby-dataset-measure.yml
pull_request:
branches:
- main
- "rc/*"
paths:
- ruby/ql/lib/ruby.dbscheme
- .github/workflows/ruby-dataset-measure.yml
workflow_dispatch:
permissions:
contents: read
jobs:
measure:
env:
CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI
strategy:
fail-fast: false
matrix:
repo: [rails/rails, discourse/discourse, spree/spree, ruby/ruby]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack
- name: Checkout ${{ matrix.repo }}
uses: actions/checkout@v4
with:
repository: ${{ matrix.repo }}
path: ${{ github.workspace }}/repo
- name: Create database
run: |
codeql database create \
--search-path "${{ github.workspace }}" \
--threads 4 \
--language ruby --source-root "${{ github.workspace }}/repo" \
"${{ runner.temp }}/database"
- name: Measure database
run: |
mkdir -p "stats/${{ matrix.repo }}"
codeql dataset measure --threads 4 --output "stats/${{ matrix.repo }}/stats.xml" "${{ runner.temp }}/database/db-ruby"
- uses: actions/upload-artifact@v4
with:
name: measurements-${{ hashFiles('stats/**') }}
path: stats
retention-days: 1
merge:
runs-on: ubuntu-latest
needs: measure
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: stats
- run: |
python -m pip install --user lxml
find stats -name 'stats.xml' | sort | xargs python ruby/scripts/merge_stats.py --output ruby/ql/lib/ruby.dbscheme.stats --normalise ruby_tokeninfo
- uses: actions/upload-artifact@v4
with:
name: ruby.dbscheme.stats
path: ruby/ql/lib/ruby.dbscheme.stats

View File

@@ -1,73 +0,0 @@
name: "Ruby: Run QL Tests"
on:
push:
paths:
- "ruby/**"
- "shared/**"
- .github/workflows/ruby-build.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
branches:
- main
- "rc/*"
pull_request:
paths:
- "ruby/**"
- "shared/**"
- .github/workflows/ruby-qltest.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
branches:
- main
- "rc/*"
env:
CARGO_TERM_COLOR: always
defaults:
run:
working-directory: ruby
permissions:
contents: read
jobs:
qlupgrade:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql
- name: Check DB upgrade scripts
run: |
echo >empty.trap
codeql dataset import -S ql/lib/upgrades/initial/ruby.dbscheme testdb empty.trap
codeql dataset upgrade testdb --additional-packs ql/lib
diff -q testdb/ruby.dbscheme ql/lib/ruby.dbscheme
- name: Check DB downgrade scripts
run: |
echo >empty.trap
rm -rf testdb; codeql dataset import -S ql/lib/ruby.dbscheme testdb empty.trap
codeql resolve upgrades --format=lines --allow-downgrades --additional-packs downgrades \
--dbscheme=ql/lib/ruby.dbscheme --target-dbscheme=downgrades/initial/ruby.dbscheme |
xargs codeql execute upgrades testdb
diff -q testdb/ruby.dbscheme downgrades/initial/ruby.dbscheme
qltest:
if: github.repository_owner == 'github'
runs-on: ubuntu-latest-xl
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: ruby-qltest
- name: Run QL tests
run: |
codeql test run --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -1,64 +0,0 @@
name: "Code scanning - Rust"
on:
push:
branches:
- main
- 'rc/*'
pull_request:
branches:
- main
- 'rc/*'
paths:
- '**/*.rs'
- '**/Cargo.toml'
- '.github/codeql/codeql-config.yml'
- '.github/workflows/rust-analysis.yml'
schedule:
- cron: '0 9 * * 1'
env:
CODEQL_ENABLE_EXPERIMENTAL_FEATURES: "true"
jobs:
analyze:
strategy:
matrix:
language: [ 'rust' ]
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
pull-requests: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Query latest nightly CodeQL bundle
shell: bash
id: codeql
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
REPO=dsp-testing/codeql-cli-nightlies
TAG=$(
gh release list -R $REPO -L1 --exclude-drafts --json tagName -q ".[] | .tagName"
)
echo "nightly_bundle=https://github.com/$REPO/releases/download/$TAG/codeql-bundle-linux64.tar.zst" \
| tee -a "$GITHUB_OUTPUT"
- name: Initialize CodeQL
uses: github/codeql-action/init@main
with:
tools: ${{ steps.codeql.outputs.nightly_bundle }}
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
- name: Autobuild
uses: github/codeql-action/autobuild@main
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@main

View File

@@ -1,80 +0,0 @@
name: "Rust"
on:
pull_request:
paths:
- "rust/**"
- "misc/bazel/**"
- "misc/codegen/**"
- "shared/**"
- "MODULE.bazel"
- .github/workflows/rust.yml
- .github/actions/**
- codeql-workspace.yml
- "!**/*.md"
- "!**/*.qhelp"
branches:
- rust-experiment
- main
- rc/*
- codeql-cli-*
permissions:
contents: read
jobs:
rust-ast-generator:
runs-on: ubuntu-latest
defaults:
run:
working-directory: rust/ast-generator
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Inject sources
shell: bash
run: |
bazel run //rust/ast-generator:inject-sources
- name: Format
shell: bash
run: |
cargo fmt --check
- name: Compilation
shell: bash
run: cargo check
- name: Clippy
shell: bash
run: |
cargo clippy --no-deps -- -D warnings
rust-code:
runs-on: ubuntu-latest
defaults:
run:
working-directory: rust/extractor
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Format
shell: bash
run: |
cargo fmt --check
- name: Compilation
shell: bash
run: cargo check
- name: Clippy
shell: bash
run: |
cargo clippy --no-deps -- -D warnings
rust-codegen:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install CodeQL
uses: ./.github/actions/fetch-codeql
- name: Code generation
shell: bash
run: |
bazel run //rust/codegen
git add .
git diff --exit-code HEAD

View File

@@ -1,111 +0,0 @@
name: "Swift"
on:
pull_request:
paths:
- "swift/**"
- "misc/bazel/**"
- "misc/codegen/**"
- "shared/**"
- "*.bazel*"
- .github/workflows/swift.yml
- .github/actions/**
- codeql-workspace.yml
- .pre-commit-config.yaml
- "!**/*.md"
- "!**/*.qhelp"
branches:
- main
- rc/*
- codeql-cli-*
push:
paths:
- "swift/**"
- "misc/bazel/**"
- "misc/codegen/**"
- "shared/**"
- "*.bazel*"
- .github/workflows/swift.yml
- .github/actions/**
- codeql-workspace.yml
- .pre-commit-config.yaml
- "!**/*.md"
- "!**/*.qhelp"
branches:
- main
- rc/*
- codeql-cli-*
permissions:
contents: read
jobs:
# not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks
# without waiting for the macOS build
build-and-test-macos:
if: github.repository_owner == 'github'
runs-on: macos-13-xlarge
steps:
- uses: actions/checkout@v4
- uses: ./swift/actions/build-and-test
build-and-test-linux:
if: github.repository_owner == 'github'
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: ./swift/actions/build-and-test
qltests-macos:
if: ${{ github.repository_owner == 'github' && github.event_name == 'pull_request' }}
needs: build-and-test-macos
runs-on: macos-13-xlarge
steps:
- uses: actions/checkout@v4
- uses: ./swift/actions/run-ql-tests
clang-format:
if : ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that python code is properly formatted
with:
extra_args: clang-format --all-files
codegen:
if : ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: bazelbuild/setup-bazelisk@v2
- uses: actions/setup-python@v4
with:
python-version-file: 'swift/.python-version'
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that python code is properly formatted
with:
extra_args: autopep8 --all-files
- uses: ./.github/actions/fetch-codeql
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that QL generated code was checked in
with:
extra_args: swift-codegen --all-files
- name: Generate C++ files
run: |
bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/generated-cpp-files
- uses: actions/upload-artifact@v4
with:
name: swift-generated-cpp-files
path: generated-cpp-files/**
database-upgrade-scripts:
if : ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql
- uses: ./swift/actions/database-upgrade-scripts
check-no-override:
if : github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- shell: bash
run: bazel test //swift/... --test_tag_filters=override --test_output=errors

View File

@@ -1,25 +0,0 @@
name: Check synchronized files
on:
push:
branches:
- main
- 'rc/*'
pull_request:
branches:
- main
- 'rc/*'
permissions:
contents: read
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check synchronized files
run: python config/sync-files.py
- name: Check dbscheme fragments
run: python config/sync-dbscheme-fragments.py

View File

@@ -1,49 +0,0 @@
name: Test tree-sitter-extractor
on:
push:
paths:
- "shared/tree-sitter-extractor/**"
- .github/workflows/tree-sitter-extractor-test.yml
branches:
- main
- "rc/*"
pull_request:
paths:
- "shared/tree-sitter-extractor/**"
- .github/workflows/tree-sitter-extractor-test.yml
branches:
- main
- "rc/*"
env:
CARGO_TERM_COLOR: always
defaults:
run:
working-directory: shared/tree-sitter-extractor
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check formatting
run: cargo fmt -- --check
- name: Run tests
run: cargo test --verbose
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check formatting
run: cargo fmt --check
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run clippy
run: cargo clippy -- --no-deps -D warnings -A clippy::new_without_default -A clippy::too_many_arguments

View File

@@ -1,34 +0,0 @@
name: Validate change notes
on:
push:
paths:
- "*/ql/*/change-notes/**/*"
- ".github/workflows/validate-change-notes.yml"
- ".github/actions/fetch-codeql/action.yml"
branches:
- main
- "rc/*"
pull_request:
paths:
- "*/ql/*/change-notes/**/*"
- ".github/workflows/validate-change-notes.yml"
- ".github/actions/fetch-codeql/action.yml"
permissions:
contents: read
jobs:
check-change-note:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup CodeQL
uses: ./.github/actions/fetch-codeql
- name: Fail if there are any errors with existing change notes
run: |
codeql pack release --groups cpp,csharp,java,javascript,python,ruby,-examples,-test,-experimental

View File

@@ -1,23 +0,0 @@
name: "Test zipmerge code"
on:
pull_request:
paths:
- "misc/bazel/internal/zipmerge/**"
- "MODULE.bazel"
- ".bazelrc*"
branches:
- main
- "rc/*"
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
bazel test //misc/bazel/internal/zipmerge:test --test_output=all

56
.gitignore vendored
View File

@@ -5,11 +5,11 @@
# query compilation caches
.cache
data
# qltest projects and artifacts
*.actual
*/ql/test*/**/*.testproj
*/ql/test/**/go.sum
*/ql/test/**/*.testproj
*/ql/test/**/*.actual
# Visual studio temporaries, except a file used by QL4VS
.vs/*
@@ -18,56 +18,14 @@
# Byte-compiled python files
*.pyc
# python virtual environment folder
# python virtual environment folder
.venv/
# binary files created by pytest-cov
.coverage
# It's useful (though not required) to be able to unpack codeql in the ql checkout itself
/codeql/
# Avoid committing cached package components
.codeql
# Exclude output directories for compiled packs.
.codeql/
# Compiled class file
*.class
csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
# links created by bazel
/bazel-*
# local bazel options
/local.bazelrc
# generated cmake directory
/.bazel-cmake
# CLion project files
/.clwb
# Go build artifacts
go/build/*
# Go binaries
go/tools/bin
go/tools/linux64
go/tools/osx64
go/tools/win64
go/tools/tokenizer.jar
go/main
# node_modules folders except in the JS test suite
node_modules/
!/javascript/ql/test/**/node_modules/
# Temporary folders for working with generated models
.model-temp
# bazel-built in-tree extractor packs
/*/extractor-pack
# Jetbrains IDE files
.idea
# cargo build directory
/target

View File

@@ -1,7 +0,0 @@
[lfs]
# codeql is publicly forked by many users, and we don't want any LFS file polluting their working
# copies. We therefore exclude everything by default.
# For files required by bazel builds, use rules in `misc/bazel/lfs.bzl` to download them on demand.
# we go for `fetchinclude` to something not exsiting rather than `fetchexclude = *` because the
# former is easier to override (with `git -c` or a local git config) to fetch something specific
fetchinclude = /nothing

View File

@@ -6,7 +6,6 @@ path_classifiers:
test:
- csharp/ql/src
- csharp/ql/test
- go/ql/test
- javascript/extractor/parser-tests
- javascript/extractor/tests
- javascript/ql/src
@@ -14,9 +13,6 @@ path_classifiers:
- python/ql/src
- python/ql/test
example:
- go/ql/src
queries:
- include: "*"

View File

@@ -1,85 +0,0 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
- id: end-of-file-fixer
exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v17.0.6
hooks:
- id: clang-format
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v2.0.4
hooks:
- id: autopep8
files: ^misc/codegen/.*\.py
- repo: local
hooks:
- id: buildifier
name: Format bazel files
files: \.(bazel|bzl)
language: system
entry: bazel run //misc/bazel/buildifier
pass_filenames: false
# DISABLED: can be enabled by copying this config and installing `pre-commit` with `--config` on the copy
# - id: go-gen
# name: Check checked in generated files in go
# files: ^go/.*
# language: system
# entry: bazel run //go:gen
# pass_filenames: false
- id: codeql-format
name: Fix QL file formatting
files: \.qll?$
language: system
entry: codeql query format --in-place
- id: sync-files
name: Fix files required to be identical
files: \.(qll?|qhelp|swift|toml)$|^config/identical-files\.json$
language: system
entry: python3 config/sync-files.py --latest
pass_filenames: false
- id: qhelp
name: Check query help generation
files: \.qhelp$
language: system
entry: python3 misc/scripts/check-qhelp.py
- id: swift-codegen
name: Run Swift checked in code generation
files: ^misc/codegen/|^swift/(schema.py$|codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)|ql/\.generated.list)
language: system
entry: bazel run //swift/codegen -- --quiet
pass_filenames: false
- id: swift-codegen-unit-tests
name: Run Swift code generation unit tests
files: ^swift/codegen/.*\.py$
language: system
entry: bazel test //misc/codegen/test
pass_filenames: false
- id: rust-codegen
name: Run Rust checked in code generation
files: ^misc/codegen/|^rust/(prefix\.dbscheme|schema/|codegen/|.*/generated/|ql/lib/(rust\.dbscheme$|codeql/rust/elements)|\.generated.list)
language: system
entry: bazel run //rust/codegen -- --quiet
pass_filenames: false
- id: rust-lint
name: Run fmt and clippy on Rust code
files: ^rust/extractor/(.*rs|Cargo.toml)$
language: system
entry: python3 rust/lint.py
pass_filenames: false

View File

@@ -1,6 +1,3 @@
{
"omnisharp.autoStart": false,
"cmake.sourceDirectory": "${workspaceFolder}/swift",
"cmake.buildDirectory": "${workspaceFolder}/bazel-cmake-build",
"editor.suggest.matchOnWordStartOnly": false
"omnisharp.autoStart": false
}

106
.vscode/tasks.json vendored
View File

@@ -22,110 +22,6 @@
"command": "${config:python.pythonPath}",
},
"problemMatcher": []
},
{
"label": "Accept .expected changes from CI",
"type": "process",
// Non-Windows OS will usually have Python 3 already installed at /usr/bin/python3.
"command": "python3",
"args": [
"misc/scripts/accept-expected-changes-from-ci.py"
],
"group": "build",
"windows": {
// On Windows, use whatever Python interpreter is configured for this workspace. The default is
// just `python`, so if Python is already on the path, this will find it.
"command": "${config:python.pythonPath}",
},
"problemMatcher": []
},
{
"label": "Create query change note",
"type": "process",
"command": "python3",
"args": [
"misc/scripts/create-change-note.py",
"${input:language}",
"src",
"${input:name}",
"${input:categoryQuery}"
],
"presentation": {
"reveal": "never",
"close": true
},
"problemMatcher": []
},
{
"label": "Create library change note",
"type": "process",
"command": "python3",
"args": [
"misc/scripts/create-change-note.py",
"${input:language}",
"lib",
"${input:name}",
"${input:categoryLibrary}"
],
"presentation": {
"reveal": "never",
"close": true
},
"problemMatcher": []
}
],
"inputs": [
{
"type": "pickString",
"id": "language",
"description": "Language",
"options":
[
"actions",
"go",
"java",
"javascript",
"cpp",
"csharp",
"python",
"ruby",
"rust",
"swift",
]
},
{
"type": "promptString",
"id": "name",
"description": "Short name (kebab-case)"
},
{
"type": "pickString",
"id": "categoryQuery",
"description": "Category (query change)",
"options":
[
"breaking",
"deprecated",
"newQuery",
"queryMetadata",
"majorAnalysis",
"minorAnalysis",
"fix",
]
},
{
"type": "pickString",
"id": "categoryLibrary",
"description": "Category (library change)",
"options":
[
"breaking",
"deprecated",
"feature",
"majorAnalysis",
"minorAnalysis",
"fix",
]
}
]
}
}

View File

@@ -1,5 +0,0 @@
exports_files([
"LICENSE",
"Cargo.lock",
"Cargo.toml",
])

View File

@@ -1,48 +1,19 @@
/actions/ @github/codeql-dynamic
/cpp/ @github/codeql-c-analysis
/csharp/ @github/codeql-csharp
/csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor
/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests @github/codeql-c-extractor
/go/ @github/codeql-go
/java/ @github/codeql-java
/javascript/ @github/codeql-javascript
/python/ @github/codeql-python
/ruby/ @github/codeql-ruby
/swift/ @github/codeql-swift
/misc/codegen/ @github/codeql-swift
/java/kotlin-extractor/ @github/codeql-kotlin
/java/ql/test-kotlin1/ @github/codeql-kotlin
/java/ql/test-kotlin2/ @github/codeql-kotlin
# CodeQL tools and associated docs
/docs/codeql/codeql-cli/ @github/codeql-cli-reviewers
/docs/codeql/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
/docs/codeql/ql-language-reference/ @github/codeql-frontend-reviewers
/docs/query-*-style-guide.md @github/codeql-analysis-reviewers
# Make @xcorail (GitHub Security Lab) a code owner for experimental queries so he gets pinged when we promote a query out of experimental
/cpp/**/experimental/**/* @github/codeql-c-analysis @xcorail
/csharp/**/experimental/**/* @github/codeql-csharp @xcorail
/java/**/experimental/**/* @github/codeql-java @xcorail
/javascript/**/experimental/**/* @github/codeql-javascript @xcorail
/python/**/experimental/**/* @github/codeql-python @xcorail
# QL for QL reviewers
/ql/ @github/codeql-ql-for-ql-reviewers
# Bazel (excluding BUILD.bazel files)
MODULE.bazel @github/codeql-ci-reviewers
.bazelversion @github/codeql-ci-reviewers
.bazelrc @github/codeql-ci-reviewers
**/*.bzl @github/codeql-ci-reviewers
# Documentation etc
/*.md @github/code-scanning-product
/LICENSE @github/code-scanning-product
# Workflows
/.github/workflows/ @github/codeql-ci-reviewers
/.github/workflows/go-* @github/codeql-go
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
/.github/workflows/ruby-* @github/codeql-ruby
/.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
# Notify members of codeql-go about PRs to the shared data-flow library files
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go

View File

@@ -2,13 +2,8 @@
We welcome contributions to our CodeQL libraries and queries. Got an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [project's open source license](LICENSE).
There is lots of useful documentation to help you write queries, ranging from information about query file structure to tutorials for specific target languages. For more information on the documentation available, see [CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/codeql-queries) on [codeql.github.com](https://codeql.github.com).
There is lots of useful documentation to help you write queries, ranging from information about query file structure to tutorials for specific target languages. For more information on the documentation available, see [CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com).
Note that the CodeQL for Visual Studio Code documentation has been migrated to https://docs.github.com/en/code-security/codeql-for-vs-code/, but you can still contribute to it via a different repository. For more information, see [Contributing to GitHub Docs documentation](https://docs.github.com/en/contributing)."
## Change notes
Any nontrivial user-visible change to a query pack or library pack should have a change note. For details on how to add a change note for your change, see [this guide](docs/change-notes.md).
## Submitting a new experimental query
@@ -16,20 +11,16 @@ If you have an idea for a query that you would like to share with other CodeQL u
1. **Directory structure**
There are eight language-specific query directories in this repository:
There are five language-specific query directories in this repository:
* C/C++: `cpp/ql/src`
* C#: `csharp/ql/src`
* Go: `go/ql/src`
* Java/Kotlin: `java/ql/src`
* Java: `java/ql/src`
* JavaScript: `javascript/ql/src`
* Python: `python/ql/src`
* Ruby: `ruby/ql/src`
* Swift: `swift/ql/src`
Each language-specific directory contains further subdirectories that group queries based on their `@tags` or purpose.
- Experimental queries and libraries are stored in the `experimental` subdirectory within each language-specific directory in the [CodeQL repository](https://github.com/github/codeql). For example, experimental Java queries and libraries are stored in `java/ql/src/experimental` and any corresponding tests in `java/ql/test/experimental`.
- Experimental queries need to include `experimental` in their `@tags`
- The structure of an `experimental` subdirectory mirrors the structure of its parent directory.
- Select or create an appropriate directory in `experimental` based on the existing directory structure of `experimental` or its parent directory.
@@ -41,17 +32,13 @@ If you have an idea for a query that you would like to share with other CodeQL u
For details, see the [guide on query metadata](docs/query-metadata-style-guide.md).
Make sure the `select` statement is compatible with the query `@kind`. See [About CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/about-codeql-queries/#select-clause) on codeql.github.com.
Make sure the `select` statement is compatible with the query `@kind`. See [About CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/introduction-to-queries.html#select-clause) on help.semmle.com.
3. **Formatting**
- The queries and libraries must be autoformatted, for example using the "Format Document" command in [CodeQL for Visual Studio Code](https://docs.github.com/en/code-security/codeql-for-vs-code/).
- The queries and libraries must be autoformatted, for example using the "Format Document" command in [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode/procedures/about-codeql-for-vscode.html).
If you prefer, you can either:
1. install the [pre-commit framework](https://pre-commit.com/) and install the configured hooks on this repo via `pre-commit install`, or
2. use this [pre-commit hook](misc/scripts/pre-commit) that automatically checks whether your files are correctly formatted.
See the [pre-commit hook installation guide](docs/pre-commit-hook-setup.md) for instructions on the two approaches.
If you prefer, you can use this [pre-commit hook](misc/scripts/pre-commit) that automatically checks whether your files are correctly formatted. See the [pre-commit hook installation guide](docs/pre-commit-hook-setup.md) for instructions on how to install the hook.
4. **Compilation**
@@ -72,10 +59,6 @@ After the experimental query is merged, we welcome pull requests to improve it.
## Using your personal data
If you contribute to this project, we will record your name and email address (as provided by you with your contributions) as part of the code repositories, which are public. We might also use this information to contact you in relation to your contributions, as well as in the normal course of software development. We also store records of CLA agreements signed in the past, but no longer require contributors to sign a CLA. Under GDPR legislation, we do this on the basis of our legitimate interest in creating the CodeQL product.
If you contribute to this project, we will record your name and email address (as provided by you with your contributions) as part of the code repositories, which are public. We might also use this information to contact you in relation to your contributions, as well as in the normal course of software development. We also store records of CLA agreements signed in the past, but no longer require contributors to sign a CLA. Under GDPR legislation, we do this on the basis of our legitimate interest in creating the CodeQL product.
Please do get in touch (privacy@github.com) if you have any questions about this or our data protection policies.
## Bazel
Please notice that any bazel targets and definitions in this repository are currently experimental
and for internal use only.

2835
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +0,0 @@
# This is the shared workspace file for extractor using shared/tree-sitter/extractor
[workspace]
resolver = "2"
members = [
"shared/tree-sitter-extractor",
"ruby/extractor",
"rust/extractor",
"rust/extractor/macros",
"rust/ast-generator",
"rust/autobuild",
]
[patch.crates-io]
# patch for build script bug preventing bazel build
# see https://github.com/rust-lang/rustc_apfloat/pull/17
rustc_apfloat = { git = "https://github.com/redsun82/rustc_apfloat.git", rev = "096d585100636bc2e9f09d7eefec38c5b334d47b" }

View File

@@ -1,280 +0,0 @@
module(
name = "ql",
version = "0.0",
repo_name = "codeql",
)
# this points to our internal repository when `codeql` is checked out as a submodule thereof
# when building things from `codeql` independently this is stubbed out in `.bazelrc`
bazel_dep(name = "semmle_code", version = "0.0")
local_path_override(
module_name = "semmle_code",
path = "..",
)
# see https://registry.bazel.build/ for a list of available packages
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "rules_go", version = "0.50.1")
bazel_dep(name = "rules_pkg", version = "1.0.1")
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
bazel_dep(name = "rules_python", version = "0.40.0")
bazel_dep(name = "rules_shell", version = "0.3.0")
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "absl")
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
bazel_dep(name = "fmt", version = "10.0.0")
bazel_dep(name = "rules_kotlin", version = "2.0.0-codeql.1")
bazel_dep(name = "gazelle", version = "0.40.0")
bazel_dep(name = "rules_dotnet", version = "0.17.4")
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
bazel_dep(name = "rules_rust", version = "0.52.2")
bazel_dep(name = "zstd", version = "1.5.5.bcr.1")
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
# Keep edition and version approximately in sync with internal repo.
# the versions there are canonical, the versions here are used for CI in github/codeql, as well as for the vendoring of dependencies.
RUST_EDITION = "2021"
RUST_VERSION = "1.82.0"
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(
edition = RUST_EDITION,
# We need those extra target triples so that we can build universal binaries on macos
extra_target_triples = [
"x86_64-apple-darwin",
"aarch64-apple-darwin",
],
versions = [RUST_VERSION],
)
use_repo(rust, "rust_toolchains")
register_toolchains("@rust_toolchains//:all")
rust_host_tools = use_extension("@rules_rust//rust:extensions.bzl", "rust_host_tools")
# Don't download a second toolchain as host toolchain, make sure this is the same version as above
# The host toolchain is used for vendoring dependencies.
rust_host_tools.host_tools(
edition = RUST_EDITION,
version = RUST_VERSION,
)
# deps for python extractor
# keep in sync by running `misc/bazel/3rdparty/update_cargo_deps.sh`
py_deps = use_extension("//misc/bazel/3rdparty:py_deps_extension.bzl", "p")
use_repo(
py_deps,
"vendor__anyhow-1.0.44",
"vendor__cc-1.0.70",
"vendor__clap-2.33.3",
"vendor__regex-1.5.5",
"vendor__smallvec-1.6.1",
"vendor__string-interner-0.12.2",
"vendor__thiserror-1.0.29",
"vendor__tree-sitter-0.20.4",
"vendor__tree-sitter-graph-0.7.0",
)
# deps for ruby+rust
# keep in sync by running `misc/bazel/3rdparty/update_cargo_deps.sh`
tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r")
use_repo(
tree_sitter_extractors_deps,
"vendor__anyhow-1.0.95",
"vendor__argfile-0.2.1",
"vendor__chrono-0.4.39",
"vendor__clap-4.5.26",
"vendor__dunce-1.0.5",
"vendor__either-1.13.0",
"vendor__encoding-0.2.33",
"vendor__figment-0.10.19",
"vendor__flate2-1.0.35",
"vendor__glob-0.3.2",
"vendor__globset-0.4.15",
"vendor__itertools-0.14.0",
"vendor__lazy_static-1.5.0",
"vendor__log-0.4.22",
"vendor__mustache-0.9.0",
"vendor__num-traits-0.2.19",
"vendor__num_cpus-1.16.0",
"vendor__proc-macro2-1.0.93",
"vendor__quote-1.0.38",
"vendor__ra_ap_base_db-0.0.258",
"vendor__ra_ap_cfg-0.0.258",
"vendor__ra_ap_hir-0.0.258",
"vendor__ra_ap_hir_def-0.0.258",
"vendor__ra_ap_hir_expand-0.0.258",
"vendor__ra_ap_ide_db-0.0.258",
"vendor__ra_ap_intern-0.0.258",
"vendor__ra_ap_load-cargo-0.0.258",
"vendor__ra_ap_parser-0.0.258",
"vendor__ra_ap_paths-0.0.258",
"vendor__ra_ap_project_model-0.0.258",
"vendor__ra_ap_span-0.0.258",
"vendor__ra_ap_stdx-0.0.258",
"vendor__ra_ap_syntax-0.0.258",
"vendor__ra_ap_vfs-0.0.258",
"vendor__rand-0.8.5",
"vendor__rayon-1.10.0",
"vendor__regex-1.11.1",
"vendor__serde-1.0.217",
"vendor__serde_json-1.0.135",
"vendor__serde_with-3.12.0",
"vendor__stderrlog-0.6.0",
"vendor__syn-2.0.96",
"vendor__toml-0.8.19",
"vendor__tracing-0.1.41",
"vendor__tracing-subscriber-0.3.19",
"vendor__tree-sitter-0.24.6",
"vendor__tree-sitter-embedded-template-0.23.2",
"vendor__tree-sitter-json-0.24.8",
"vendor__tree-sitter-ql-0.23.1",
"vendor__tree-sitter-ruby-0.23.1",
"vendor__triomphe-0.1.14",
"vendor__ungrammar-1.16.1",
)
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# rust-analyzer sources needed by the rust ast-generator (see `rust/ast-generator/README.md`)
RUST_ANALYZER_SRC_TAG = "2025-01-07"
http_archive(
name = "rust-analyzer-src",
build_file = "//rust/ast-generator:BUILD.rust-analyzer-src.bazel",
integrity = "sha256-eo8mIaUafZL8LOM65bDIIIXw1rNQ/P/x5RK/XUtgo5g=",
patch_args = ["-p1"],
patches = [
"//rust/ast-generator:patches/rust-analyzer.patch",
],
strip_prefix = "rust-analyzer-%s" % RUST_ANALYZER_SRC_TAG,
url = "https://github.com/rust-lang/rust-analyzer/archive/refs/tags/%s.tar.gz" % RUST_ANALYZER_SRC_TAG,
)
dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet")
dotnet.toolchain(dotnet_version = "9.0.100")
use_repo(dotnet, "dotnet_toolchains")
register_toolchains("@dotnet_toolchains//:all")
csharp_main_extension = use_extension("//csharp:paket.main_extension.bzl", "main_extension")
use_repo(csharp_main_extension, "paket.main")
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
pip.parse(
hub_name = "codegen_deps",
python_version = "3.11",
requirements_lock = "//misc/codegen:requirements_lock.txt",
)
use_repo(pip, "codegen_deps")
swift_deps = use_extension("//swift/third_party:load.bzl", "swift_deps")
# following list can be kept in sync with `bazel mod tidy`
use_repo(
swift_deps,
"binlog",
"picosha2",
"swift-prebuilt-linux",
"swift-prebuilt-linux-download-only",
"swift-prebuilt-macos",
"swift-prebuilt-macos-download-only",
"swift-resource-dir-linux",
"swift-resource-dir-macos",
)
node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
node.toolchain(
name = "nodejs",
node_urls = [
"https://nodejs.org/dist/v{version}/{filename}",
"https://mirrors.dotsrc.org/nodejs/release/v{version}/{filename}",
],
node_version = "18.15.0",
)
use_repo(node, "nodejs", "nodejs_toolchains")
kotlin_extractor_deps = use_extension("//java/kotlin-extractor:deps.bzl", "kotlin_extractor_deps")
# following list can be kept in sync by running `bazel mod tidy` in `codeql`
use_repo(
kotlin_extractor_deps,
"codeql_kotlin_defaults",
"codeql_kotlin_embeddable",
"kotlin-compiler-1.5.0",
"kotlin-compiler-1.5.10",
"kotlin-compiler-1.5.20",
"kotlin-compiler-1.5.30",
"kotlin-compiler-1.6.0",
"kotlin-compiler-1.6.20",
"kotlin-compiler-1.7.0",
"kotlin-compiler-1.7.20",
"kotlin-compiler-1.8.0",
"kotlin-compiler-1.9.0-Beta",
"kotlin-compiler-1.9.20-Beta",
"kotlin-compiler-2.0.0-RC1",
"kotlin-compiler-2.0.20-Beta2",
"kotlin-compiler-2.1.0-Beta1",
"kotlin-compiler-embeddable-1.5.0",
"kotlin-compiler-embeddable-1.5.10",
"kotlin-compiler-embeddable-1.5.20",
"kotlin-compiler-embeddable-1.5.30",
"kotlin-compiler-embeddable-1.6.0",
"kotlin-compiler-embeddable-1.6.20",
"kotlin-compiler-embeddable-1.7.0",
"kotlin-compiler-embeddable-1.7.20",
"kotlin-compiler-embeddable-1.8.0",
"kotlin-compiler-embeddable-1.9.0-Beta",
"kotlin-compiler-embeddable-1.9.20-Beta",
"kotlin-compiler-embeddable-2.0.0-RC1",
"kotlin-compiler-embeddable-2.0.20-Beta2",
"kotlin-compiler-embeddable-2.1.0-Beta1",
"kotlin-stdlib-1.5.0",
"kotlin-stdlib-1.5.10",
"kotlin-stdlib-1.5.20",
"kotlin-stdlib-1.5.30",
"kotlin-stdlib-1.6.0",
"kotlin-stdlib-1.6.20",
"kotlin-stdlib-1.7.0",
"kotlin-stdlib-1.7.20",
"kotlin-stdlib-1.8.0",
"kotlin-stdlib-1.9.0-Beta",
"kotlin-stdlib-1.9.20-Beta",
"kotlin-stdlib-2.0.0-RC1",
"kotlin-stdlib-2.0.20-Beta2",
"kotlin-stdlib-2.1.0-Beta1",
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
go_sdk.download(version = "1.23.1")
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//go/extractor:go.mod")
use_repo(go_deps, "org_golang_x_mod", "org_golang_x_tools")
lfs_files = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_files")
lfs_files(
name = "ripunzip-linux",
srcs = ["//misc/ripunzip:ripunzip-linux"],
executable = True,
)
lfs_files(
name = "ripunzip-windows",
srcs = ["//misc/ripunzip:ripunzip-windows.exe"],
executable = True,
)
lfs_files(
name = "ripunzip-macos",
srcs = ["//misc/ripunzip:ripunzip-macos"],
executable = True,
)
register_toolchains(
"@nodejs_toolchains//:all",
)

View File

@@ -1,23 +1,20 @@
# CodeQL
This open source repository contains the standard CodeQL libraries and queries that power [GitHub Advanced Security](https://github.com/features/security/code) and the other application security products that [GitHub](https://github.com/features/security/) makes available to its customers worldwide.
This open source repository contains the standard CodeQL libraries and queries that power [LGTM](https://lgtm.com) and the other CodeQL products that [GitHub](https://github.com) makes available to its customers worldwide. For the queries, libraries, and extractor that power Go analysis, visit the [CodeQL for Go repository](https://github.com/github/codeql-go).
## How do I learn CodeQL and run queries?
There is extensive documentation about the [CodeQL language](https://codeql.github.com/docs/), writing CodeQL using the [CodeQL extension for Visual Studio Code](https://docs.github.com/en/code-security/codeql-for-vs-code/) and using the [CodeQL CLI](https://docs.github.com/en/code-security/codeql-cli).
There is [extensive documentation](https://help.semmle.com/QL/learn-ql/) on getting started with writing CodeQL.
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode.html) extension to try out your queries on any open source project that's currently being analyzed.
## Contributing
We welcome contributions to our standard library and standard checks. Do you have an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! Before you do, though, please take the time to read our [contributing guidelines](CONTRIBUTING.md). You can also consult our [style guides](https://github.com/github/codeql/tree/main/docs) to learn how to format your code for consistency and clarity, how to write query metadata, and how to write query help documentation for your query.
For information on contributing to CodeQL documentation, see the "[contributing guide](docs/codeql/CONTRIBUTING.md)" for docs.
## License
The code in this repository is licensed under the [MIT License](LICENSE) by [GitHub](https://github.com).
The CodeQL CLI (including the CodeQL engine) is hosted in a [different repository](https://github.com/github/codeql-cli-binaries) and is [licensed separately](https://github.com/github/codeql-cli-binaries/blob/main/LICENSE.md). If you'd like to use the CodeQL CLI to analyze closed-source code, you will need a separate commercial license; please [contact us](https://github.com/enterprise/contact) for further help.
## Visual Studio Code integration
If you use Visual Studio Code to work in this repository, there are a few integration features to make development easier.

View File

@@ -1,9 +0,0 @@
load("//misc/bazel:pkg.bzl", "codeql_pack")
package(default_visibility = ["//visibility:public"])
codeql_pack(
name = "actions",
srcs = ["//actions/extractor"],
experimental = True,
)

View File

@@ -1,10 +0,0 @@
load("//misc/bazel:pkg.bzl", "codeql_pkg_files", "strip_prefix")
codeql_pkg_files(
name = "extractor",
srcs = [
"codeql-extractor.yml",
] + glob(["tools/**"]),
strip_prefix = strip_prefix.from_pkg(),
visibility = ["//actions:__pkg__"],
)

View File

@@ -1,44 +0,0 @@
name: "actions"
aliases: []
display_name: "GitHub Actions"
version: 0.0.1
column_kind: "utf16"
unicode_newlines: true
build_modes:
- none
file_coverage_languages: []
github_api_languages: []
scc_languages: []
file_types:
- name: workflow
display_name: GitHub Actions workflow files
extensions:
- .yml
- .yaml
forwarded_extractor_name: javascript
options:
trap:
title: TRAP options
description: Options about how the extractor handles TRAP files
type: object
visibility: 3
properties:
cache:
title: TRAP cache options
description: Options about how the extractor handles its TRAP cache
type: object
properties:
dir:
title: TRAP cache directory
description: The directory of the TRAP cache to use
type: string
bound:
title: TRAP cache bound
description: A soft limit (in MB) on the size of the TRAP cache
type: string
pattern: "[0-9]+"
write:
title: TRAP cache writeable
description: Whether to write to the TRAP cache as well as reading it
type: string
pattern: "(true|TRUE|false|FALSE)"

View File

@@ -1,40 +0,0 @@
if (($null -ne $env:LGTM_INDEX_INCLUDE) -or ($null -ne $env:LGTM_INDEX_EXCLUDE) -or ($null -ne $env:LGTM_INDEX_FILTERS)) {
Write-Output 'Path filters set. Passing them through to the JavaScript extractor.'
} else {
Write-Output 'No path filters set. Using the default filters.'
$DefaultPathFilters = @(
'exclude:**/*',
'include:.github/workflows/**/*.yml',
'include:.github/workflows/**/*.yaml',
'include:**/action.yml',
'include:**/action.yaml'
)
$env:LGTM_INDEX_FILTERS = $DefaultPathFilters -join "`n"
}
# Find the JavaScript extractor directory via `codeql resolve extractor`.
$CodeQL = Join-Path $env:CODEQL_DIST 'codeql.exe'
$env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = &$CodeQL resolve extractor --language javascript
if ($LASTEXITCODE -ne 0) {
throw 'Failed to resolve JavaScript extractor.'
}
Write-Output "Found JavaScript extractor at '${env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}'."
# Run the JavaScript autobuilder.
$JavaScriptAutoBuild = Join-Path $env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT 'tools\autobuild.cmd'
Write-Output "Running JavaScript autobuilder at '${JavaScriptAutoBuild}'."
# Copy the values of the Actions extractor environment variables to the JavaScript extractor environment variables.
$env:CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_DIAGNOSTIC_DIR
$env:CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_LOG_DIR
$env:CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_SCRATCH_DIR
$env:CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_SOURCE_ARCHIVE_DIR
$env:CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_TRAP_DIR
$env:CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = $env:CODEQL_EXTRACTOR_ACTIONS_WIP_DATABASE
&$JavaScriptAutoBuild
if ($LASTEXITCODE -ne 0) {
throw "JavaScript autobuilder failed."
}

View File

@@ -1,3 +0,0 @@
@echo off
rem All of the work is done in the PowerShell script
powershell.exe %~dp0autobuild-impl.ps1

View File

@@ -1,39 +0,0 @@
#!/bin/sh
set -eu
DEFAULT_PATH_FILTERS=$(cat << END
exclude:**/*
include:.github/workflows/**/*.yml
include:.github/workflows/**/*.yaml
include:**/action.yml
include:**/action.yaml
END
)
if [ -n "${LGTM_INDEX_INCLUDE:-}" ] || [ -n "${LGTM_INDEX_EXCLUDE:-}" ] || [ -n "${LGTM_INDEX_FILTERS:-}" ] ; then
echo "Path filters set. Passing them through to the JavaScript extractor."
else
echo "No path filters set. Using the default filters."
LGTM_INDEX_FILTERS="${DEFAULT_PATH_FILTERS}"
export LGTM_INDEX_FILTERS
fi
# Find the JavaScript extractor directory via `codeql resolve extractor`.
CODEQL_EXTRACTOR_JAVASCRIPT_ROOT="$($CODEQL_DIST/codeql resolve extractor --language javascript)"
export CODEQL_EXTRACTOR_JAVASCRIPT_ROOT
echo "Found JavaScript extractor at '${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}'."
# Run the JavaScript autobuilder
JAVASCRIPT_AUTO_BUILD="${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}/tools/autobuild.sh"
echo "Running JavaScript autobuilder at '${JAVASCRIPT_AUTO_BUILD}'."
# Copy the values of the Actions extractor environment variables to the JavaScript extractor environment variables.
env CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR="${CODEQL_EXTRACTOR_ACTIONS_DIAGNOSTIC_DIR}" \
CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR="${CODEQL_EXTRACTOR_ACTIONS_LOG_DIR}" \
CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR="${CODEQL_EXTRACTOR_ACTIONS_SCRATCH_DIR}" \
CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR="${CODEQL_EXTRACTOR_ACTIONS_SOURCE_ARCHIVE_DIR}" \
CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR="${CODEQL_EXTRACTOR_ACTIONS_TRAP_DIR}" \
CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE="${CODEQL_EXTRACTOR_ACTIONS_WIP_DATABASE}" \
${JAVASCRIPT_AUTO_BUILD}

View File

@@ -1,9 +0,0 @@
## 0.4.1
No user-facing changes.
## 0.4.0
### New Features
* Initial public preview release

View File

@@ -1 +0,0 @@
import codeql.actions.Ast

View File

@@ -1,5 +0,0 @@
## 0.4.0
### New Features
* Initial public preview release

View File

@@ -1,3 +0,0 @@
## 0.4.1
No user-facing changes.

View File

@@ -1,4 +0,0 @@
---
lockVersion: 1.0.0
dependencies: {}
compiled: false

View File

@@ -1,2 +0,0 @@
---
lastReleaseVersion: 0.4.1

View File

@@ -1,98 +0,0 @@
/** Provides classes for working with locations. */
import files.FileSystem
import codeql.actions.ast.internal.Ast
bindingset[loc]
pragma[inline_late]
private string locationToString(Location loc) {
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
loc.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
result = filepath + "@" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
)
}
newtype TLocation =
TBaseLocation(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
exists(File file |
file.getAbsolutePath() = filepath and
locations_default(_, file, startline, startcolumn, endline, endcolumn)
)
or
exists(ExpressionImpl e |
e.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
)
or
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
/**
* A location as given by a file, a start line, a start column,
* an end line, and an end column.
*
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
class Location extends TLocation, TBaseLocation {
string filepath;
int startline;
int startcolumn;
int endline;
int endcolumn;
Location() { this = TBaseLocation(filepath, startline, startcolumn, endline, endcolumn) }
/** Gets the file for this location. */
File getFile() {
exists(File file |
file.getAbsolutePath() = filepath and
result = file
)
}
/** Gets the 1-based line number (inclusive) where this location starts. */
int getStartLine() { result = startline }
/** Gets the 1-based column number (inclusive) where this location starts. */
int getStartColumn() { result = startcolumn }
/** Gets the 1-based line number (inclusive) where this.getLocationDefault() location ends. */
int getEndLine() { result = endline }
/** Gets the 1-based column number (inclusive) where this.getLocationDefault() location ends. */
int getEndColumn() { result = endcolumn }
/** Gets the number of lines covered by this location. */
int getNumLines() { result = endline - startline + 1 }
/** Gets a textual representation of this element. */
pragma[inline]
string toString() { result = locationToString(this) }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(string p, int sl, int sc, int el, int ec) {
p = filepath and
sl = startline and
sc = startcolumn and
el = endline and
ec = endcolumn
}
/** Holds if this location starts strictly before the specified location. */
pragma[inline]
predicate strictlyBefore(Location other) {
this.getStartLine() < other.getStartLine()
or
this.getStartLine() = other.getStartLine() and this.getStartColumn() < other.getStartColumn()
}
}
/** An entity representing an empty location. */
class EmptyLocation extends Location {
EmptyLocation() { this.hasLocationInfo("", 0, 0, 0, 0) }
}

View File

@@ -1,400 +0,0 @@
private import codeql.actions.ast.internal.Ast
private import codeql.Locations
import codeql.actions.Helper
class AstNode instanceof AstNodeImpl {
AstNode getAChildNode() { result = super.getAChildNode() }
AstNode getParentNode() { result = super.getParentNode() }
string getAPrimaryQlClass() { result = super.getAPrimaryQlClass() }
Location getLocation() { result = super.getLocation() }
string toString() { result = super.toString() }
Step getEnclosingStep() { result = super.getEnclosingStep() }
Job getEnclosingJob() { result = super.getEnclosingJob() }
Event getATriggerEvent() { result = super.getATriggerEvent() }
Workflow getEnclosingWorkflow() { result = super.getEnclosingWorkflow() }
CompositeAction getEnclosingCompositeAction() { result = super.getEnclosingCompositeAction() }
Expression getInScopeEnvVarExpr(string name) { result = super.getInScopeEnvVarExpr(name) }
ScalarValue getInScopeDefaultValue(string name, string prop) {
result = super.getInScopeDefaultValue(name, prop)
}
}
class ScalarValue extends AstNode instanceof ScalarValueImpl {
string getValue() { result = super.getValue() }
}
class Expression extends AstNode instanceof ExpressionImpl {
string expression;
string rawExpression;
Expression() {
expression = this.getExpression() and
rawExpression = this.getRawExpression()
}
string getExpression() { result = expression }
string getRawExpression() { result = rawExpression }
string getNormalizedExpression() { result = normalizeExpr(expression) }
}
/** A common class for `env` in workflow, job or step. */
abstract class Env extends AstNode instanceof EnvImpl {
/** Gets an environment variable value given its name. */
ScalarValueImpl getEnvVarValue(string name) { result = super.getEnvVarValue(name) }
/** Gets an environment variable value. */
ScalarValueImpl getAnEnvVarValue() { result = super.getAnEnvVarValue() }
/** Gets an environment variable expressin given its name. */
ExpressionImpl getEnvVarExpr(string name) { result = super.getEnvVarExpr(name) }
/** Gets an environment variable expression. */
ExpressionImpl getAnEnvVarExpr() { result = super.getAnEnvVarExpr() }
}
/**
* A custom composite action. This is a mapping at the top level of an Actions YAML action file.
* See https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions.
*/
class CompositeAction extends AstNode instanceof CompositeActionImpl {
Runs getRuns() { result = super.getRuns() }
Outputs getOutputs() { result = super.getOutputs() }
Expression getAnOutputExpr() { result = super.getAnOutputExpr() }
Expression getOutputExpr(string outputName) { result = super.getOutputExpr(outputName) }
Input getAnInput() { result = super.getAnInput() }
Input getInput(string inputName) { result = super.getInput(inputName) }
LocalJob getACallerJob() { result = super.getACallerJob() }
UsesStep getACallerStep() { result = super.getACallerStep() }
predicate isPrivileged() { super.isPrivileged() }
}
/**
* An Actions workflow. This is a mapping at the top level of an Actions YAML workflow file.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions.
*/
class Workflow extends AstNode instanceof WorkflowImpl {
Env getEnv() { result = super.getEnv() }
string getName() { result = super.getName() }
Job getAJob() { result = super.getAJob() }
Job getJob(string jobId) { result = super.getJob(jobId) }
Permissions getPermissions() { result = super.getPermissions() }
Strategy getStrategy() { result = super.getStrategy() }
On getOn() { result = super.getOn() }
}
class ReusableWorkflow extends Workflow instanceof ReusableWorkflowImpl {
Outputs getOutputs() { result = super.getOutputs() }
Expression getAnOutputExpr() { result = super.getAnOutputExpr() }
Expression getOutputExpr(string outputName) { result = super.getOutputExpr(outputName) }
Input getAnInput() { result = super.getAnInput() }
Input getInput(string inputName) { result = super.getInput(inputName) }
ExternalJob getACaller() { result = super.getACaller() }
}
class Input extends AstNode instanceof InputImpl { }
class Default extends AstNode instanceof DefaultsImpl {
ScalarValue getValue(string name, string prop) { result = super.getValue(name, prop) }
}
class Outputs extends AstNode instanceof OutputsImpl {
Expression getAnOutputExpr() { result = super.getAnOutputExpr() }
Expression getOutputExpr(string outputName) { result = super.getOutputExpr(outputName) }
override string toString() { result = "Job outputs node" }
}
class Permissions extends AstNode instanceof PermissionsImpl {
bindingset[perm]
string getPermission(string perm) { result = super.getPermission(perm) }
string getAPermission() { result = super.getAPermission() }
}
class Strategy extends AstNode instanceof StrategyImpl {
Expression getMatrixVarExpr(string varName) { result = super.getMatrixVarExpr(varName) }
Expression getAMatrixVarExpr() { result = super.getAMatrixVarExpr() }
}
/**
* https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idneeds
*/
class Needs extends AstNode instanceof NeedsImpl {
Job getANeededJob() { result = super.getANeededJob() }
}
class On extends AstNode instanceof OnImpl {
Event getAnEvent() { result = super.getAnEvent() }
}
class Event extends AstNode instanceof EventImpl {
string getName() { result = super.getName() }
string getAnActivityType() { result = super.getAnActivityType() }
string getAPropertyValue(string prop) { result = super.getAPropertyValue(prop) }
predicate hasProperty(string prop) { super.hasProperty(prop) }
predicate isExternallyTriggerable() { super.isExternallyTriggerable() }
predicate isPrivileged() { super.isPrivileged() }
}
/**
* An Actions job within a workflow.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobs.
*/
abstract class Job extends AstNode instanceof JobImpl {
string getId() { result = super.getId() }
Workflow getWorkflow() { result = super.getWorkflow() }
Job getANeededJob() { result = super.getANeededJob() }
Outputs getOutputs() { result = super.getOutputs() }
Expression getAnOutputExpr() { result = super.getAnOutputExpr() }
Expression getOutputExpr(string outputName) { result = super.getOutputExpr(outputName) }
Env getEnv() { result = super.getEnv() }
If getIf() { result = super.getIf() }
Environment getEnvironment() { result = super.getEnvironment() }
Permissions getPermissions() { result = super.getPermissions() }
Strategy getStrategy() { result = super.getStrategy() }
string getARunsOnLabel() { result = super.getARunsOnLabel() }
predicate isPrivileged() { super.isPrivileged() }
predicate isPrivilegedExternallyTriggerable(Event event) {
super.isPrivilegedExternallyTriggerable(event)
}
}
abstract class StepsContainer extends AstNode instanceof StepsContainerImpl {
Step getAStep() { result = super.getAStep() }
Step getStep(int i) { result = super.getStep(i) }
}
/**
* An `runs` mapping in a custom composite action YAML.
* See https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs
*/
class Runs extends StepsContainer instanceof RunsImpl {
CompositeAction getAction() { result = super.getAction() }
}
/**
* An Actions job within a workflow which is composed of steps.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobs.
*/
class LocalJob extends Job, StepsContainer instanceof LocalJobImpl { }
/**
* A step within an Actions job.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idsteps.
*/
class Step extends AstNode instanceof StepImpl {
string getId() { result = super.getId() }
Env getEnv() { result = super.getEnv() }
If getIf() { result = super.getIf() }
StepsContainer getContainer() { result = super.getContainer() }
Step getNextStep() { result = super.getNextStep() }
Step getAFollowingStep() { result = super.getAFollowingStep() }
}
/**
* An If node representing a conditional statement.
*/
class If extends AstNode instanceof IfImpl {
string getCondition() { result = super.getCondition() }
Expression getConditionExpr() { result = super.getConditionExpr() }
string getConditionStyle() { result = super.getConditionStyle() }
}
/**
* An Environemnt node representing a deployment environment.
*/
class Environment extends AstNode instanceof EnvironmentImpl {
string getName() { result = super.getName() }
Expression getNameExpr() { result = super.getNameExpr() }
}
abstract class Uses extends AstNode instanceof UsesImpl {
string getCallee() { result = super.getCallee() }
ScalarValue getCalleeNode() { result = super.getCalleeNode() }
string getVersion() { result = super.getVersion() }
int getMajorVersion() { result = super.getMajorVersion() }
string getArgument(string argName) { result = super.getArgument(argName) }
Expression getArgumentExpr(string argName) { result = super.getArgumentExpr(argName) }
}
class UsesStep extends Step, Uses instanceof UsesStepImpl { }
class ExternalJob extends Job, Uses instanceof ExternalJobImpl { }
/**
* A `run` field within an Actions job step, which runs command-line programs using an operating system shell.
* See https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsrun.
*/
class Run extends Step instanceof RunImpl {
ShellScript getScript() { result = super.getScript() }
Expression getAnScriptExpr() { result = super.getAnScriptExpr() }
string getWorkingDirectory() { result = super.getWorkingDirectory() }
string getShell() { result = super.getShell() }
}
class ShellScript extends ScalarValueImpl instanceof ShellScriptImpl {
string getRawScript() { result = super.getRawScript() }
string getStmt(int i) { result = super.getStmt(i) }
string getAStmt() { result = super.getAStmt() }
string getCommand(int i) { result = super.getCommand(i) }
string getACommand() { result = super.getACommand() }
string getFileReadCommand(int i) { result = super.getFileReadCommand(i) }
string getAFileReadCommand() { result = super.getAFileReadCommand() }
predicate getAssignment(int i, string name, string data) { super.getAssignment(i, name, data) }
predicate getAnAssignment(string name, string data) { super.getAnAssignment(name, data) }
predicate getAWriteToGitHubEnv(string name, string data) {
super.getAWriteToGitHubEnv(name, data)
}
predicate getAWriteToGitHubOutput(string name, string data) {
super.getAWriteToGitHubOutput(name, data)
}
predicate getAWriteToGitHubPath(string data) { super.getAWriteToGitHubPath(data) }
predicate getAnEnvReachingGitHubOutputWrite(string var, string output_field) {
super.getAnEnvReachingGitHubOutputWrite(var, output_field)
}
predicate getACmdReachingGitHubOutputWrite(string cmd, string output_field) {
super.getACmdReachingGitHubOutputWrite(cmd, output_field)
}
predicate getAnEnvReachingGitHubEnvWrite(string var, string output_field) {
super.getAnEnvReachingGitHubEnvWrite(var, output_field)
}
predicate getACmdReachingGitHubEnvWrite(string cmd, string output_field) {
super.getACmdReachingGitHubEnvWrite(cmd, output_field)
}
predicate getAnEnvReachingGitHubPathWrite(string var) {
super.getAnEnvReachingGitHubPathWrite(var)
}
predicate getACmdReachingGitHubPathWrite(string cmd) { super.getACmdReachingGitHubPathWrite(cmd) }
predicate getAnEnvReachingArgumentInjectionSink(string var, string command, string argument) {
super.getAnEnvReachingArgumentInjectionSink(var, command, argument)
}
predicate getACmdReachingArgumentInjectionSink(string cmd, string command, string argument) {
super.getACmdReachingArgumentInjectionSink(cmd, command, argument)
}
predicate fileToGitHubEnv(string path) { super.fileToGitHubEnv(path) }
predicate fileToGitHubOutput(string path) { super.fileToGitHubOutput(path) }
predicate fileToGitHubPath(string path) { super.fileToGitHubPath(path) }
}
abstract class SimpleReferenceExpression extends AstNode instanceof SimpleReferenceExpressionImpl {
string getFieldName() { result = super.getFieldName() }
AstNode getTarget() { result = super.getTarget() }
}
class JsonReferenceExpression extends AstNode instanceof JsonReferenceExpressionImpl {
string getAccessPath() { result = super.getAccessPath() }
string getInnerExpression() { result = super.getInnerExpression() }
}
class GitHubExpression extends SimpleReferenceExpression instanceof GitHubExpressionImpl { }
class SecretsExpression extends SimpleReferenceExpression instanceof SecretsExpressionImpl { }
class StepsExpression extends SimpleReferenceExpression instanceof StepsExpressionImpl {
string getStepId() { result = super.getStepId() }
}
class NeedsExpression extends SimpleReferenceExpression instanceof NeedsExpressionImpl {
string getNeededJobId() { result = super.getNeededJobId() }
}
class JobsExpression extends SimpleReferenceExpression instanceof JobsExpressionImpl { }
class InputsExpression extends SimpleReferenceExpression instanceof InputsExpressionImpl { }
class EnvExpression extends SimpleReferenceExpression instanceof EnvExpressionImpl { }
class MatrixExpression extends SimpleReferenceExpression instanceof MatrixExpressionImpl { }

View File

@@ -1,722 +0,0 @@
private import codeql.actions.Ast
class BashShellScript extends ShellScript {
BashShellScript() {
exists(Run run |
this = run.getScript() and
run.getShell().matches(["bash%", "sh"])
)
}
private string lineProducer(int i) {
result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", i)
}
private predicate cmdSubstitutionReplacement(string cmdSubs, string id, int k) {
exists(string line | line = this.lineProducer(k) |
exists(int i, int j |
cmdSubs =
// $() cmd substitution
line.regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", i, j)
.regexpReplaceAll("^\\$\\(", "")
.regexpReplaceAll("\\)$", "") and
id = "cmdsubs:" + k + ":" + i + ":" + j
)
or
exists(int i, int j |
// `...` cmd substitution
cmdSubs =
line.regexpFind("\\`[^\\`]+\\`", i, j)
.regexpReplaceAll("^\\`", "")
.regexpReplaceAll("\\`$", "") and
id = "cmd:" + k + ":" + i + ":" + j
)
)
}
private predicate rankedCmdSubstitutionReplacements(int i, string old, string new) {
old = rank[i](string old2 | this.cmdSubstitutionReplacement(old2, _, _) | old2) and
this.cmdSubstitutionReplacement(old, new, _)
}
private predicate doReplaceCmdSubstitutions(int line, int round, string old, string new) {
round = 0 and
old = this.lineProducer(line) and
new = old
or
round > 0 and
exists(string middle, string target, string replacement |
this.doReplaceCmdSubstitutions(line, round - 1, old, middle) and
this.rankedCmdSubstitutionReplacements(round, target, replacement) and
new = middle.replaceAll(target, replacement)
)
}
private string cmdSubstitutedLineProducer(int i) {
// script lines where any command substitution has been replaced with a unique placeholder
result =
max(int round, string new |
this.doReplaceCmdSubstitutions(i, round, _, new)
|
new order by round
)
or
this.cmdSubstitutionReplacement(result, _, i)
}
private predicate quotedStringReplacement(string quotedStr, string id) {
exists(string line, int k | line = this.cmdSubstitutedLineProducer(k) |
exists(int i, int j |
// double quoted string
quotedStr = line.regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", i, j) and
id =
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
)
or
exists(int i, int j |
// single quoted string
quotedStr = line.regexpFind("'((?:\\\\.|[^'\\\\])*)'", i, j) and
id =
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
)
)
}
private predicate rankedQuotedStringReplacements(int i, string old, string new) {
old = rank[i](string old2 | this.quotedStringReplacement(old2, _) | old2) and
this.quotedStringReplacement(old, new)
}
private predicate doReplaceQuotedStrings(int line, int round, string old, string new) {
round = 0 and
old = this.cmdSubstitutedLineProducer(line) and
new = old
or
round > 0 and
exists(string middle, string target, string replacement |
this.doReplaceQuotedStrings(line, round - 1, old, middle) and
this.rankedQuotedStringReplacements(round, target, replacement) and
new = middle.replaceAll(target, replacement)
)
}
private string quotedStringLineProducer(int i) {
result =
max(int round, string new | this.doReplaceQuotedStrings(i, round, _, new) | new order by round)
}
private string stmtProducer(int i) {
result = this.quotedStringLineProducer(i).splitAt(Bash::splitSeparator()).trim() and
// when splitting the line with a separator that is not present, the result is the original line which may contain other separators
// we only one the split parts that do not contain any of the separators
not result.indexOf(Bash::splitSeparator()) > -1
}
private predicate doStmtRestoreQuotedStrings(int line, int round, string old, string new) {
round = 0 and
old = this.stmtProducer(line) and
new = old
or
round > 0 and
exists(string middle, string target, string replacement |
this.doStmtRestoreQuotedStrings(line, round - 1, old, middle) and
this.rankedQuotedStringReplacements(round, target, replacement) and
new = middle.replaceAll(replacement, target)
)
}
private string restoredStmtQuotedStringLineProducer(int i) {
result =
max(int round, string new |
this.doStmtRestoreQuotedStrings(i, round, _, new)
|
new order by round
) and
not result.indexOf("qstr:") > -1
}
private predicate doStmtRestoreCmdSubstitutions(int line, int round, string old, string new) {
round = 0 and
old = this.restoredStmtQuotedStringLineProducer(line) and
new = old
or
round > 0 and
exists(string middle, string target, string replacement |
this.doStmtRestoreCmdSubstitutions(line, round - 1, old, middle) and
this.rankedCmdSubstitutionReplacements(round, target, replacement) and
new = middle.replaceAll(replacement, target)
)
}
override string getStmt(int i) {
result =
max(int round, string new |
this.doStmtRestoreCmdSubstitutions(i, round, _, new)
|
new order by round
) and
not result.indexOf("cmdsubs:") > -1
}
override string getAStmt() { result = this.getStmt(_) }
private string cmdProducer(int i) {
result = this.quotedStringLineProducer(i).splitAt(Bash::separator()).trim() and
// when splitting the line with a separator that is not present, the result is the original line which may contain other separators
// we only one the split parts that do not contain any of the separators
not result.indexOf(Bash::separator()) > -1
}
private predicate doCmdRestoreQuotedStrings(int line, int round, string old, string new) {
round = 0 and
old = this.cmdProducer(line) and
new = old
or
round > 0 and
exists(string middle, string target, string replacement |
this.doCmdRestoreQuotedStrings(line, round - 1, old, middle) and
this.rankedQuotedStringReplacements(round, target, replacement) and
new = middle.replaceAll(replacement, target)
)
}
private string restoredCmdQuotedStringLineProducer(int i) {
result =
max(int round, string new |
this.doCmdRestoreQuotedStrings(i, round, _, new)
|
new order by round
) and
not result.indexOf("qstr:") > -1
}
private predicate doCmdRestoreCmdSubstitutions(int line, int round, string old, string new) {
round = 0 and
old = this.restoredCmdQuotedStringLineProducer(line) and
new = old
or
round > 0 and
exists(string middle, string target, string replacement |
this.doCmdRestoreCmdSubstitutions(line, round - 1, old, middle) and
this.rankedCmdSubstitutionReplacements(round, target, replacement) and
new = middle.replaceAll(replacement, target)
)
}
string getCmd(int i) {
result =
max(int round, string new |
this.doCmdRestoreCmdSubstitutions(i, round, _, new)
|
new order by round
) and
not result.indexOf("cmdsubs:") > -1
}
string getACmd() { result = this.getCmd(_) }
override string getCommand(int i) {
// remove redirection
result =
this.getCmd(i)
.regexpReplaceAll("(>|>>|2>|2>>|<|<<<)\\s*[\\{\\}\\$\"'_\\-0-9a-zA-Z]+$", "")
.trim() and
// exclude variable declarations
not result.regexpMatch("^[a-zA-Z0-9\\-_]+=") and
// exclude comments
not result.trim().indexOf("#") = 0 and
// exclude the following keywords
not result =
[
"", "for", "in", "do", "done", "if", "then", "else", "elif", "fi", "while", "until", "case",
"esac", "{", "}"
]
}
override string getACommand() { result = this.getCommand(_) }
override string getFileReadCommand(int i) {
result = this.getStmt(i) and
result.matches(Bash::fileReadCommand() + "%")
}
override string getAFileReadCommand() { result = this.getFileReadCommand(_) }
override predicate getAssignment(int i, string name, string data) {
exists(string stmt |
stmt = this.getStmt(i) and
name = stmt.regexpCapture("^([a-zA-Z0-9\\-_]+)=.*", 1) and
data = stmt.regexpCapture("^[a-zA-Z0-9\\-_]+=(.*)", 1)
)
}
override predicate getAnAssignment(string name, string data) { this.getAssignment(_, name, data) }
override predicate getAWriteToGitHubEnv(string name, string data) {
exists(string raw |
Bash::extractFileWrite(this, "GITHUB_ENV", raw) and
Bash::extractVariableAndValue(raw, name, data)
)
}
override predicate getAWriteToGitHubOutput(string name, string data) {
exists(string raw |
Bash::extractFileWrite(this, "GITHUB_OUTPUT", raw) and
Bash::extractVariableAndValue(raw, name, data)
)
}
override predicate getAWriteToGitHubPath(string data) {
Bash::extractFileWrite(this, "GITHUB_PATH", data)
}
override predicate getAnEnvReachingGitHubOutputWrite(string var, string output_field) {
Bash::envReachingGitHubFileWrite(this, var, "GITHUB_OUTPUT", output_field)
}
override predicate getACmdReachingGitHubOutputWrite(string cmd, string output_field) {
Bash::cmdReachingGitHubFileWrite(this, cmd, "GITHUB_OUTPUT", output_field)
}
override predicate getAnEnvReachingGitHubEnvWrite(string var, string output_field) {
Bash::envReachingGitHubFileWrite(this, var, "GITHUB_ENV", output_field)
}
override predicate getACmdReachingGitHubEnvWrite(string cmd, string output_field) {
Bash::cmdReachingGitHubFileWrite(this, cmd, "GITHUB_ENV", output_field)
}
override predicate getAnEnvReachingGitHubPathWrite(string var) {
Bash::envReachingGitHubFileWrite(this, var, "GITHUB_PATH", _)
}
override predicate getACmdReachingGitHubPathWrite(string cmd) {
Bash::cmdReachingGitHubFileWrite(this, cmd, "GITHUB_PATH", _)
}
override predicate getAnEnvReachingArgumentInjectionSink(
string var, string command, string argument
) {
Bash::envReachingArgumentInjectionSink(this, var, command, argument)
}
override predicate getACmdReachingArgumentInjectionSink(
string cmd, string command, string argument
) {
Bash::cmdReachingArgumentInjectionSink(this, cmd, command, argument)
}
override predicate fileToGitHubEnv(string path) {
Bash::fileToFileWrite(this, "GITHUB_ENV", path)
}
override predicate fileToGitHubOutput(string path) {
Bash::fileToFileWrite(this, "GITHUB_OUTPUT", path)
}
override predicate fileToGitHubPath(string path) {
Bash::fileToFileWrite(this, "GITHUB_PATH", path)
}
}
module Bash {
string stmtSeparator() { result = ";" }
string commandSeparator() { result = ["&&", "||"] }
string splitSeparator() {
result = stmtSeparator() or
result = commandSeparator()
}
string redirectionSeparator() { result = [">", ">>", "2>", "2>>", ">&", "2>&", "<", "<<<"] }
string pipeSeparator() { result = "|" }
string separator() {
result = stmtSeparator() or
result = commandSeparator() or
result = pipeSeparator()
}
string fileReadCommand() { result = ["<", "cat", "jq", "yq", "tail", "head"] }
/** Checks if expr is a bash command substitution */
bindingset[expr]
predicate isCmdSubstitution(string expr, string cmd) {
exists(string regexp |
// $(cmd)
regexp = "\\$\\(([^)]+)\\)" and
cmd = expr.regexpCapture(regexp, 1)
or
// `cmd`
regexp = "`([^`]+)`" and
cmd = expr.regexpCapture(regexp, 1)
)
}
/** Checks if expr is a bash command substitution */
bindingset[expr]
predicate containsCmdSubstitution(string expr, string cmd) {
exists(string regexp |
// $(cmd)
regexp = ".*\\$\\(([^)]+)\\).*" and
cmd = expr.regexpCapture(regexp, 1).trim()
or
// `cmd`
regexp = ".*`([^`]+)`.*" and
cmd = expr.regexpCapture(regexp, 1).trim()
)
}
/** Checks if expr is a bash parameter expansion */
bindingset[expr]
predicate isParameterExpansion(string expr, string parameter, string operator, string params) {
exists(string regexp |
// $VAR
regexp = "\\$([a-zA-Z_][a-zA-Z0-9_]+)\\b" and
parameter = expr.regexpCapture(regexp, 1) and
operator = "" and
params = ""
or
// ${VAR}
regexp = "\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}" and
parameter = expr.regexpCapture(regexp, 1) and
operator = "" and
params = ""
or
// ${!VAR}
regexp = "\\$\\{([!#])([a-zA-Z_][a-zA-Z0-9_]*)\\}" and
parameter = expr.regexpCapture(regexp, 2) and
operator = expr.regexpCapture(regexp, 1) and
params = ""
or
// ${VAR<OP><PARAMS>}, ...
regexp = "\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)([#%/:^,\\-+]{1,2})?(.*?)\\}" and
parameter = expr.regexpCapture(regexp, 1) and
operator = expr.regexpCapture(regexp, 2) and
params = expr.regexpCapture(regexp, 3)
)
}
bindingset[expr]
predicate containsParameterExpansion(string expr, string parameter, string operator, string params) {
exists(string regexp |
// $VAR
regexp = ".*\\$([a-zA-Z_][a-zA-Z0-9_]+)\\b.*" and
parameter = expr.regexpCapture(regexp, 1) and
operator = "" and
params = ""
or
// ${VAR}
regexp = ".*\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}.*" and
parameter = expr.regexpCapture(regexp, 1) and
operator = "" and
params = ""
or
// ${!VAR}
regexp = ".*\\$\\{([!#])([a-zA-Z_][a-zA-Z0-9_]*)\\}.*" and
parameter = expr.regexpCapture(regexp, 2) and
operator = expr.regexpCapture(regexp, 1) and
params = ""
or
// ${VAR<OP><PARAMS>}, ...
regexp = ".*\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)([#%/:^,\\-+]{1,2})?(.*?)\\}.*" and
parameter = expr.regexpCapture(regexp, 1) and
operator = expr.regexpCapture(regexp, 2) and
params = expr.regexpCapture(regexp, 3)
)
}
bindingset[raw_content]
predicate extractVariableAndValue(string raw_content, string key, string value) {
exists(string regexp, string content | content = trimQuotes(raw_content) |
regexp = "(?msi).*^([a-zA-Z_][a-zA-Z0-9_]*)\\s*<<\\s*['\"]?(\\S+)['\"]?\\s*\n(.*?)\n\\2\\s*$" and
key = trimQuotes(content.regexpCapture(regexp, 1)) and
value = trimQuotes(content.regexpCapture(regexp, 3))
or
exists(string line |
line = content.splitAt("\n") and
regexp = "(?i)^([a-zA-Z_][a-zA-Z0-9_\\-]*)\\s*=\\s*(.*)$" and
key = trimQuotes(line.regexpCapture(regexp, 1)) and
value = trimQuotes(line.regexpCapture(regexp, 2))
)
)
}
bindingset[script]
predicate singleLineFileWrite(
string script, string cmd, string file, string content, string filters
) {
exists(string regexp |
regexp = "(?i)(echo|printf)\\s*(.*?)\\s*(>>|>|\\s*\\|\\s*tee\\s*(-a|--append)?)\\s*(\\S+)" and
cmd = script.regexpCapture(regexp, 1) and
file = trimQuotes(script.regexpCapture(regexp, 5)) and
filters = "" and
content = script.regexpCapture(regexp, 2)
)
}
bindingset[script]
predicate singleLineWorkflowCmd(string script, string cmd, string key, string value) {
exists(string regexp |
regexp = "(?i)(echo|printf)\\s*(['|\"])?::(set-[a-z]+)\\s*name\\s*=\\s*(.*?)::(.*)" and
cmd = script.regexpCapture(regexp, 3) and
key = script.regexpCapture(regexp, 4) and
value = trimQuotes(script.regexpCapture(regexp, 5))
or
regexp = "(?i)(echo|printf)\\s*(['|\"])?::(add-[a-z]+)\\s*::(.*)" and
cmd = script.regexpCapture(regexp, 3) and
key = "" and
value = trimQuotes(script.regexpCapture(regexp, 4))
)
}
bindingset[script]
predicate heredocFileWrite(string script, string cmd, string file, string content, string filters) {
exists(string regexp |
regexp =
"(?msi).*^(cat)\\s*(>>|>|\\s*\\|\\s*tee\\s*(-a|--append)?)\\s*(\\S+)\\s*<<\\s*['\"]?(\\S+)['\"]?\\s*\n(.*?)\n\\4\\s*$.*" and
cmd = script.regexpCapture(regexp, 1) and
file = trimQuotes(script.regexpCapture(regexp, 4)) and
content = script.regexpCapture(regexp, 6) and
filters = ""
or
regexp =
"(?msi).*^(cat)\\s*(<<|<)\\s*[-]?['\"]?(\\S+)['\"]?\\s*([^>]*)(>>|>|\\s*\\|\\s*tee\\s*(-a|--append)?)\\s*(\\S+)\\s*\n(.*?)\n\\3\\s*$.*" and
cmd = script.regexpCapture(regexp, 1) and
file = trimQuotes(script.regexpCapture(regexp, 7)) and
filters = script.regexpCapture(regexp, 4) and
content = script.regexpCapture(regexp, 8)
)
}
bindingset[script]
predicate linesFileWrite(string script, string cmd, string file, string content, string filters) {
exists(string regexp, string var_name |
regexp =
"(?msi).*((echo|printf)\\s+['|\"]?(.*?<<(\\S+))['|\"]?\\s*>>\\s*(\\S+)\\s*[\r\n]+)" +
"(((.*?)\\s*>>\\s*\\S+\\s*[\r\n]+)+)" +
"((echo|printf)\\s+['|\"]?(EOF)['|\"]?\\s*>>\\s*\\S+\\s*[\r\n]*).*" and
var_name = trimQuotes(script.regexpCapture(regexp, 3)).regexpReplaceAll("<<\\s*(\\S+)", "") and
content =
var_name + "=$(" +
trimQuotes(script.regexpCapture(regexp, 6))
.regexpReplaceAll(">>.*GITHUB_(ENV|OUTPUT)(})?", "")
.trim() + ")" and
cmd = "echo" and
file = trimQuotes(script.regexpCapture(regexp, 5)) and
filters = ""
)
}
bindingset[script]
predicate blockFileWrite(string script, string cmd, string file, string content, string filters) {
exists(string regexp, string first_line, string var_name |
regexp =
"(?msi).*^\\s*\\{\\s*[\r\n]" +
//
"(.*?)" +
//
"(\\s*\\}\\s*(>>|>|\\s*\\|\\s*tee\\s*(-a|--append)?)\\s*(\\S+))\\s*$.*" and
first_line = script.regexpCapture(regexp, 1).splitAt("\n", 0).trim() and
var_name = first_line.regexpCapture("echo\\s+('|\\\")?(.*)<<.*", 2) and
content = var_name + "=$(" + script.regexpCapture(regexp, 1).splitAt("\n").trim() + ")" and
not content.indexOf("EOF") > 0 and
file = trimQuotes(script.regexpCapture(regexp, 5)) and
cmd = "echo" and
filters = ""
)
}
bindingset[script]
predicate multiLineFileWrite(
string script, string cmd, string file, string content, string filters
) {
heredocFileWrite(script, cmd, file, content, filters)
or
linesFileWrite(script, cmd, file, content, filters)
or
blockFileWrite(script, cmd, file, content, filters)
}
bindingset[file_var]
predicate extractFileWrite(BashShellScript script, string file_var, string content) {
// single line assignment
exists(string file_expr, string raw_content |
isParameterExpansion(file_expr, file_var, _, _) and
singleLineFileWrite(script.getAStmt(), _, file_expr, raw_content, _) and
content = trimQuotes(raw_content)
)
or
// workflow command assignment
exists(string key, string value, string cmd |
(
file_var = "GITHUB_ENV" and
cmd = "set-env" and
content = key + "=" + value
or
file_var = "GITHUB_OUTPUT" and
cmd = "set-output" and
content = key + "=" + value
or
file_var = "GITHUB_PATH" and
cmd = "add-path" and
content = value
) and
singleLineWorkflowCmd(script.getAStmt(), cmd, key, value)
)
or
// multiline assignment
exists(string file_expr, string raw_content |
multiLineFileWrite(script.getRawScript(), _, file_expr, raw_content, _) and
isParameterExpansion(file_expr, file_var, _, _) and
content = trimQuotes(raw_content)
)
}
/** Writes the content of the file specified by `path` into a file pointed to by `file_var` */
predicate fileToFileWrite(BashShellScript script, string file_var, string path) {
exists(string regexp, string stmt, string file_expr |
regexp =
"(?i)(cat)\\s*" + "((?:(?!<<|<<-)[^>\n])+)\\s*" +
"(>>|>|\\s*\\|\\s*tee\\s*(-a|--append)?)\\s*" + "(\\S+)" and
stmt = script.getAStmt() and
file_expr = trimQuotes(stmt.regexpCapture(regexp, 5)) and
path = stmt.regexpCapture(regexp, 2) and
containsParameterExpansion(file_expr, file_var, _, _)
)
}
/**
* Holds if the Run scripts contains an access to an environment variable called `var`
* which value may get appended to the GITHUB_XXX special file
*/
predicate envReachingGitHubFileWrite(
BashShellScript script, string var, string file_var, string field
) {
exists(string file_write_value |
(
file_var = "GITHUB_ENV" and
script.getAWriteToGitHubEnv(field, file_write_value)
or
file_var = "GITHUB_OUTPUT" and
script.getAWriteToGitHubOutput(field, file_write_value)
or
file_var = "GITHUB_PATH" and
field = "PATH" and
script.getAWriteToGitHubPath(file_write_value)
) and
envReachingRunExpr(script, var, file_write_value)
)
}
/**
* Holds if and environment variable is used, directly or indirectly, in a Run's step expression.
* Where the expression is a string captured from the Run's script.
*/
bindingset[expr]
predicate envReachingRunExpr(BashShellScript script, string var, string expr) {
exists(string var2, string value2 |
// VAR2=${VAR:-default} (var2=value2)
// echo "FIELD=${VAR2:-default}" >> $GITHUB_ENV (field, file_write_value)
script.getAnAssignment(var2, value2) and
containsParameterExpansion(value2, var, _, _) and
containsParameterExpansion(expr, var2, _, _)
)
or
// var reaches the file write directly
// echo "FIELD=${VAR:-default}" >> $GITHUB_ENV (field, file_write_value)
containsParameterExpansion(expr, var, _, _)
}
/**
* Holds if the Run scripts contains a command substitution (`cmd`)
* which output may get appended to the GITHUB_XXX special file
*/
predicate cmdReachingGitHubFileWrite(
BashShellScript script, string cmd, string file_var, string field
) {
exists(string file_write_value |
(
file_var = "GITHUB_ENV" and
script.getAWriteToGitHubEnv(field, file_write_value)
or
file_var = "GITHUB_OUTPUT" and
script.getAWriteToGitHubOutput(field, file_write_value)
or
file_var = "GITHUB_PATH" and
field = "PATH" and
script.getAWriteToGitHubPath(file_write_value)
) and
cmdReachingRunExpr(script, cmd, file_write_value)
)
}
predicate envReachingArgumentInjectionSink(
BashShellScript script, string source, string command, string argument
) {
exists(string cmd, string regex, int command_group, int argument_group |
cmd = script.getACommand() and
argumentInjectionSinksDataModel(regex, command_group, argument_group) and
argument = cmd.regexpCapture(regex, argument_group).trim() and
command = cmd.regexpCapture(regex, command_group).trim() and
envReachingRunExpr(script, source, argument)
)
}
predicate cmdReachingArgumentInjectionSink(
BashShellScript script, string source, string command, string argument
) {
exists(string cmd, string regex, int command_group, int argument_group |
cmd = script.getACommand() and
argumentInjectionSinksDataModel(regex, command_group, argument_group) and
argument = cmd.regexpCapture(regex, argument_group).trim() and
command = cmd.regexpCapture(regex, command_group).trim() and
cmdReachingRunExpr(script, source, argument)
)
}
/**
* Holds if a command output is used, directly or indirectly, in a Run's step expression.
* Where the expression is a string captured from the Run's script.
*/
bindingset[expr]
predicate cmdReachingRunExpr(BashShellScript script, string cmd, string expr) {
// cmd output is assigned to a second variable (var2) and var2 reaches the file write
exists(string var2, string value2 |
// VAR2=$(cmd)
// echo "FIELD=${VAR2:-default}" >> $GITHUB_ENV (field, file_write_value)
script.getAnAssignment(var2, value2) and
containsCmdSubstitution(value2, cmd) and
containsParameterExpansion(expr, var2, _, _) and
not varMatchesRegexTest(script, var2, alphaNumericRegex())
)
or
// var reaches the file write directly
// echo "FIELD=$(cmd)" >> $GITHUB_ENV (field, file_write_value)
containsCmdSubstitution(expr, cmd)
}
/**
* Holds if there test command that checks a variable against a regex
* eg: `[[ $VAR =~ ^[a-zA-Z0-9_]+$ ]]`
*/
bindingset[var, regex]
predicate varMatchesRegexTest(BashShellScript script, string var, string regex) {
exists(string lhs, string rhs |
lhs = script.getACommand().regexpCapture(".*\\[\\[\\s*(.*?)\\s*=~\\s*(.*?)\\s*\\]\\].*", 1) and
containsParameterExpansion(lhs, var, _, _) and
rhs = script.getACommand().regexpCapture(".*\\[\\[\\s*(.*?)\\s*=~\\s*(.*?)\\s*\\]\\].*", 2) and
trimQuotes(rhs).regexpMatch(regex)
)
}
/**
* Holds if the given regex is used to match an alphanumeric string
* eg: `^[0-9a-zA-Z]{40}$`, `^[0-9]+$` or `^[a-zA-Z0-9_]+$`
*/
string alphaNumericRegex() { result = "^\\^\\[([09azAZ_-]+)\\](\\+|\\{\\d+\\})\\$$" }
}

View File

@@ -1,6 +0,0 @@
/** Provides classes representing the control flow graph. */
private import codeql.actions.controlflow.internal.Cfg as CfgInternal
import CfgInternal::Completion
import CfgInternal::CfgScope
import CfgInternal::CfgImpl

View File

@@ -1 +0,0 @@
import DataFlow::DataFlow::Consistency

View File

@@ -1,22 +0,0 @@
/**
* Provides classes for performing local (intra-procedural) and
* global (inter-procedural) data flow analyses.
*/
import codeql.Locations
module DataFlow {
private import codeql.dataflow.DataFlow
private import codeql.actions.dataflow.internal.DataFlowImplSpecific
import DataFlowMake<Location, ActionsDataFlow>
import codeql.actions.dataflow.internal.DataFlowPublic
// debug
private import codeql.actions.dataflow.internal.TaintTrackingImplSpecific
import codeql.dataflow.internal.DataFlowImplConsistency as DFIC
module ActionsConsistency implements DFIC::InputSig<Location, ActionsDataFlow> { }
module Consistency {
import DFIC::MakeConsistency<Location, ActionsDataFlow, ActionsTaintTracking, ActionsConsistency>
}
}

View File

@@ -1,88 +0,0 @@
private import codeql.actions.Ast
private import codeql.Locations
private import codeql.actions.security.ControlChecks
import codeql.actions.config.Config
import codeql.actions.Bash
import codeql.actions.PowerShell
bindingset[expr]
string normalizeExpr(string expr) {
result =
expr.regexpReplaceAll("\\['([a-zA-Z0-9_\\*\\-]+)'\\]", ".$1")
.regexpReplaceAll("\\[\"([a-zA-Z0-9_\\*\\-]+)\"\\]", ".$1")
.regexpReplaceAll("\\s*\\.\\s*", ".")
}
bindingset[regex]
string wrapRegexp(string regex) { result = "\\b" + regex + "\\b" }
bindingset[regex]
string wrapJsonRegexp(string regex) {
result = ["fromJSON\\(\\s*" + regex + "\\s*\\)", "toJSON\\(\\s*" + regex + "\\s*\\)"]
}
bindingset[str]
string trimQuotes(string str) {
result = str.trim().regexpReplaceAll("^(\"|')", "").regexpReplaceAll("(\"|')$", "")
}
predicate inPrivilegedContext(AstNode node, Event event) {
node.getEnclosingJob().isPrivilegedExternallyTriggerable(event)
}
predicate inNonPrivilegedContext(AstNode node) {
not node.getEnclosingJob().isPrivilegedExternallyTriggerable(_)
}
string defaultBranchNames() {
repositoryDataModel(_, result)
or
not exists(string default_branch_name | repositoryDataModel(_, default_branch_name)) and
result = ["main", "master"]
}
string getRepoRoot() {
exists(Workflow w |
w.getLocation().getFile().getRelativePath().indexOf("/.github/workflows") > 0 and
result =
w.getLocation()
.getFile()
.getRelativePath()
.prefix(w.getLocation().getFile().getRelativePath().indexOf("/.github/workflows") + 1) and
// exclude workflow_enum reusable workflows directory root
not result.indexOf(".github/workflows/external/") > -1 and
not result.indexOf(".github/actions/external/") > -1
or
not w.getLocation().getFile().getRelativePath().indexOf("/.github/workflows") > 0 and
not w.getLocation().getFile().getRelativePath().indexOf(".github/workflows/external/") > -1 and
not w.getLocation().getFile().getRelativePath().indexOf(".github/actions/external/") > -1 and
result = ""
)
}
bindingset[path]
string normalizePath(string path) {
exists(string trimmed_path | trimmed_path = trimQuotes(path) |
// ./foo -> GITHUB_WORKSPACE/foo
if path.indexOf("./") = 0
then result = path.replaceAll("./", "GITHUB_WORKSPACE/")
else
// GITHUB_WORKSPACE/foo -> GITHUB_WORKSPACE/foo
if path.indexOf("GITHUB_WORKSPACE/") = 0
then result = path
else
// foo -> GITHUB_WORKSPACE/foo
if path.regexpMatch("^[^/~].*")
then result = "GITHUB_WORKSPACE/" + path.regexpReplaceAll("/$", "")
else
// ~/foo -> ~/foo
// /foo -> /foo
result = path
)
}
/**
* Holds if the path cache_path is a subpath of the path untrusted_path.
*/
bindingset[subpath, path]
predicate isSubpath(string subpath, string path) { subpath.substring(0, path.length()) = path }

View File

@@ -1,62 +0,0 @@
private import codeql.actions.Ast
class PowerShellScript extends ShellScript {
PowerShellScript() {
exists(Run run |
this = run.getScript() and
run.getShell().matches("pwsh%")
)
}
override string getStmt(int i) { none() }
override string getAStmt() { none() }
override string getCommand(int i) { none() }
override string getACommand() { none() }
override string getFileReadCommand(int i) { none() }
override string getAFileReadCommand() { none() }
override predicate getAssignment(int i, string name, string data) { none() }
override predicate getAnAssignment(string name, string data) { none() }
override predicate getAWriteToGitHubEnv(string name, string data) { none() }
override predicate getAWriteToGitHubOutput(string name, string data) { none() }
override predicate getAWriteToGitHubPath(string data) { none() }
override predicate getAnEnvReachingGitHubOutputWrite(string var, string output_field) { none() }
override predicate getACmdReachingGitHubOutputWrite(string cmd, string output_field) { none() }
override predicate getAnEnvReachingGitHubEnvWrite(string var, string output_field) { none() }
override predicate getACmdReachingGitHubEnvWrite(string cmd, string output_field) { none() }
override predicate getAnEnvReachingGitHubPathWrite(string var) { none() }
override predicate getACmdReachingGitHubPathWrite(string cmd) { none() }
override predicate getAnEnvReachingArgumentInjectionSink(
string var, string command, string argument
) {
none()
}
override predicate getACmdReachingArgumentInjectionSink(
string cmd, string command, string argument
) {
none()
}
override predicate fileToGitHubEnv(string path) { none() }
override predicate fileToGitHubOutput(string path) { none() }
override predicate fileToGitHubPath(string path) { none() }
}

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