Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions .github/scripts/build-codeql-lib-versions-table.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,21 @@ if [ -z "$CODEQL_VERSION" ]; then
exit 1
fi

LANGUAGES=(cpp csharp go java javascript python ruby)
PACKTYPES=(src lib)
LANGUAGES=(actions cpp csharp go java javascript python ruby rust swift)
LIB_LANGUAGES=(cpp csharp go java javascript python ruby)

lang_label() {
case "$1" in
actions) echo "Actions" ;;
cpp) echo "C++" ;;
csharp) echo "C#" ;;
go) echo "Go" ;;
java) echo "Java" ;;
javascript) echo "JavaScript" ;;
python) echo "Python" ;;
ruby) echo "Ruby" ;;
rust) echo "Rust" ;;
swift) echo "Swift" ;;
*) echo "$1" ;;
esac
}
Expand Down Expand Up @@ -127,6 +130,14 @@ upstream_version_and_line() {

MISMATCH=0

is_lib_language() {
local lang="$1"
for supported in "${LIB_LANGUAGES[@]}"; do
[ "$supported" == "$lang" ] && return 0
done
return 1
}

echo "## CodeQL standard library & query pack versions"
echo
echo "Pinned CodeQL CLI/library version ([\`.codeqlversion\`](https://github.com/${REPO}/blob/${REPO_SHA}/.codeqlversion)): [\`v${CODEQL_VERSION}\`](https://github.com/github/codeql-cli-binaries/releases/tag/v${CODEQL_VERSION})"
Expand All @@ -139,7 +150,11 @@ echo "| --- | --- | --- | --- | --- | --- |"
for lang in "${LANGUAGES[@]}"; do
label=$(lang_label "$lang")

for packtype in "${PACKTYPES[@]}"; do
for packtype in src lib; do
if [ "$packtype" == "lib" ] && ! is_lib_language "$lang"; then
echo "| $label | \`$packtype\` | - | n/a | - | n/a |"
continue
fi
qlpackfile="${lang}/${packtype}/qlpack.yml"
lockfile="${lang}/${packtype}/codeql-pack.lock.yml"

Expand Down
22 changes: 20 additions & 2 deletions .github/scripts/build-publish-summary.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,30 @@ else
MERGED=$(jq -s '.' "${FRAGMENTS[@]}")
fi

LANGUAGES=(cpp csharp go java javascript python ruby)
LANGUAGES=(actions cpp csharp go java javascript python ruby rust swift)
TYPES=(src lib ext ext-library-sources)
# Languages with a published `lib` pack - the remaining languages currently
# have no shared library use cases and should not produce empty placeholder packs.
LIB_LANGUAGES=(cpp csharp go java javascript python ruby)
# Languages with an `ext` (model/extension) pack - matches the `extensions` job's matrix.
EXT_LANGUAGES=(csharp go java python)
EXT_LANGUAGES=(csharp go java python rust)
# Languages with an `ext-library-sources` pack - matches the `library_sources_extensions`
# job's matrix. This is a strict subset of EXT_LANGUAGES: go/python ship `ext` packs but
# have no `ext-library-sources` pack, so they must not be expected to have a result for it.
EXT_LIBRARY_SOURCES_LANGUAGES=(csharp java)

lang_label() {
case "$1" in
actions) echo "Actions" ;;
cpp) echo "C++" ;;
csharp) echo "C#" ;;
go) echo "Go" ;;
java) echo "Java" ;;
javascript) echo "JavaScript" ;;
python) echo "Python" ;;
ruby) echo "Ruby" ;;
rust) echo "Rust" ;;
swift) echo "Swift" ;;
*) echo "$1" ;;
esac
}
Expand All @@ -64,6 +70,14 @@ is_ext_language() {
return 1
}

is_lib_language() {
local lang="$1"
for l in "${LIB_LANGUAGES[@]}"; do
[ "$l" == "$lang" ] && return 0
done
return 1
}

is_ext_library_sources_language() {
local lang="$1"
for l in "${EXT_LIBRARY_SOURCES_LANGUAGES[@]}"; do
Expand Down Expand Up @@ -163,6 +177,10 @@ for lang in "${LANGUAGES[@]}"; do
row="$row n/a |"
continue
fi
if [ "$type" == "lib" ] && ! is_lib_language "$lang"; then
row="$row n/a |"
continue
fi
if [ "$type" == "ext-library-sources" ] && ! is_ext_library_sources_language "$lang"; then
row="$row n/a |"
continue
Expand Down
8 changes: 4 additions & 4 deletions .github/scripts/pr-compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ run_lenient_full_compile() {
# all of them at once. Failing on that backlog would block CI-infra validation
# (workflow_dispatch, or a PR that only touches .github/**) on unrelated debt.
echo "[+] Compiling all queries in $LANGUAGE"
codeql query compile --threads=0 --check-only "./$LANGUAGE/"
codeql query compile --additional-packs "$LANGUAGE" --threads=0 --check-only "./$LANGUAGE/"
}

run_strict_full_compile() {
echo "[+] Compiling all queries in $LANGUAGE (strict)"
codeql query compile --threads=0 --check-only --warnings=error "./$LANGUAGE/"
codeql query compile --additional-packs "$LANGUAGE" --threads=0 --check-only --warnings=error "./$LANGUAGE/"
}

if [[ -z "$PR_NUMBER" ]]; then
Expand Down Expand Up @@ -74,7 +74,7 @@ if [[ "$WORKFLOW_CHANGED" == true ]]; then
continue
fi
echo "[+] Compiling $file (in $LANGUAGE)"
codeql query compile --threads=0 --check-only --warnings=error "./$file"
codeql query compile --additional-packs "$LANGUAGE" --threads=0 --check-only --warnings=error "./$file"
done
echo "[+] Complete"
exit 0
Expand All @@ -92,7 +92,7 @@ for file in "${TOUCHED_QUERIES[@]}"; do
continue
fi
echo "[+] Compiling $file (in $LANGUAGE)"
codeql query compile --threads=0 --check-only --warnings=error "./$file"
codeql query compile --additional-packs "$LANGUAGE" --threads=0 --check-only --warnings=error "./$file"
done

echo "[+] Complete"
14 changes: 7 additions & 7 deletions .github/scripts/pr-suites-packs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if [[ -z "$PR_NUMBER" ]]; then
if [[ -d "$LANGUAGE/suites" ]]; then
while IFS= read -r -d '' suite; do
echo "[+] Compiling Suite: $suite"
codeql resolve queries "$suite"
codeql resolve queries --additional-packs "$LANGUAGE" "$suite"
done < <(find "$LANGUAGE/suites" -name '*.qls' -print0)
fi

Expand All @@ -30,9 +30,9 @@ if [[ -z "$PR_NUMBER" ]]; then
# extension in the pack (a known CodeQL CLI bug, see
# https://github.com/github/codeql/issues/20211). See CONTRIBUTING.md.
if [[ "$pack_dir" != "$LANGUAGE/ext" && "$pack_dir" != "$LANGUAGE/ext-library-sources" ]]; then
codeql pack install "$pack_dir"
codeql pack install --additional-packs "$LANGUAGE" "$pack_dir"
fi
codeql pack create "$pack_dir"
codeql pack create --additional-packs "$LANGUAGE" "$pack_dir"
fi
done

Expand All @@ -48,7 +48,7 @@ for file in $(gh pr view "$PR_NUMBER" --json files --jq '.files.[].path'); do
# suite folder
if [[ "$file" == $LANGUAGE/suites/**.qls ]]; then
echo "[+] Compiling Suite: $file"
codeql resolve queries "$file"
codeql resolve queries --additional-packs "$LANGUAGE" "$file"

# qlpack file and lock file
elif [[ "$file" == $LANGUAGE/qlpack.yml ]] || [[ "$file" == $LANGUAGE/codeql-pack.lock.yml ]]; then
Expand All @@ -57,9 +57,9 @@ for file in $(gh pr view "$PR_NUMBER" --json files --jq '.files.[].path'); do
fi
echo "[+] Compiling Pack: $LANGUAGE"
# install deps
codeql pack install "$LANGUAGE"
codeql pack install --additional-packs "$LANGUAGE" "$LANGUAGE"
# compile / create pack
codeql pack create "$LANGUAGE"
codeql pack create --additional-packs "$LANGUAGE" "$LANGUAGE"

# if the version of the pack is changed, comment in the PR
PUBLISHED_VERSION=$(gh api /orgs/githubsecuritylab/packages/container/codeql-"$LANGUAGE"-queries/versions --jq '.[0].metadata.container.tags[0]')
Expand All @@ -75,7 +75,7 @@ for file in $(gh pr view "$PR_NUMBER" --json files --jq '.files.[].path'); do
fi
fi

# Same for the libs pack
# Same for the libs pack, when this language has one
PUBLISHED_VERSION=$(gh api /orgs/githubsecuritylab/packages/container/codeql-"$LANGUAGE"-libs/versions --jq '.[0].metadata.container.tags[0]')
CURRENT_VERSION=$(grep version "$LANGUAGE"/lib/qlpack.yml | awk '{print $2}')

Expand Down
18 changes: 11 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
language: [ 'actions', 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'rust', 'swift' ]

steps:
- uses: actions/checkout@v7
Expand Down Expand Up @@ -50,9 +50,13 @@ jobs:
CODEQL_CLI_VERSION: ${{ steps.install-codeql.outputs.codeql-cli-version }}
run: |
gh repo clone github/codeql -- -b codeql-cli-${CODEQL_CLI_VERSION} # to make stubs available for tests
codeql pack install "${{ matrix.language }}/lib"
codeql pack install "${{ matrix.language }}/src"
codeql pack install "${{ matrix.language }}/test"
# Resolve this language's local query/library/extension packs before GHCR so
# tests can use packs that have not been published yet.
if [[ -f "${{ matrix.language }}/lib/qlpack.yml" ]]; then
codeql pack install --additional-packs "$GITHUB_WORKSPACE/${{ matrix.language }}" "${{ matrix.language }}/lib"
fi
codeql pack install --additional-packs "$GITHUB_WORKSPACE/${{ matrix.language }}" "${{ matrix.language }}/src"
codeql pack install --additional-packs "$GITHUB_WORKSPACE/${{ matrix.language }}" "${{ matrix.language }}/test"

- name: Compile Queries
if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
Expand Down Expand Up @@ -168,7 +172,7 @@ jobs:
# JVMs start at once, and their /tmp/hsperfdata_<user>/<pid> files can collide
# ("Cannot use file ... locked by another process"), corrupting the report.
# -XX:-UsePerfData stops the JVM from creating those files at all.
procs.append((subprocess.Popen(["codeql", "test", "run", "-J=-XX:-UsePerfData", "--failing-exitcode=122", "--verbosity=progress", "--ram=2048", "--format=json", *extra_args], stdout=test_report_file, stderr=test_log_file), test_log_path))
procs.append((subprocess.Popen(["codeql", "test", "run", "--additional-packs", language, "-J=-XX:-UsePerfData", "--failing-exitcode=122", "--verbosity=progress", "--ram=2048", "--format=json", *extra_args], stdout=test_report_file, stderr=test_log_file), test_log_path))

for p, test_log_path in procs:
p.wait()
Expand Down Expand Up @@ -262,7 +266,7 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'csharp', 'go', 'java', 'python' ]
language: [ 'csharp', 'go', 'java', 'python', 'rust' ]

steps:
- uses: actions/checkout@v7
Expand Down Expand Up @@ -355,7 +359,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
for lang in cpp csharp go java javascript python ruby; do
for lang in actions cpp csharp go java javascript python ruby rust swift; do
if [[ -d "${lang}/src" ]]; then
codeql pack install "${lang}/src"
fi
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,18 @@ jobs:
# hole before running `codeql pack install` and immediately finding/
# fixing the real one-line bug.
#
# We install every pack (not just the language the agent will end up
# We install every dependency-bearing pack (not just the language the agent will end up
# touching) because we don't know ahead of time which one it'll be
# asked to fix - the extra cost is a few seconds per pack, which is
# trivial next to the minutes it can save. Same exclude list as
# update-codeql-version.yml's `codeql pack upgrade` loop: skip
# ql/hotspots (standalone tool, not a real GHCR-resolvable pack),
# codeql_home (vendored CLI packs), and codeql/ + */.codeql (the test-
# stubs clone below and CodeQL's own per-pack build caches).
for dir in $(find . -name qlpack.yml -not -path "./ql/hotspots/*" -not -path "./codeql_home/*" -not -path "./codeql/*" -not -path "*/.codeql/*" -exec dirname {} \;); do
# stubs clone below and CodeQL's own per-pack build caches). Model/extension
# packs are also skipped because they must not be installed or have lockfiles.
for dir in $(find . -name qlpack.yml -not -path "./ql/hotspots/*" -not -path "./codeql_home/*" -not -path "./codeql/*" -not -path "*/.codeql/*" -not -path "*/ext/*" -not -path "*/ext-library-sources/*" -exec dirname {} \;); do
echo "::group::codeql pack install $dir"
codeql pack install "$dir"
codeql pack install --additional-packs "$(dirname "$dir")" "$dir"
echo "::endgroup::"
done

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
strategy:
fail-fast: false
matrix:
language: ["cpp", "csharp", "go", "java", "javascript", "python", "ruby"]
language: ["actions", "cpp", "csharp", "go", "java", "javascript", "python", "ruby", "rust", "swift"]

steps:
- uses: actions/checkout@v7
Expand Down Expand Up @@ -211,7 +211,7 @@ jobs:
strategy:
fail-fast: false
matrix:
language: ["csharp", "go", "java", "python"]
language: ["csharp", "go", "java", "python", "rust"]

steps:
- uses: actions/checkout@v7
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-codeql-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ jobs:
# GitHubSecurityLab/CodeQL-Community-Packs#206.
for dir in $(find . -name qlpack.yml -not -path "./ql/hotspots/*" -not -path "./codeql_home/*" -not -path "./codeql/*" -not -path "*/.codeql/*" -not -path "*/ext/*" -not -path "*/ext-library-sources/*" -exec dirname {} \;); do
echo "::group::codeql pack upgrade $dir"
codeql pack upgrade "$dir"
codeql pack upgrade --additional-packs "$(dirname "$dir")" "$dir"
echo "::endgroup::"
done

Expand Down
40 changes: 23 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@ There is lots of useful documentation to help you write queries, ranging from in

## Submitting a new query

If you have an idea for a query that you would like to share with other CodeQL users, please open a pull request to add it to this repository. New queries start out in a `<language>/ql/src/` directory, to which they can be merged when they meet the following requirements.
If you have an idea for a query that you would like to share with other CodeQL users, please open a pull request to add it to this repository. New queries start out in a `<language>/src/` directory, to which they can be merged when they meet the following requirements.

1. **Directory structure**

There are eight language-specific query directories in this repository:
Query packs are available for the following CodeQL languages:

* C/C++: `cpp/ql/src`
* C#: `csharp/ql/src`
* Go: `go/ql/src`
* Java/Kotlin: `java/ql/src`
* JavaScript: `javascript/ql/src`
* Python: `python/ql/src`
* Ruby: `ruby/ql/src`
* Swift: `swift/ql/src`
* GitHub Actions: `actions/src`
* C/C++: `cpp/src`
* C#: `csharp/src`
* Go: `go/src`
* Java/Kotlin: `java/src`
* JavaScript/TypeScript: `javascript/src`
* Python: `python/src`
* Ruby: `ruby/src`
* Rust: `rust/src`
* Swift: `swift/src`

Each language-specific directory contains further subdirectories that group queries based on their `@tags` or purpose.

Expand Down Expand Up @@ -71,7 +73,7 @@ instead of, or alongside, a query change.
1. **Pick the right pack: `ext` vs `ext-library-sources`**

Every language with data-extension support has a `<language>/ext` pack (`csharp`/`go`/`java`/
`python`). Two of those languages additionally have a second, narrower pack,
`python`/`rust`). Two of those languages additionally have a second, narrower pack,
`<language>/ext-library-sources` (`csharp`/`java` only). They hold different *kinds* of models,
and picking the right one matters:

Expand All @@ -82,7 +84,8 @@ instead of, or alongside, a query change.
well-known framework API (e.g. a web framework's `getParameter()`-style methods). This is
where our own [Spring R2DBC `DatabaseClient` SQL injection sink models][pr-204] live
(`java/ext/manual/org.springframework.r2dbc.model.yml`) — use it as a concrete reference for
both the file layout and the row shape.
both the file layout and the row shape. For example, Rust models for Diesel SQL sinks belong
in `rust/ext/manual/diesel.model.yml`.
- **`<language>/ext-library-sources`** (published as
`githubsecuritylab/codeql-<language>-library-sources`) exists only for `csharp`/`java` and
holds a narrower category: `sourceModel` rows (almost always `kind: "remote"`) that flag a
Expand All @@ -96,7 +99,8 @@ instead of, or alongside, a query change.

**Rule of thumb: if you're modeling a dangerous sink, or how taint flows through a library
method, use `ext`. Only reach for `ext-library-sources` if you're contributing a genuinely new
remote-data-entry-point (source) model, and only for csharp/java.**
remote-data-entry-point (source) model, and only for csharp/java. Do not add an empty
`ext-library-sources` pack for other languages.**

2. **Row shape**

Expand Down Expand Up @@ -135,8 +139,9 @@ instead of, or alongside, a query change.
Add a test under `<language>/test/security/<CWE-id>/<your-library>/`: minimal source stubs that
reproduce the vulnerable call shape, a `.ql` query that imports the *real* standard query (e.g.
`SqlInjectionQuery`/`QueryInjectionFlow`, not a reimplementation of it), and a `.expected` file.
Check that `<language>/test/qlpack.yml` depends on `githubsecuritylab/codeql-<language>-extensions`
(and `-library-sources` where applicable) — that dependency is what makes `codeql test run`'s
If the language has an `ext` pack, check that `<language>/test/qlpack.yml` depends on
`githubsecuritylab/codeql-<language>-extensions` (and `-library-sources` where applicable) —
that dependency is what makes `codeql test run`'s
normal dependency resolution load your data extensions automatically, unlike ad-hoc `codeql
database analyze`/`query run`, which need an explicit `--model-packs` flag. Add the dependency if
it's missing. Confirm the test actually exercises your model (not just that it compiles) by
Expand Down Expand Up @@ -308,7 +313,7 @@ process for each; most of it is manual today.
[`publish.yml`][publish-workflow] is organized as five jobs: four publish jobs, one per pack type
(`queries` for `src`, `library` for `lib`, `extensions` for `ext`, `library_sources_extensions` for
`ext-library-sources`), each matrixed over every language that has that pack type
(`ext` runs for `csharp`/`go`/`java`/`python`; `ext-library-sources` only runs for `csharp`/`java`, the only languages with that pack) - plus a fifth
(`src` includes Actions, Rust, and Swift; `lib` is only created where there is shared library code; `ext` runs for `csharp`/`go`/`java`/`python`/`rust`; `ext-library-sources` only runs for `csharp`/`java`, the only languages with that pack) - plus a fifth
`summary` job that runs after the other four (`if: always()`, so it still runs even if one of them
fails), aggregates their per-pack results into the publish-summary and CodeQL library/query pack
version tables, and (on the release-cut `push` trigger only) upserts both tables into the GitHub
Expand Down Expand Up @@ -344,7 +349,8 @@ merge. Bumping your pack's own `version:` in a regular PR just *stages* the chan
To ship a change:

- [ ] Make your change in the pack directory you intend to publish: `<language>/src` (queries),
`<language>/lib` (library), `<language>/ext` (extensions, `csharp`/`go`/`java`/`python` only),
`<language>/lib` (shared library code, only where needed), `<language>/ext` (extensions,
`csharp`/`go`/`java`/`python`/`rust`),
or `<language>/ext-library-sources` (extensions, `csharp`/`java` only). See [Adding a data
extension](#adding-a-data-extension) above if you're not sure which extensions pack to use.
- [ ] Bump `version:` in that pack's `qlpack.yml`, following [semver](https://semver.org/). Only bump
Expand Down
Loading
Loading