mirror of
https://github.com/github/codeql-action.git
synced 2025-12-06 15:58:06 +08:00
Compare commits
46 Commits
codeql-bun
...
v2.1.13
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d00e8c09a3 | ||
|
|
8bd4419d1e | ||
|
|
31367d4e57 | ||
|
|
ccf5d70ab3 | ||
|
|
30fe0a56d2 | ||
|
|
7adb33da1d | ||
|
|
2e111b27f7 | ||
|
|
c7785f6b91 | ||
|
|
2e80c74b1b | ||
|
|
80ecdcdf69 | ||
|
|
7c412c67ba | ||
|
|
ee4575b213 | ||
|
|
d2ab7a2abb | ||
|
|
d7459f0368 | ||
|
|
6db77eec0d | ||
|
|
777b778409 | ||
|
|
97f9db4fb9 | ||
|
|
59ca9b59cb | ||
|
|
6834383903 | ||
|
|
4918636a75 | ||
|
|
428caf0cf5 | ||
|
|
df05122fc6 | ||
|
|
a27dc4fee4 | ||
|
|
a568674c69 | ||
|
|
f8f4c0b33e | ||
|
|
79d8e4a43d | ||
|
|
0ece1d1000 | ||
|
|
81b419c908 | ||
|
|
eec34d5f05 | ||
|
|
06e27d3e3d | ||
|
|
40b280032c | ||
|
|
bcb7fad5b3 | ||
|
|
0efcf74ce0 | ||
|
|
29a2159db1 | ||
|
|
f7c46e5cbc | ||
|
|
ccf479d336 | ||
|
|
1b5ea4afdc | ||
|
|
69e09909dc | ||
|
|
632cc8efb3 | ||
|
|
57096f1d43 | ||
|
|
27ea8f8fe5 | ||
|
|
3f00a1265f | ||
|
|
dbe6f211e6 | ||
|
|
16c620dea4 | ||
|
|
b36688d5b7 | ||
|
|
bfe9d7da56 |
20
.github/check-sarif/action.yml
vendored
Normal file
20
.github/check-sarif/action.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: Check SARIF
|
||||
description: Checks a SARIF file to see if certain queries were run and others were not run.
|
||||
inputs:
|
||||
sarif-file:
|
||||
required: true
|
||||
description: The SARIF file to check
|
||||
|
||||
queries-run:
|
||||
required: true
|
||||
description: |
|
||||
Comma separated list of query ids that should be included in this SARIF file.
|
||||
|
||||
queries-not-run:
|
||||
required: true
|
||||
description: |
|
||||
Comma separated list of query ids that should NOT be included in this SARIF file.
|
||||
|
||||
runs:
|
||||
using: node12
|
||||
main: index.js
|
||||
43
.github/check-sarif/index.js
vendored
Normal file
43
.github/check-sarif/index.js
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
'use strict'
|
||||
|
||||
const core = require('@actions/core')
|
||||
const fs = require('fs')
|
||||
|
||||
const sarif = JSON.parse(fs.readFileSync(core.getInput('sarif-file'), 'utf8'))
|
||||
const rules = sarif.runs[0].tool.extensions.flatMap(ext => ext.rules || [])
|
||||
const ruleIds = rules.map(rule => rule.id)
|
||||
|
||||
// Check that all the expected queries ran
|
||||
const expectedQueriesRun = getQueryIdsInput('queries-run')
|
||||
const queriesThatShouldHaveRunButDidNot = expectedQueriesRun.filter(queryId => !ruleIds.includes(queryId))
|
||||
|
||||
if (queriesThatShouldHaveRunButDidNot.length > 0) {
|
||||
core.setFailed(`The following queries were expected to run but did not: ${queriesThatShouldHaveRunButDidNot.join(', ')}`)
|
||||
}
|
||||
|
||||
// Check that all the unexpected queries did not run
|
||||
const expectedQueriesNotRun = getQueryIdsInput('queries-not-run')
|
||||
|
||||
const queriesThatShouldNotHaveRunButDid = expectedQueriesNotRun.filter(queryId => ruleIds.includes(queryId))
|
||||
|
||||
if (queriesThatShouldNotHaveRunButDid.length > 0) {
|
||||
core.setFailed(`The following queries were NOT expected to have run but did: ${queriesThatShouldNotHaveRunButDid.join(', ')}`)
|
||||
}
|
||||
|
||||
|
||||
core.startGroup('All queries run')
|
||||
rules.forEach(rule => {
|
||||
core.info(`${rule.id}: ${(rule.properties && rule.properties.name) || rule.name}`)
|
||||
})
|
||||
core.endGroup()
|
||||
|
||||
core.startGroup('Full SARIF')
|
||||
core.info(JSON.stringify(sarif, null, 2))
|
||||
core.endGroup()
|
||||
|
||||
function getQueryIdsInput(name) {
|
||||
return core.getInput(name)
|
||||
.split(',')
|
||||
.map(q => q.trim())
|
||||
.filter(q => q.length > 0)
|
||||
}
|
||||
52
.github/query-filter-test/action.yml
vendored
Normal file
52
.github/query-filter-test/action.yml
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
name: Query Filter Test
|
||||
description: Runs a test of query filters using the check SARIF action
|
||||
inputs:
|
||||
sarif-file:
|
||||
required: true
|
||||
description: The SARIF file to check
|
||||
|
||||
queries-run:
|
||||
required: true
|
||||
description: |
|
||||
Comma separated list of query ids that should be included in this SARIF file.
|
||||
|
||||
queries-not-run:
|
||||
required: true
|
||||
description: |
|
||||
Comma separated list of query ids that should NOT be included in this SARIF file.
|
||||
|
||||
config-file:
|
||||
required: true
|
||||
description: |
|
||||
The location of the codeql configuration file to use.
|
||||
|
||||
tools:
|
||||
required: true
|
||||
description: |
|
||||
The url of codeql to use.
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
languages: javascript
|
||||
config-file: ${{ inputs.config-file }}
|
||||
tools: ${{ inputs.tools }}
|
||||
db-location: ${{ runner.temp }}/query-filter-test
|
||||
- uses: ./../action/analyze
|
||||
with:
|
||||
output: ${{ runner.temp }}/results
|
||||
upload-database: false
|
||||
upload: false
|
||||
env:
|
||||
TEST_MODE: "true"
|
||||
- name: Check SARIF
|
||||
uses: ./../action/.github/check-sarif
|
||||
with:
|
||||
sarif-file: ${{ inputs.sarif-file }}
|
||||
queries-run: ${{ inputs.queries-run}}
|
||||
queries-not-run: ${{ inputs.queries-not-run}}
|
||||
- name: Cleanup after test
|
||||
shell: bash
|
||||
run: rm -rf "$RUNNER_TEMP/results" "$RUNNER_TEMP//query-filter-test"
|
||||
47
.github/workflows/expected-queries-runs.yml
vendored
Normal file
47
.github/workflows/expected-queries-runs.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
name: Check queries that ran
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- releases/v1
|
||||
- releases/v2
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
workflow_dispatch: {}
|
||||
|
||||
jobs:
|
||||
expected-queries:
|
||||
name: Expected Queries Tests
|
||||
timeout-minutes: 45
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Prepare test
|
||||
id: prepare-test
|
||||
uses: ./.github/prepare-test
|
||||
with:
|
||||
version: latest
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
languages: javascript
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
- uses: ./../action/analyze
|
||||
with:
|
||||
output: ${{ runner.temp }}/results
|
||||
upload-database: false
|
||||
upload: false
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
- name: Check Sarif
|
||||
uses: ./../action/.github/check-sarif
|
||||
with:
|
||||
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||
queries-run: js/incomplete-hostname-regexp,js/path-injection
|
||||
queries-not-run: foo,bar
|
||||
56
.github/workflows/query-filters.yml
vendored
Normal file
56
.github/workflows/query-filters.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: Query filters tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- releases/v1
|
||||
- releases/v2
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
workflow_dispatch: {}
|
||||
|
||||
jobs:
|
||||
query-filters:
|
||||
name: Query Filters Tests
|
||||
timeout-minutes: 45
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Prepare test
|
||||
id: prepare-test
|
||||
uses: ./.github/prepare-test
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Check SARIF for default queries with Single include, Single exclude
|
||||
uses: ./../action/.github/query-filter-test
|
||||
with:
|
||||
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||
queries-run: js/zipslip
|
||||
queries-not-run: js/path-injection
|
||||
config-file: ./.github/codeql/codeql-config-query-filters1.yml
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
|
||||
- name: Check SARIF for query packs with Single include, Single exclude
|
||||
uses: ./../action/.github/query-filter-test
|
||||
with:
|
||||
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||
queries-run: js/zipslip,javascript/example/empty-or-one-block
|
||||
queries-not-run: js/path-injection
|
||||
config-file: ./.github/codeql/codeql-config-query-filters2.yml
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
|
||||
- name: Check SARIF for query packs and local queries with Single include, Single exclude
|
||||
uses: ./../action/.github/query-filter-test
|
||||
with:
|
||||
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||
queries-run: js/zipslip,javascript/example/empty-or-one-block,inrepo-javascript-querypack/show-ifs
|
||||
queries-not-run: js/path-injection,complex-python-querypack/show-ifs,complex-python-querypack/foo/bar/show-ifs
|
||||
config-file: ./.github/codeql/codeql-config-query-filters3.yml
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
@@ -21,7 +21,7 @@ fi
|
||||
echo "Getting checks for $GITHUB_SHA"
|
||||
|
||||
# Ignore any checks with "https://", CodeQL, LGTM, and Update checks.
|
||||
CHECKS="$(gh api repos/github/codeql-action/commits/${GITHUB_SHA}/check-runs --paginate | jq --slurp --compact-output --raw-output '[.[].check_runs | .[].name | select(contains("https://") or . == "CodeQL" or . == "LGTM.com" or contains("Update") | not)] | sort')"
|
||||
CHECKS="$(gh api repos/github/codeql-action/commits/${GITHUB_SHA}/check-runs --paginate | jq --slurp --compact-output --raw-output '[.[].check_runs | .[].name | select(contains("https://") or . == "CodeQL" or . == "LGTM.com" or contains("Update") | not)] | unique | sort')"
|
||||
|
||||
echo "$CHECKS" | jq
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
# CodeQL Action Changelog
|
||||
|
||||
## [UNRELEASED]
|
||||
## 2.1.13 - 21 Jun 2022
|
||||
|
||||
No user facing changes.
|
||||
- Add the ability to filter queries from a code scanning run by using the `query-filters` option in the code scanning configuration file. [#1098](https://github.com/github/codeql-action/pull/1098)
|
||||
- Update default CodeQL bundle version to 2.9.4. [#1100](https://github.com/github/codeql-action/pull/1100)
|
||||
|
||||
## 2.1.12 - 01 Jun 2022
|
||||
|
||||
- Update default CodeQL bundle version to 2.9.3. [#1084](https://github.com/github/codeql-action/pull/1084)
|
||||
|
||||
## 2.1.11 - 17 May 2022
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
78
lib/analyze.js
generated
78
lib/analyze.js
generated
@@ -18,14 +18,19 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runCleanup = exports.runFinalize = exports.runQueries = exports.CodeQLAnalysisError = void 0;
|
||||
exports.validateQueryFilters = exports.runCleanup = exports.runFinalize = exports.createQuerySuiteContents = exports.convertPackToQuerySuiteEntry = exports.runQueries = exports.CodeQLAnalysisError = void 0;
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const del_1 = __importDefault(require("del"));
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
const analysisPaths = __importStar(require("./analysis-paths"));
|
||||
const codeql_1 = require("./codeql");
|
||||
const configUtils = __importStar(require("./config-utils"));
|
||||
const count_loc_1 = require("./count-loc");
|
||||
const languages_1 = require("./languages");
|
||||
const sharedEnv = __importStar(require("./shared-environment"));
|
||||
@@ -124,6 +129,7 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
|
||||
}
|
||||
for (const language of config.languages) {
|
||||
const queries = config.queries[language];
|
||||
const queryFilters = validateQueryFilters(config.originalUserInput["query-filters"]);
|
||||
const packsWithVersion = config.packs[language] || [];
|
||||
const hasBuiltinQueries = (queries === null || queries === void 0 ? void 0 : queries.builtin.length) > 0;
|
||||
const hasCustomQueries = (queries === null || queries === void 0 ? void 0 : queries.custom.length) > 0;
|
||||
@@ -146,7 +152,7 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
|
||||
const querySuitePaths = [];
|
||||
if (queries["builtin"].length > 0) {
|
||||
const startTimeBuiltIn = new Date().getTime();
|
||||
querySuitePaths.push(await runQueryGroup(language, "builtin", createQuerySuiteContents(queries["builtin"]), undefined));
|
||||
querySuitePaths.push(await runQueryGroup(language, "builtin", createQuerySuiteContents(queries["builtin"], queryFilters), undefined));
|
||||
statusReport[`analyze_builtin_queries_${language}_duration_ms`] =
|
||||
new Date().getTime() - startTimeBuiltIn;
|
||||
}
|
||||
@@ -154,12 +160,12 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
|
||||
let ranCustom = false;
|
||||
for (let i = 0; i < queries["custom"].length; ++i) {
|
||||
if (queries["custom"][i].queries.length > 0) {
|
||||
querySuitePaths.push(await runQueryGroup(language, `custom-${i}`, createQuerySuiteContents(queries["custom"][i].queries), queries["custom"][i].searchPath));
|
||||
querySuitePaths.push(await runQueryGroup(language, `custom-${i}`, createQuerySuiteContents(queries["custom"][i].queries, queryFilters), queries["custom"][i].searchPath));
|
||||
ranCustom = true;
|
||||
}
|
||||
}
|
||||
if (packsWithVersion.length > 0) {
|
||||
querySuitePaths.push(...(await runQueryPacks(language, "packs", packsWithVersion, undefined)));
|
||||
querySuitePaths.push(await runQueryPacks(language, "packs", packsWithVersion, queryFilters));
|
||||
ranCustom = true;
|
||||
}
|
||||
if (ranCustom) {
|
||||
@@ -217,23 +223,41 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
|
||||
logger.debug(`BQRS results produced for ${language} (queries: ${type})"`);
|
||||
return querySuitePath;
|
||||
}
|
||||
async function runQueryPacks(language, type, packs, searchPath) {
|
||||
async function runQueryPacks(language, type, packs, queryFilters) {
|
||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||
// Run the queries individually instead of all at once to avoid command
|
||||
// line length restrictions, particularly on windows.
|
||||
for (const pack of packs) {
|
||||
logger.debug(`Running query pack for ${language}-${type}: ${pack}`);
|
||||
const codeql = await (0, codeql_1.getCodeQL)(config.codeQLCmd);
|
||||
await codeql.databaseRunQueries(databasePath, searchPath, pack, memoryFlag, threadsFlag);
|
||||
logger.debug(`BQRS results produced for ${language} (queries: ${type})"`);
|
||||
}
|
||||
return packs;
|
||||
// combine the list of packs into a query suite in order to run them all simultaneously.
|
||||
const querySuite = packs.map(convertPackToQuerySuiteEntry).concat(queryFilters);
|
||||
const querySuitePath = `${databasePath}-queries-${type}.qls`;
|
||||
fs.writeFileSync(querySuitePath, yaml.dump(querySuite));
|
||||
logger.debug(`BQRS results produced for ${language} (queries: ${type})"`);
|
||||
const codeql = await (0, codeql_1.getCodeQL)(config.codeQLCmd);
|
||||
await codeql.databaseRunQueries(databasePath, undefined, querySuitePath, memoryFlag, threadsFlag);
|
||||
return querySuitePath;
|
||||
}
|
||||
}
|
||||
exports.runQueries = runQueries;
|
||||
function createQuerySuiteContents(queries) {
|
||||
return queries.map((q) => `- query: ${q}`).join("\n");
|
||||
function convertPackToQuerySuiteEntry(packStr) {
|
||||
var _a, _b, _c, _d;
|
||||
const pack = configUtils.parsePacksSpecification(packStr);
|
||||
return {
|
||||
qlpack: !pack.path ? pack.name : undefined,
|
||||
from: pack.path ? pack.name : undefined,
|
||||
version: pack.version,
|
||||
query: ((_a = pack.path) === null || _a === void 0 ? void 0 : _a.endsWith(".ql")) ? pack.path : undefined,
|
||||
queries: !((_b = pack.path) === null || _b === void 0 ? void 0 : _b.endsWith(".ql")) && !((_c = pack.path) === null || _c === void 0 ? void 0 : _c.endsWith(".qls"))
|
||||
? pack.path
|
||||
: undefined,
|
||||
apply: ((_d = pack.path) === null || _d === void 0 ? void 0 : _d.endsWith(".qls")) ? pack.path : undefined,
|
||||
};
|
||||
}
|
||||
exports.convertPackToQuerySuiteEntry = convertPackToQuerySuiteEntry;
|
||||
function createQuerySuiteContents(queries, queryFilters) {
|
||||
return yaml.dump(queries.map((q) => ({ query: q })).concat(queryFilters));
|
||||
}
|
||||
exports.createQuerySuiteContents = createQuerySuiteContents;
|
||||
async function runFinalize(outputDir, threadsFlag, memoryFlag, config, logger) {
|
||||
const codeql = await (0, codeql_1.getCodeQL)(config.codeQLCmd);
|
||||
if (await util.codeQlVersionAbove(codeql, codeql_1.CODEQL_VERSION_NEW_TRACING)) {
|
||||
@@ -244,13 +268,8 @@ async function runFinalize(outputDir, threadsFlag, memoryFlag, config, logger) {
|
||||
// Delete the tracer config env var to avoid tracing ourselves
|
||||
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
|
||||
}
|
||||
// After switching to Node16, this entire block can be replaced with `await fs.promises.rm(outputDir, { recursive: true, force: true });`.
|
||||
try {
|
||||
await fs.promises.rmdir(outputDir, {
|
||||
recursive: true,
|
||||
maxRetries: 5,
|
||||
retryDelay: 2000,
|
||||
});
|
||||
await (0, del_1.default)(outputDir, { force: true });
|
||||
}
|
||||
catch (error) {
|
||||
if ((error === null || error === void 0 ? void 0 : error.code) !== "ENOENT") {
|
||||
@@ -299,4 +318,25 @@ function printLinesOfCodeSummary(logger, language, lineCounts) {
|
||||
logger.info(`Counted a baseline of ${lineCounts[language]} lines of code for ${language}.`);
|
||||
}
|
||||
}
|
||||
// exported for testing
|
||||
function validateQueryFilters(queryFilters) {
|
||||
if (!queryFilters) {
|
||||
return [];
|
||||
}
|
||||
const errors = [];
|
||||
for (const qf of queryFilters) {
|
||||
const keys = Object.keys(qf);
|
||||
if (keys.length !== 1) {
|
||||
errors.push(`Query filter must have exactly one key: ${JSON.stringify(qf)}`);
|
||||
}
|
||||
if (!["exclude", "include"].includes(keys[0])) {
|
||||
errors.push(`Only "include" or "exclude" filters are allowed:\n${JSON.stringify(qf)}`);
|
||||
}
|
||||
}
|
||||
if (errors.length) {
|
||||
throw new Error(`Invalid query filter.\n${errors.join("\n")}`);
|
||||
}
|
||||
return queryFilters;
|
||||
}
|
||||
exports.validateQueryFilters = validateQueryFilters;
|
||||
//# sourceMappingURL=analyze.js.map
|
||||
File diff suppressed because one or more lines are too long
132
lib/analyze.test.js
generated
132
lib/analyze.test.js
generated
@@ -210,4 +210,136 @@ const util = __importStar(require("./util"));
|
||||
}
|
||||
}
|
||||
});
|
||||
(0, ava_1.default)("validateQueryFilters", (t) => {
|
||||
t.notThrows(() => (0, analyze_1.validateQueryFilters)([]));
|
||||
t.notThrows(() => (0, analyze_1.validateQueryFilters)(undefined));
|
||||
t.notThrows(() => {
|
||||
return (0, analyze_1.validateQueryFilters)([
|
||||
{
|
||||
exclude: {
|
||||
"problem.severity": "recommendation",
|
||||
},
|
||||
},
|
||||
{
|
||||
exclude: {
|
||||
"tags contain": ["foo", "bar"],
|
||||
},
|
||||
},
|
||||
{
|
||||
include: {
|
||||
"problem.severity": "something-to-think-about",
|
||||
},
|
||||
},
|
||||
{
|
||||
include: {
|
||||
"tags contain": ["baz", "bop"],
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
t.throws(() => {
|
||||
return (0, analyze_1.validateQueryFilters)([
|
||||
{
|
||||
exclude: {
|
||||
"tags contain": ["foo", "bar"],
|
||||
},
|
||||
include: {
|
||||
"tags contain": ["baz", "bop"],
|
||||
},
|
||||
},
|
||||
]);
|
||||
}, { message: /Query filter must have exactly one key/ });
|
||||
t.throws(() => {
|
||||
return (0, analyze_1.validateQueryFilters)([{ xxx: "foo" }]);
|
||||
}, { message: /Only "include" or "exclude" filters are allowed/ });
|
||||
});
|
||||
const convertPackToQuerySuiteEntryMacro = ava_1.default.macro({
|
||||
exec: (t, packSpec, suiteEntry) => t.deepEqual((0, analyze_1.convertPackToQuerySuiteEntry)(packSpec), suiteEntry),
|
||||
title: (_providedTitle, packSpec) => `Query Suite Entry: ${packSpec}`,
|
||||
});
|
||||
(0, ava_1.default)(convertPackToQuerySuiteEntryMacro, "a/b", {
|
||||
qlpack: "a/b",
|
||||
from: undefined,
|
||||
version: undefined,
|
||||
query: undefined,
|
||||
queries: undefined,
|
||||
apply: undefined,
|
||||
});
|
||||
(0, ava_1.default)(convertPackToQuerySuiteEntryMacro, "a/b@~1.2.3", {
|
||||
qlpack: "a/b",
|
||||
from: undefined,
|
||||
version: "~1.2.3",
|
||||
query: undefined,
|
||||
queries: undefined,
|
||||
apply: undefined,
|
||||
});
|
||||
(0, ava_1.default)(convertPackToQuerySuiteEntryMacro, "a/b:my/path", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: undefined,
|
||||
query: undefined,
|
||||
queries: "my/path",
|
||||
apply: undefined,
|
||||
});
|
||||
(0, ava_1.default)(convertPackToQuerySuiteEntryMacro, "a/b@~1.2.3:my/path", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: "~1.2.3",
|
||||
query: undefined,
|
||||
queries: "my/path",
|
||||
apply: undefined,
|
||||
});
|
||||
(0, ava_1.default)(convertPackToQuerySuiteEntryMacro, "a/b:my/path/query.ql", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: undefined,
|
||||
query: "my/path/query.ql",
|
||||
queries: undefined,
|
||||
apply: undefined,
|
||||
});
|
||||
(0, ava_1.default)(convertPackToQuerySuiteEntryMacro, "a/b@~1.2.3:my/path/query.ql", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: "~1.2.3",
|
||||
query: "my/path/query.ql",
|
||||
queries: undefined,
|
||||
apply: undefined,
|
||||
});
|
||||
(0, ava_1.default)(convertPackToQuerySuiteEntryMacro, "a/b:my/path/suite.qls", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: undefined,
|
||||
query: undefined,
|
||||
queries: undefined,
|
||||
apply: "my/path/suite.qls",
|
||||
});
|
||||
(0, ava_1.default)(convertPackToQuerySuiteEntryMacro, "a/b@~1.2.3:my/path/suite.qls", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: "~1.2.3",
|
||||
query: undefined,
|
||||
queries: undefined,
|
||||
apply: "my/path/suite.qls",
|
||||
});
|
||||
(0, ava_1.default)("convertPackToQuerySuiteEntry Failure", (t) => {
|
||||
t.throws(() => (0, analyze_1.convertPackToQuerySuiteEntry)("this-is-not-a-pack"));
|
||||
});
|
||||
(0, ava_1.default)("createQuerySuiteContents", (t) => {
|
||||
const yamlResult = (0, analyze_1.createQuerySuiteContents)(["query1.ql", "query2.ql"], [
|
||||
{
|
||||
exclude: { "problem.severity": "recommendation" },
|
||||
},
|
||||
{
|
||||
include: { "problem.severity": "recommendation" },
|
||||
},
|
||||
]);
|
||||
const expected = `- query: query1.ql
|
||||
- query: query2.ql
|
||||
- exclude:
|
||||
problem.severity: recommendation
|
||||
- include:
|
||||
problem.severity: recommendation
|
||||
`;
|
||||
t.deepEqual(yamlResult, expected);
|
||||
});
|
||||
//# sourceMappingURL=analyze.test.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{ "maximumVersion": "3.5", "minimumVersion": "3.1" }
|
||||
{ "maximumVersion": "3.6", "minimumVersion": "3.2" }
|
||||
|
||||
31
lib/config-utils.js
generated
31
lib/config-utils.js
generated
@@ -19,7 +19,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getConfig = exports.getPathToParsedConfigFile = exports.initConfig = exports.parsePacks = exports.validatePacksSpecification = exports.parsePacksFromConfig = exports.getDefaultConfig = exports.getUnknownLanguagesError = exports.getNoLanguagesError = exports.getConfigFileDirectoryGivenMessage = exports.getConfigFileFormatInvalidMessage = exports.getConfigFileRepoFormatInvalidMessage = exports.getConfigFileDoesNotExistErrorMessage = exports.getConfigFileOutsideWorkspaceErrorMessage = exports.getLocalPathDoesNotExist = exports.getLocalPathOutsideOfRepository = exports.getPacksStrInvalid = exports.getPacksInvalid = exports.getPacksInvalidSplit = exports.getPacksRequireLanguage = exports.getPathsInvalid = exports.getPathsIgnoreInvalid = exports.getQueryUsesInvalid = exports.getQueriesInvalid = exports.getDisableDefaultQueriesInvalid = exports.getNameInvalid = exports.validateAndSanitisePath = void 0;
|
||||
exports.getConfig = exports.getPathToParsedConfigFile = exports.initConfig = exports.parsePacks = exports.validatePackSpecification = exports.prettyPrintPack = exports.parsePacksSpecification = exports.parsePacksFromConfig = exports.getDefaultConfig = exports.getUnknownLanguagesError = exports.getNoLanguagesError = exports.getConfigFileDirectoryGivenMessage = exports.getConfigFileFormatInvalidMessage = exports.getConfigFileRepoFormatInvalidMessage = exports.getConfigFileDoesNotExistErrorMessage = exports.getConfigFileOutsideWorkspaceErrorMessage = exports.getLocalPathDoesNotExist = exports.getLocalPathOutsideOfRepository = exports.getPacksStrInvalid = exports.getPacksInvalid = exports.getPacksInvalidSplit = exports.getPacksRequireLanguage = exports.getPathsInvalid = exports.getPathsIgnoreInvalid = exports.getQueryUsesInvalid = exports.getQueriesInvalid = exports.getDisableDefaultQueriesInvalid = exports.getNameInvalid = exports.validateAndSanitisePath = void 0;
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
@@ -150,9 +150,7 @@ async function addBuiltinSuiteQueries(languages, codeQL, resultMap, packs, suite
|
||||
return injectedMlQueries;
|
||||
}
|
||||
function isMlPoweredJsQueriesPack(pack) {
|
||||
return (pack === util_1.ML_POWERED_JS_QUERIES_PACK_NAME ||
|
||||
pack.startsWith(`${util_1.ML_POWERED_JS_QUERIES_PACK_NAME}@`) ||
|
||||
pack.startsWith(`${util_1.ML_POWERED_JS_QUERIES_PACK_NAME}:`));
|
||||
return parsePacksSpecification(pack).name === util_1.ML_POWERED_JS_QUERIES_PACK_NAME;
|
||||
}
|
||||
/**
|
||||
* Retrieve the set of queries at localQueryPath and add them to resultMap.
|
||||
@@ -638,10 +636,7 @@ function parsePacksFromConfig(packsByLanguage, languages, configFile) {
|
||||
if (!languages.includes(lang)) {
|
||||
throw new Error(getPacksRequireLanguage(lang, configFile));
|
||||
}
|
||||
packs[lang] = [];
|
||||
for (const packStr of packsArr) {
|
||||
packs[lang].push(validatePacksSpecification(packStr, configFile));
|
||||
}
|
||||
packs[lang] = packsArr.map((packStr) => validatePackSpecification(packStr, configFile));
|
||||
}
|
||||
return packs;
|
||||
}
|
||||
@@ -665,7 +660,7 @@ function parsePacksFromInput(packsInput, languages) {
|
||||
}
|
||||
return {
|
||||
[languages[0]]: packsInput.split(",").reduce((packs, pack) => {
|
||||
packs.push(validatePacksSpecification(pack, ""));
|
||||
packs.push(validatePackSpecification(pack));
|
||||
return packs;
|
||||
}, []),
|
||||
};
|
||||
@@ -688,7 +683,7 @@ function parsePacksFromInput(packsInput, languages) {
|
||||
* @param packStr the package specification to verify.
|
||||
* @param configFile Config file to use for error reporting
|
||||
*/
|
||||
function validatePacksSpecification(packStr, configFile) {
|
||||
function parsePacksSpecification(packStr, configFile) {
|
||||
if (typeof packStr !== "string") {
|
||||
throw new Error(getPacksStrInvalid(packStr, configFile));
|
||||
}
|
||||
@@ -730,9 +725,21 @@ function validatePacksSpecification(packStr, configFile) {
|
||||
// 0 length path
|
||||
throw new Error(getPacksStrInvalid(packStr, configFile));
|
||||
}
|
||||
return (packName + (version ? `@${version}` : "") + (packPath ? `:${packPath}` : ""));
|
||||
return {
|
||||
name: packName,
|
||||
version,
|
||||
path: packPath,
|
||||
};
|
||||
}
|
||||
exports.validatePacksSpecification = validatePacksSpecification;
|
||||
exports.parsePacksSpecification = parsePacksSpecification;
|
||||
function prettyPrintPack(pack) {
|
||||
return `${pack.name}${pack.version ? `@${pack.version}` : ""}${pack.path ? `:${pack.path}` : ""}`;
|
||||
}
|
||||
exports.prettyPrintPack = prettyPrintPack;
|
||||
function validatePackSpecification(pack, configFile) {
|
||||
return prettyPrintPack(parsePacksSpecification(pack, configFile));
|
||||
}
|
||||
exports.validatePackSpecification = validatePackSpecification;
|
||||
// exported for testing
|
||||
function parsePacks(rawPacksFromConfig, rawPacksInput, languages, configFile) {
|
||||
const packsFromInput = parsePacksFromInput(rawPacksInput, languages);
|
||||
|
||||
File diff suppressed because one or more lines are too long
46
lib/config-utils.test.js
generated
46
lib/config-utils.test.js
generated
@@ -828,6 +828,46 @@ const invalidPackNameMacro = ava_1.default.macro({
|
||||
(0, ava_1.default)(invalidPackNameMacro, "c/d@../a");
|
||||
(0, ava_1.default)(invalidPackNameMacro, "c/d@b/../a");
|
||||
(0, ava_1.default)(invalidPackNameMacro, "c/d:z@1");
|
||||
/**
|
||||
* Test macro for pretty printing pack specs
|
||||
*/
|
||||
const packSpecPrettyPrintingMacro = ava_1.default.macro({
|
||||
exec: (t, packStr, packObj) => {
|
||||
const parsed = configUtils.parsePacksSpecification(packStr);
|
||||
t.deepEqual(parsed, packObj, "parsed pack spec is correct");
|
||||
const stringified = configUtils.prettyPrintPack(packObj);
|
||||
t.deepEqual(stringified, packStr.trim(), "pretty-printed pack spec is correct");
|
||||
t.deepEqual(configUtils.validatePackSpecification(packStr), packStr.trim(), "pack spec is valid");
|
||||
},
|
||||
title: (_providedTitle, packStr,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
_packObj) => `Prettyprint pack spec: '${packStr}'`,
|
||||
});
|
||||
(0, ava_1.default)(packSpecPrettyPrintingMacro, "a/b", {
|
||||
name: "a/b",
|
||||
version: undefined,
|
||||
path: undefined,
|
||||
});
|
||||
(0, ava_1.default)(packSpecPrettyPrintingMacro, "a/b@~1.2.3", {
|
||||
name: "a/b",
|
||||
version: "~1.2.3",
|
||||
path: undefined,
|
||||
});
|
||||
(0, ava_1.default)(packSpecPrettyPrintingMacro, "a/b@~1.2.3:abc/def", {
|
||||
name: "a/b",
|
||||
version: "~1.2.3",
|
||||
path: "abc/def",
|
||||
});
|
||||
(0, ava_1.default)(packSpecPrettyPrintingMacro, "a/b:abc/def", {
|
||||
name: "a/b",
|
||||
version: undefined,
|
||||
path: "abc/def",
|
||||
});
|
||||
(0, ava_1.default)(packSpecPrettyPrintingMacro, " a/b:abc/def ", {
|
||||
name: "a/b",
|
||||
version: undefined,
|
||||
path: "abc/def",
|
||||
});
|
||||
/**
|
||||
* Test macro for testing the packs block and the packs input
|
||||
*/
|
||||
@@ -925,4 +965,10 @@ const mlPoweredQueriesMacro = ava_1.default.macro({
|
||||
(0, ava_1.default)(mlPoweredQueriesMacro, "2.9.0", true, undefined, "security-and-quality", "~0.2.0");
|
||||
// Test that we don't inject an ML-powered query pack if the user has already specified one.
|
||||
(0, ava_1.default)(mlPoweredQueriesMacro, "2.9.0", true, "codeql/javascript-experimental-atm-queries@0.0.1", "security-and-quality", "0.0.1");
|
||||
// Test that ML-powered queries are run on all platforms running `security-extended` on CodeQL
|
||||
// CLI 2.9.3+.
|
||||
(0, ava_1.default)(mlPoweredQueriesMacro, "2.9.3", true, undefined, "security-extended", "~0.3.0");
|
||||
// Test that ML-powered queries are run on all platforms running `security-and-quality` on CodeQL
|
||||
// CLI 2.9.3+.
|
||||
(0, ava_1.default)(mlPoweredQueriesMacro, "2.9.3", true, undefined, "security-and-quality", "~0.3.0");
|
||||
//# sourceMappingURL=config-utils.test.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"bundleVersion": "codeql-bundle-20220512"
|
||||
"bundleVersion": "codeql-bundle-20220615"
|
||||
}
|
||||
|
||||
3
lib/languages.js
generated
3
lib/languages.js
generated
@@ -11,6 +11,7 @@ var Language;
|
||||
Language["javascript"] = "javascript";
|
||||
Language["python"] = "python";
|
||||
Language["ruby"] = "ruby";
|
||||
Language["swift"] = "swift";
|
||||
})(Language = exports.Language || (exports.Language = {}));
|
||||
// Additional names for languages
|
||||
const LANGUAGE_ALIASES = {
|
||||
@@ -35,7 +36,7 @@ function parseLanguage(language) {
|
||||
}
|
||||
exports.parseLanguage = parseLanguage;
|
||||
function isTracedLanguage(language) {
|
||||
return (["cpp", "java", "csharp"].includes(language) ||
|
||||
return (["cpp", "java", "csharp", "swift"].includes(language) ||
|
||||
(process.env["CODEQL_EXTRACTOR_GO_BUILD_TRACING"] === "on" &&
|
||||
language === Language.go));
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;;AAAA,wCAAwC;AACxC,IAAY,QAQX;AARD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;IACX,qBAAS,CAAA;IACT,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;IACjB,yBAAa,CAAA;AACf,CAAC,EARW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAQnB;AAED,iCAAiC;AACjC,MAAM,gBAAgB,GAAiC;IACrD,CAAC,EAAE,QAAQ,CAAC,GAAG;IACf,KAAK,EAAE,QAAQ,CAAC,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;IACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAEF,gGAAgG;AAChG,SAAgB,aAAa,CAAC,QAAgB;IAC5C,0BAA0B;IAC1B,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAElC,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,OAAO,QAAoB,CAAC;KAC7B;IAED,yBAAyB;IACzB,IAAI,QAAQ,IAAI,gBAAgB,EAAE;QAChC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC;KACnC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAfD,sCAeC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,OAAO,CACL,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5C,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,KAAK,IAAI;YACxD,QAAQ,KAAK,QAAQ,CAAC,EAAE,CAAC,CAC5B,CAAC;AACJ,CAAC;AAND,4CAMC;AAED,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAFD,8CAEC"}
|
||||
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;;AAAA,wCAAwC;AACxC,IAAY,QASX;AATD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;IACX,qBAAS,CAAA;IACT,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;IACjB,yBAAa,CAAA;IACb,2BAAe,CAAA;AACjB,CAAC,EATW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QASnB;AAED,iCAAiC;AACjC,MAAM,gBAAgB,GAAiC;IACrD,CAAC,EAAE,QAAQ,CAAC,GAAG;IACf,KAAK,EAAE,QAAQ,CAAC,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;IACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAEF,gGAAgG;AAChG,SAAgB,aAAa,CAAC,QAAgB;IAC5C,0BAA0B;IAC1B,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAElC,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,OAAO,QAAoB,CAAC;KAC7B;IAED,yBAAyB;IACzB,IAAI,QAAQ,IAAI,gBAAgB,EAAE;QAChC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC;KACnC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAfD,sCAeC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,OAAO,CACL,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACrD,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,KAAK,IAAI;YACxD,QAAQ,KAAK,QAAQ,CAAC,EAAE,CAAC,CAC5B,CAAC;AACJ,CAAC;AAND,4CAMC;AAED,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAFD,8CAEC"}
|
||||
24
lib/util.js
generated
24
lib/util.js
generated
@@ -33,6 +33,7 @@ const api = __importStar(require("./api-client"));
|
||||
const api_client_1 = require("./api-client");
|
||||
const apiCompatibility = __importStar(require("./api-compatibility.json"));
|
||||
const codeql_1 = require("./codeql");
|
||||
const config_utils_1 = require("./config-utils");
|
||||
/**
|
||||
* Specifies bundle versions that are known to be broken
|
||||
* and will not be used if found in the toolcache.
|
||||
@@ -552,10 +553,20 @@ exports.ML_POWERED_JS_QUERIES_PACK_NAME = "codeql/javascript-experimental-atm-qu
|
||||
* queries beta.
|
||||
*/
|
||||
async function getMlPoweredJsQueriesPack(codeQL) {
|
||||
if (await codeQlVersionAbove(codeQL, "2.8.4")) {
|
||||
return `${exports.ML_POWERED_JS_QUERIES_PACK_NAME}@~0.2.0`;
|
||||
let version;
|
||||
if (await codeQlVersionAbove(codeQL, "2.9.3")) {
|
||||
version = `~0.3.0`;
|
||||
}
|
||||
return `${exports.ML_POWERED_JS_QUERIES_PACK_NAME}@~0.1.0`;
|
||||
else if (await codeQlVersionAbove(codeQL, "2.8.4")) {
|
||||
version = `~0.2.0`;
|
||||
}
|
||||
else {
|
||||
version = `~0.1.0`;
|
||||
}
|
||||
return (0, config_utils_1.prettyPrintPack)({
|
||||
name: exports.ML_POWERED_JS_QUERIES_PACK_NAME,
|
||||
version,
|
||||
});
|
||||
}
|
||||
exports.getMlPoweredJsQueriesPack = getMlPoweredJsQueriesPack;
|
||||
/**
|
||||
@@ -581,9 +592,8 @@ exports.getMlPoweredJsQueriesPack = getMlPoweredJsQueriesPack;
|
||||
*/
|
||||
function getMlPoweredJsQueriesStatus(config) {
|
||||
const mlPoweredJsQueryPacks = (config.packs.javascript || [])
|
||||
.map((pack) => pack.split("@"))
|
||||
.filter((packNameVersion) => packNameVersion[0] === "codeql/javascript-experimental-atm-queries" &&
|
||||
packNameVersion.length <= 2);
|
||||
.map((p) => (0, config_utils_1.parsePacksSpecification)(p))
|
||||
.filter((pack) => pack.name === "codeql/javascript-experimental-atm-queries" && !pack.path);
|
||||
switch (mlPoweredJsQueryPacks.length) {
|
||||
case 1:
|
||||
// We should always specify an explicit version string in `getMlPoweredJsQueriesPack`,
|
||||
@@ -591,7 +601,7 @@ function getMlPoweredJsQueriesStatus(config) {
|
||||
// with each version of the CodeQL Action. Therefore in practice we should only hit the
|
||||
// `latest` case here when customers have explicitly added the ML-powered query pack to their
|
||||
// CodeQL config.
|
||||
return mlPoweredJsQueryPacks[0][1] || "latest";
|
||||
return mlPoweredJsQueryPacks[0].version || "latest";
|
||||
case 0:
|
||||
return "false";
|
||||
default:
|
||||
|
||||
File diff suppressed because one or more lines are too long
6
lib/util.test.js
generated
6
lib/util.test.js
generated
@@ -209,13 +209,13 @@ const ML_POWERED_JS_STATUS_TESTS = [
|
||||
// If no packs are loaded, status is false.
|
||||
[[], "false"],
|
||||
// If another pack is loaded but not the ML-powered query pack, status is false.
|
||||
[["someOtherPack"], "false"],
|
||||
[["some-other/pack"], "false"],
|
||||
// If the ML-powered query pack is loaded with a specific version, status is that version.
|
||||
[[`${util.ML_POWERED_JS_QUERIES_PACK_NAME}@~0.1.0`], "~0.1.0"],
|
||||
// If the ML-powered query pack is loaded with a specific version and another pack is loaded, the
|
||||
// status is the version of the ML-powered query pack.
|
||||
[
|
||||
["someOtherPack", `${util.ML_POWERED_JS_QUERIES_PACK_NAME}@~0.1.0`],
|
||||
["some-other/pack", `${util.ML_POWERED_JS_QUERIES_PACK_NAME}@~0.1.0`],
|
||||
"~0.1.0",
|
||||
],
|
||||
// If the ML-powered query pack is loaded without a version, the status is "latest".
|
||||
@@ -230,7 +230,7 @@ const ML_POWERED_JS_STATUS_TESTS = [
|
||||
],
|
||||
// If the ML-powered query pack is loaded with no specific version, and another pack is loaded,
|
||||
// the status is "latest".
|
||||
[["someOtherPack", util.ML_POWERED_JS_QUERIES_PACK_NAME], "latest"],
|
||||
[["some-other/pack", util.ML_POWERED_JS_QUERIES_PACK_NAME], "latest"],
|
||||
];
|
||||
for (const [packs, expectedStatus] of ML_POWERED_JS_STATUS_TESTS) {
|
||||
const packDescriptions = `[${packs
|
||||
|
||||
File diff suppressed because one or more lines are too long
8
node_modules/.package-lock.json
generated
vendored
8
node_modules/.package-lock.json
generated
vendored
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "codeql",
|
||||
"version": "2.1.12",
|
||||
"version": "2.1.13",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
@@ -469,6 +469,12 @@
|
||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/js-yaml": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz",
|
||||
"integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz",
|
||||
|
||||
21
node_modules/@types/js-yaml/LICENSE
generated
vendored
Executable file
21
node_modules/@types/js-yaml/LICENSE
generated
vendored
Executable file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
16
node_modules/@types/js-yaml/README.md
generated
vendored
Executable file
16
node_modules/@types/js-yaml/README.md
generated
vendored
Executable file
@@ -0,0 +1,16 @@
|
||||
# Installation
|
||||
> `npm install --save @types/js-yaml`
|
||||
|
||||
# Summary
|
||||
This package contains type definitions for js-yaml (https://github.com/nodeca/js-yaml).
|
||||
|
||||
# Details
|
||||
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/js-yaml.
|
||||
|
||||
### Additional Details
|
||||
* Last updated: Fri, 19 Nov 2021 18:01:12 GMT
|
||||
* Dependencies: none
|
||||
* Global values: `jsyaml`
|
||||
|
||||
# Credits
|
||||
These definitions were written by [Bart van der Schoor](https://github.com/Bartvds), [Sebastian Clausen](https://github.com/sclausen), [ExE Boss](https://github.com/ExE-Boss), [Armaan Tobaccowalla](https://github.com/ArmaanT), and [Linus Unnebäck](https://github.com/LinusU).
|
||||
2
node_modules/@types/js-yaml/index.d.mts
generated
vendored
Executable file
2
node_modules/@types/js-yaml/index.d.mts
generated
vendored
Executable file
@@ -0,0 +1,2 @@
|
||||
export * from "./index.js";
|
||||
export { default } from "./index.js";
|
||||
154
node_modules/@types/js-yaml/index.d.ts
generated
vendored
Executable file
154
node_modules/@types/js-yaml/index.d.ts
generated
vendored
Executable file
@@ -0,0 +1,154 @@
|
||||
// Type definitions for js-yaml 4.0
|
||||
// Project: https://github.com/nodeca/js-yaml
|
||||
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
|
||||
// Sebastian Clausen <https://github.com/sclausen>
|
||||
// ExE Boss <https://github.com/ExE-Boss>
|
||||
// Armaan Tobaccowalla <https://github.com/ArmaanT>
|
||||
// Linus Unnebäck <https://github.com/LinusU>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.2
|
||||
|
||||
export as namespace jsyaml;
|
||||
|
||||
export function load(str: string, opts?: LoadOptions): unknown;
|
||||
|
||||
export class Type {
|
||||
constructor(tag: string, opts?: TypeConstructorOptions);
|
||||
kind: 'sequence' | 'scalar' | 'mapping' | null;
|
||||
resolve(data: any): boolean;
|
||||
construct(data: any, type?: string): any;
|
||||
instanceOf: object | null;
|
||||
predicate: ((data: object) => boolean) | null;
|
||||
represent: ((data: object) => any) | { [x: string]: (data: object) => any } | null;
|
||||
representName: ((data: object) => any) | null;
|
||||
defaultStyle: string | null;
|
||||
multi: boolean;
|
||||
styleAliases: { [x: string]: any };
|
||||
}
|
||||
|
||||
export class Schema {
|
||||
constructor(definition: SchemaDefinition | Type[] | Type);
|
||||
extend(types: SchemaDefinition | Type[] | Type): Schema;
|
||||
}
|
||||
|
||||
export function loadAll(str: string, iterator?: null, opts?: LoadOptions): unknown[];
|
||||
export function loadAll(str: string, iterator: (doc: unknown) => void, opts?: LoadOptions): void;
|
||||
|
||||
export function dump(obj: any, opts?: DumpOptions): string;
|
||||
|
||||
export interface LoadOptions {
|
||||
/** string to be used as a file path in error/warning messages. */
|
||||
filename?: string | undefined;
|
||||
/** function to call on warning messages. */
|
||||
onWarning?(this: null, e: YAMLException): void;
|
||||
/** specifies a schema to use. */
|
||||
schema?: Schema | undefined;
|
||||
/** compatibility with JSON.parse behaviour. */
|
||||
json?: boolean | undefined;
|
||||
/** listener for parse events */
|
||||
listener?(this: State, eventType: EventType, state: State): void;
|
||||
}
|
||||
|
||||
export type EventType = 'open' | 'close';
|
||||
|
||||
export interface State {
|
||||
input: string;
|
||||
filename: string | null;
|
||||
schema: Schema;
|
||||
onWarning: (this: null, e: YAMLException) => void;
|
||||
json: boolean;
|
||||
length: number;
|
||||
position: number;
|
||||
line: number;
|
||||
lineStart: number;
|
||||
lineIndent: number;
|
||||
version: null | number;
|
||||
checkLineBreaks: boolean;
|
||||
kind: string;
|
||||
result: any;
|
||||
implicitTypes: Type[];
|
||||
}
|
||||
|
||||
export interface DumpOptions {
|
||||
/** indentation width to use (in spaces). */
|
||||
indent?: number | undefined;
|
||||
/** when true, will not add an indentation level to array elements */
|
||||
noArrayIndent?: boolean | undefined;
|
||||
/** do not throw on invalid types (like function in the safe schema) and skip pairs and single values with such types. */
|
||||
skipInvalid?: boolean | undefined;
|
||||
/** specifies level of nesting, when to switch from block to flow style for collections. -1 means block style everwhere */
|
||||
flowLevel?: number | undefined;
|
||||
/** Each tag may have own set of styles. - "tag" => "style" map. */
|
||||
styles?: { [x: string]: any } | undefined;
|
||||
/** specifies a schema to use. */
|
||||
schema?: Schema | undefined;
|
||||
/** if true, sort keys when dumping YAML. If a function, use the function to sort the keys. (default: false) */
|
||||
sortKeys?: boolean | ((a: any, b: any) => number) | undefined;
|
||||
/** set max line width. (default: 80) */
|
||||
lineWidth?: number | undefined;
|
||||
/** if true, don't convert duplicate objects into references (default: false) */
|
||||
noRefs?: boolean | undefined;
|
||||
/** if true don't try to be compatible with older yaml versions. Currently: don't quote "yes", "no" and so on, as required for YAML 1.1 (default: false) */
|
||||
noCompatMode?: boolean | undefined;
|
||||
/**
|
||||
* if true flow sequences will be condensed, omitting the space between `key: value` or `a, b`. Eg. `'[a,b]'` or `{a:{b:c}}`.
|
||||
* Can be useful when using yaml for pretty URL query params as spaces are %-encoded. (default: false).
|
||||
*/
|
||||
condenseFlow?: boolean | undefined;
|
||||
/** strings will be quoted using this quoting style. If you specify single quotes, double quotes will still be used for non-printable characters. (default: `'`) */
|
||||
quotingType?: "'" | '"' | undefined;
|
||||
/** if true, all non-key strings will be quoted even if they normally don't need to. (default: false) */
|
||||
forceQuotes?: boolean | undefined;
|
||||
/** callback `function (key, value)` called recursively on each key/value in source object (see `replacer` docs for `JSON.stringify`). */
|
||||
replacer?: ((key: string, value: any) => any) | undefined;
|
||||
}
|
||||
|
||||
export interface TypeConstructorOptions {
|
||||
kind?: 'sequence' | 'scalar' | 'mapping' | undefined;
|
||||
resolve?: ((data: any) => boolean) | undefined;
|
||||
construct?: ((data: any, type?: string) => any) | undefined;
|
||||
instanceOf?: object | undefined;
|
||||
predicate?: ((data: object) => boolean) | undefined;
|
||||
represent?: ((data: object) => any) | { [x: string]: (data: object) => any } | undefined;
|
||||
representName?: ((data: object) => any) | undefined;
|
||||
defaultStyle?: string | undefined;
|
||||
multi?: boolean | undefined;
|
||||
styleAliases?: { [x: string]: any } | undefined;
|
||||
}
|
||||
|
||||
export interface SchemaDefinition {
|
||||
implicit?: Type[] | undefined;
|
||||
explicit?: Type[] | undefined;
|
||||
}
|
||||
|
||||
/** only strings, arrays and plain objects: http://www.yaml.org/spec/1.2/spec.html#id2802346 */
|
||||
export let FAILSAFE_SCHEMA: Schema;
|
||||
/** only strings, arrays and plain objects: http://www.yaml.org/spec/1.2/spec.html#id2802346 */
|
||||
export let JSON_SCHEMA: Schema;
|
||||
/** same as JSON_SCHEMA: http://www.yaml.org/spec/1.2/spec.html#id2804923 */
|
||||
export let CORE_SCHEMA: Schema;
|
||||
/** all supported YAML types */
|
||||
export let DEFAULT_SCHEMA: Schema;
|
||||
|
||||
export interface Mark {
|
||||
buffer: string;
|
||||
column: number;
|
||||
line: number;
|
||||
name: string;
|
||||
position: number;
|
||||
snippet: string;
|
||||
}
|
||||
|
||||
export class YAMLException extends Error {
|
||||
constructor(reason?: string, mark?: Mark);
|
||||
|
||||
toString(compact?: boolean): string;
|
||||
|
||||
name: string;
|
||||
|
||||
reason: string;
|
||||
|
||||
message: string;
|
||||
|
||||
mark: Mark;
|
||||
}
|
||||
53
node_modules/@types/js-yaml/package.json
generated
vendored
Executable file
53
node_modules/@types/js-yaml/package.json
generated
vendored
Executable file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "@types/js-yaml",
|
||||
"version": "4.0.5",
|
||||
"description": "TypeScript definitions for js-yaml",
|
||||
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/js-yaml",
|
||||
"license": "MIT",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Bart van der Schoor",
|
||||
"url": "https://github.com/Bartvds",
|
||||
"githubUsername": "Bartvds"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Clausen",
|
||||
"url": "https://github.com/sclausen",
|
||||
"githubUsername": "sclausen"
|
||||
},
|
||||
{
|
||||
"name": "ExE Boss",
|
||||
"url": "https://github.com/ExE-Boss",
|
||||
"githubUsername": "ExE-Boss"
|
||||
},
|
||||
{
|
||||
"name": "Armaan Tobaccowalla",
|
||||
"url": "https://github.com/ArmaanT",
|
||||
"githubUsername": "ArmaanT"
|
||||
},
|
||||
{
|
||||
"name": "Linus Unnebäck",
|
||||
"url": "https://github.com/LinusU",
|
||||
"githubUsername": "LinusU"
|
||||
}
|
||||
],
|
||||
"main": "",
|
||||
"types": "index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||
"directory": "types/js-yaml"
|
||||
},
|
||||
"scripts": {},
|
||||
"dependencies": {},
|
||||
"typesPublisherContentHash": "6f40877154edac83ffa22d53a6aca74f151a0d094074c81ce7fb21df57ea5725",
|
||||
"typeScriptVersion": "3.8",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": {
|
||||
"import": "./index.d.mts",
|
||||
"default": "./index.d.ts"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
package-lock.json
generated
17
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "codeql",
|
||||
"version": "2.1.12",
|
||||
"version": "2.1.13",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "codeql",
|
||||
"version": "2.1.12",
|
||||
"version": "2.1.13",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/artifact": "^1.0.0",
|
||||
@@ -38,6 +38,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ava/typescript": "3.0.1",
|
||||
"@types/js-yaml": "^4.0.5",
|
||||
"@types/long": "4.0.1",
|
||||
"@types/node": "16.11.22",
|
||||
"@types/semver": "^7.3.8",
|
||||
@@ -521,6 +522,12 @@
|
||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/js-yaml": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz",
|
||||
"integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz",
|
||||
@@ -5885,6 +5892,12 @@
|
||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/js-yaml": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz",
|
||||
"integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "codeql",
|
||||
"version": "2.1.12",
|
||||
"version": "2.1.13",
|
||||
"private": true,
|
||||
"description": "CodeQL action",
|
||||
"scripts": {
|
||||
@@ -53,6 +53,7 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"@ava/typescript": "3.0.1",
|
||||
"@types/js-yaml": "^4.0.5",
|
||||
"@types/long": "4.0.1",
|
||||
"@types/node": "16.11.22",
|
||||
"@types/semver": "^7.3.8",
|
||||
|
||||
@@ -269,7 +269,7 @@ test("getWorkflowErrors() when on.push is correct with empty objects", (t) => {
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
);
|
||||
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
@@ -441,7 +441,7 @@ on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
);
|
||||
|
||||
t.deepEqual(
|
||||
@@ -559,7 +559,7 @@ test("getWorkflowErrors() when branches contain dots", (t) => {
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [4.1, master]
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
);
|
||||
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
@@ -575,7 +575,7 @@ on:
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
);
|
||||
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
@@ -604,7 +604,7 @@ jobs:
|
||||
|
||||
test3:
|
||||
steps: []
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
);
|
||||
|
||||
t.deepEqual(
|
||||
@@ -635,7 +635,7 @@ jobs:
|
||||
|
||||
test3:
|
||||
steps: []
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
);
|
||||
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
@@ -645,7 +645,7 @@ test("getWorkflowErrors() when on is missing", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors(
|
||||
yaml.load(`
|
||||
name: "CodeQL"
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
);
|
||||
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
@@ -658,7 +658,7 @@ test("getWorkflowErrors() with a different on setup", (t) => {
|
||||
yaml.load(`
|
||||
name: "CodeQL"
|
||||
on: "workflow_dispatch"
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
),
|
||||
[]
|
||||
)
|
||||
@@ -670,7 +670,7 @@ on: "workflow_dispatch"
|
||||
yaml.load(`
|
||||
name: "CodeQL"
|
||||
on: [workflow_dispatch]
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
),
|
||||
[]
|
||||
)
|
||||
@@ -683,7 +683,7 @@ on: [workflow_dispatch]
|
||||
name: "CodeQL"
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
),
|
||||
[]
|
||||
)
|
||||
@@ -699,7 +699,7 @@ name: "CodeQL"
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
),
|
||||
[]
|
||||
)
|
||||
@@ -711,7 +711,7 @@ on:
|
||||
yaml.load(`
|
||||
name: "CodeQL"
|
||||
on: ["push"]
|
||||
`)
|
||||
`) as actionsutil.Workflow
|
||||
),
|
||||
[]
|
||||
)
|
||||
|
||||
@@ -191,7 +191,7 @@ interface WorkflowTriggers {
|
||||
pull_request?: WorkflowTrigger | null;
|
||||
}
|
||||
|
||||
interface Workflow {
|
||||
export interface Workflow {
|
||||
jobs?: { [key: string]: WorkflowJob };
|
||||
on?: string | string[] | WorkflowTriggers;
|
||||
}
|
||||
@@ -411,7 +411,7 @@ export async function getWorkflow(): Promise<Workflow> {
|
||||
relativePath
|
||||
);
|
||||
|
||||
return yaml.load(fs.readFileSync(absolutePath, "utf-8"));
|
||||
return yaml.load(fs.readFileSync(absolutePath, "utf-8")) as Workflow;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
import test from "ava";
|
||||
import test, { ExecutionContext } from "ava";
|
||||
import * as yaml from "js-yaml";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import { runQueries } from "./analyze";
|
||||
import {
|
||||
convertPackToQuerySuiteEntry,
|
||||
createQuerySuiteContents,
|
||||
runQueries,
|
||||
validateQueryFilters,
|
||||
} from "./analyze";
|
||||
import { setCodeQL } from "./codeql";
|
||||
import { Config } from "./config-utils";
|
||||
import * as count from "./count-loc";
|
||||
@@ -249,3 +254,161 @@ test("status report fields and search path setting", async (t) => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("validateQueryFilters", (t) => {
|
||||
t.notThrows(() => validateQueryFilters([]));
|
||||
t.notThrows(() => validateQueryFilters(undefined));
|
||||
t.notThrows(() => {
|
||||
return validateQueryFilters([
|
||||
{
|
||||
exclude: {
|
||||
"problem.severity": "recommendation",
|
||||
},
|
||||
},
|
||||
{
|
||||
exclude: {
|
||||
"tags contain": ["foo", "bar"],
|
||||
},
|
||||
},
|
||||
{
|
||||
include: {
|
||||
"problem.severity": "something-to-think-about",
|
||||
},
|
||||
},
|
||||
{
|
||||
include: {
|
||||
"tags contain": ["baz", "bop"],
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
t.throws(
|
||||
() => {
|
||||
return validateQueryFilters([
|
||||
{
|
||||
exclude: {
|
||||
"tags contain": ["foo", "bar"],
|
||||
},
|
||||
include: {
|
||||
"tags contain": ["baz", "bop"],
|
||||
},
|
||||
},
|
||||
]);
|
||||
},
|
||||
{ message: /Query filter must have exactly one key/ }
|
||||
);
|
||||
|
||||
t.throws(
|
||||
() => {
|
||||
return validateQueryFilters([{ xxx: "foo" } as any]);
|
||||
},
|
||||
{ message: /Only "include" or "exclude" filters are allowed/ }
|
||||
);
|
||||
});
|
||||
|
||||
const convertPackToQuerySuiteEntryMacro = test.macro({
|
||||
exec: (t: ExecutionContext<unknown>, packSpec: string, suiteEntry: any) =>
|
||||
t.deepEqual(convertPackToQuerySuiteEntry(packSpec), suiteEntry),
|
||||
|
||||
title: (_providedTitle, packSpec: string) => `Query Suite Entry: ${packSpec}`,
|
||||
});
|
||||
|
||||
test(convertPackToQuerySuiteEntryMacro, "a/b", {
|
||||
qlpack: "a/b",
|
||||
from: undefined,
|
||||
version: undefined,
|
||||
query: undefined,
|
||||
queries: undefined,
|
||||
apply: undefined,
|
||||
});
|
||||
|
||||
test(convertPackToQuerySuiteEntryMacro, "a/b@~1.2.3", {
|
||||
qlpack: "a/b",
|
||||
from: undefined,
|
||||
version: "~1.2.3",
|
||||
query: undefined,
|
||||
queries: undefined,
|
||||
apply: undefined,
|
||||
});
|
||||
|
||||
test(convertPackToQuerySuiteEntryMacro, "a/b:my/path", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: undefined,
|
||||
query: undefined,
|
||||
queries: "my/path",
|
||||
apply: undefined,
|
||||
});
|
||||
|
||||
test(convertPackToQuerySuiteEntryMacro, "a/b@~1.2.3:my/path", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: "~1.2.3",
|
||||
query: undefined,
|
||||
queries: "my/path",
|
||||
apply: undefined,
|
||||
});
|
||||
|
||||
test(convertPackToQuerySuiteEntryMacro, "a/b:my/path/query.ql", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: undefined,
|
||||
query: "my/path/query.ql",
|
||||
queries: undefined,
|
||||
apply: undefined,
|
||||
});
|
||||
|
||||
test(convertPackToQuerySuiteEntryMacro, "a/b@~1.2.3:my/path/query.ql", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: "~1.2.3",
|
||||
query: "my/path/query.ql",
|
||||
queries: undefined,
|
||||
apply: undefined,
|
||||
});
|
||||
|
||||
test(convertPackToQuerySuiteEntryMacro, "a/b:my/path/suite.qls", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: undefined,
|
||||
query: undefined,
|
||||
queries: undefined,
|
||||
apply: "my/path/suite.qls",
|
||||
});
|
||||
|
||||
test(convertPackToQuerySuiteEntryMacro, "a/b@~1.2.3:my/path/suite.qls", {
|
||||
qlpack: undefined,
|
||||
from: "a/b",
|
||||
version: "~1.2.3",
|
||||
query: undefined,
|
||||
queries: undefined,
|
||||
apply: "my/path/suite.qls",
|
||||
});
|
||||
|
||||
test("convertPackToQuerySuiteEntry Failure", (t) => {
|
||||
t.throws(() => convertPackToQuerySuiteEntry("this-is-not-a-pack"));
|
||||
});
|
||||
|
||||
test("createQuerySuiteContents", (t) => {
|
||||
const yamlResult = createQuerySuiteContents(
|
||||
["query1.ql", "query2.ql"],
|
||||
[
|
||||
{
|
||||
exclude: { "problem.severity": "recommendation" },
|
||||
},
|
||||
{
|
||||
include: { "problem.severity": "recommendation" },
|
||||
},
|
||||
]
|
||||
);
|
||||
const expected = `- query: query1.ql
|
||||
- query: query2.ql
|
||||
- exclude:
|
||||
problem.severity: recommendation
|
||||
- include:
|
||||
problem.severity: recommendation
|
||||
`;
|
||||
|
||||
t.deepEqual(yamlResult, expected);
|
||||
});
|
||||
|
||||
122
src/analyze.ts
122
src/analyze.ts
@@ -2,6 +2,7 @@ import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
import * as toolrunner from "@actions/exec/lib/toolrunner";
|
||||
import del from "del";
|
||||
import * as yaml from "js-yaml";
|
||||
|
||||
import * as analysisPaths from "./analysis-paths";
|
||||
@@ -151,7 +152,7 @@ function dbIsFinalized(
|
||||
try {
|
||||
const dbInfo = yaml.load(
|
||||
fs.readFileSync(path.resolve(dbPath, "codeql-database.yml"), "utf8")
|
||||
);
|
||||
) as { inProgress?: boolean };
|
||||
return !("inProgress" in dbInfo);
|
||||
} catch (e) {
|
||||
logger.warning(
|
||||
@@ -223,6 +224,9 @@ export async function runQueries(
|
||||
|
||||
for (const language of config.languages) {
|
||||
const queries = config.queries[language];
|
||||
const queryFilters = validateQueryFilters(
|
||||
config.originalUserInput["query-filters"]
|
||||
);
|
||||
const packsWithVersion = config.packs[language] || [];
|
||||
|
||||
const hasBuiltinQueries = queries?.builtin.length > 0;
|
||||
@@ -260,7 +264,7 @@ export async function runQueries(
|
||||
await runQueryGroup(
|
||||
language,
|
||||
"builtin",
|
||||
createQuerySuiteContents(queries["builtin"]),
|
||||
createQuerySuiteContents(queries["builtin"], queryFilters),
|
||||
undefined
|
||||
)
|
||||
);
|
||||
@@ -275,7 +279,10 @@ export async function runQueries(
|
||||
await runQueryGroup(
|
||||
language,
|
||||
`custom-${i}`,
|
||||
createQuerySuiteContents(queries["custom"][i].queries),
|
||||
createQuerySuiteContents(
|
||||
queries["custom"][i].queries,
|
||||
queryFilters
|
||||
),
|
||||
queries["custom"][i].searchPath
|
||||
)
|
||||
);
|
||||
@@ -284,12 +291,7 @@ export async function runQueries(
|
||||
}
|
||||
if (packsWithVersion.length > 0) {
|
||||
querySuitePaths.push(
|
||||
...(await runQueryPacks(
|
||||
language,
|
||||
"packs",
|
||||
packsWithVersion,
|
||||
undefined
|
||||
))
|
||||
await runQueryPacks(language, "packs", packsWithVersion, queryFilters)
|
||||
);
|
||||
ranCustom = true;
|
||||
}
|
||||
@@ -391,32 +393,61 @@ export async function runQueries(
|
||||
language: Language,
|
||||
type: string,
|
||||
packs: string[],
|
||||
searchPath: string | undefined
|
||||
): Promise<string[]> {
|
||||
queryFilters: configUtils.QueryFilter[]
|
||||
): Promise<string> {
|
||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||
// Run the queries individually instead of all at once to avoid command
|
||||
// line length restrictions, particularly on windows.
|
||||
|
||||
for (const pack of packs) {
|
||||
logger.debug(`Running query pack for ${language}-${type}: ${pack}`);
|
||||
|
||||
const codeql = await getCodeQL(config.codeQLCmd);
|
||||
await codeql.databaseRunQueries(
|
||||
databasePath,
|
||||
searchPath,
|
||||
pack,
|
||||
memoryFlag,
|
||||
threadsFlag
|
||||
);
|
||||
|
||||
logger.debug(`BQRS results produced for ${language} (queries: ${type})"`);
|
||||
}
|
||||
return packs;
|
||||
|
||||
// combine the list of packs into a query suite in order to run them all simultaneously.
|
||||
const querySuite = (
|
||||
packs.map(convertPackToQuerySuiteEntry) as configUtils.QuerySuiteEntry[]
|
||||
).concat(queryFilters);
|
||||
|
||||
const querySuitePath = `${databasePath}-queries-${type}.qls`;
|
||||
fs.writeFileSync(querySuitePath, yaml.dump(querySuite));
|
||||
|
||||
logger.debug(`BQRS results produced for ${language} (queries: ${type})"`);
|
||||
|
||||
const codeql = await getCodeQL(config.codeQLCmd);
|
||||
await codeql.databaseRunQueries(
|
||||
databasePath,
|
||||
undefined,
|
||||
querySuitePath,
|
||||
memoryFlag,
|
||||
threadsFlag
|
||||
);
|
||||
|
||||
return querySuitePath;
|
||||
}
|
||||
}
|
||||
|
||||
function createQuerySuiteContents(queries: string[]) {
|
||||
return queries.map((q: string) => `- query: ${q}`).join("\n");
|
||||
export function convertPackToQuerySuiteEntry(
|
||||
packStr: string
|
||||
): configUtils.QuerySuitePackEntry {
|
||||
const pack = configUtils.parsePacksSpecification(packStr);
|
||||
return {
|
||||
qlpack: !pack.path ? pack.name : undefined,
|
||||
from: pack.path ? pack.name : undefined,
|
||||
version: pack.version,
|
||||
query: pack.path?.endsWith(".ql") ? pack.path : undefined,
|
||||
queries:
|
||||
!pack.path?.endsWith(".ql") && !pack.path?.endsWith(".qls")
|
||||
? pack.path
|
||||
: undefined,
|
||||
apply: pack.path?.endsWith(".qls") ? pack.path : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export function createQuerySuiteContents(
|
||||
queries: string[],
|
||||
queryFilters: configUtils.QueryFilter[]
|
||||
) {
|
||||
return yaml.dump(
|
||||
queries.map((q: string) => ({ query: q })).concat(queryFilters as any)
|
||||
);
|
||||
}
|
||||
|
||||
export async function runFinalize(
|
||||
@@ -435,13 +466,8 @@ export async function runFinalize(
|
||||
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
|
||||
}
|
||||
|
||||
// After switching to Node16, this entire block can be replaced with `await fs.promises.rm(outputDir, { recursive: true, force: true });`.
|
||||
try {
|
||||
await fs.promises.rmdir(outputDir, {
|
||||
recursive: true,
|
||||
maxRetries: 5,
|
||||
retryDelay: 2000,
|
||||
} as any);
|
||||
await del(outputDir, { force: true });
|
||||
} catch (error: any) {
|
||||
if (error?.code !== "ENOENT") {
|
||||
throw error;
|
||||
@@ -509,3 +535,33 @@ function printLinesOfCodeSummary(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// exported for testing
|
||||
export function validateQueryFilters(queryFilters?: configUtils.QueryFilter[]) {
|
||||
if (!queryFilters) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const errors: string[] = [];
|
||||
for (const qf of queryFilters) {
|
||||
const keys = Object.keys(qf);
|
||||
if (keys.length !== 1) {
|
||||
errors.push(
|
||||
`Query filter must have exactly one key: ${JSON.stringify(qf)}`
|
||||
);
|
||||
}
|
||||
if (!["exclude", "include"].includes(keys[0])) {
|
||||
errors.push(
|
||||
`Only "include" or "exclude" filters are allowed:\n${JSON.stringify(
|
||||
qf
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
throw new Error(`Invalid query filter.\n${errors.join("\n")}`);
|
||||
}
|
||||
|
||||
return queryFilters;
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"maximumVersion": "3.5", "minimumVersion": "3.1"}
|
||||
{"maximumVersion": "3.6", "minimumVersion": "3.2"}
|
||||
|
||||
@@ -1572,6 +1572,60 @@ test(invalidPackNameMacro, "c/d@../a");
|
||||
test(invalidPackNameMacro, "c/d@b/../a");
|
||||
test(invalidPackNameMacro, "c/d:z@1");
|
||||
|
||||
/**
|
||||
* Test macro for pretty printing pack specs
|
||||
*/
|
||||
const packSpecPrettyPrintingMacro = test.macro({
|
||||
exec: (t: ExecutionContext, packStr: string, packObj: configUtils.Pack) => {
|
||||
const parsed = configUtils.parsePacksSpecification(packStr);
|
||||
t.deepEqual(parsed, packObj, "parsed pack spec is correct");
|
||||
const stringified = configUtils.prettyPrintPack(packObj);
|
||||
t.deepEqual(
|
||||
stringified,
|
||||
packStr.trim(),
|
||||
"pretty-printed pack spec is correct"
|
||||
);
|
||||
|
||||
t.deepEqual(
|
||||
configUtils.validatePackSpecification(packStr),
|
||||
packStr.trim(),
|
||||
"pack spec is valid"
|
||||
);
|
||||
},
|
||||
title: (
|
||||
_providedTitle: string | undefined,
|
||||
packStr: string,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
_packObj: configUtils.Pack
|
||||
) => `Prettyprint pack spec: '${packStr}'`,
|
||||
});
|
||||
|
||||
test(packSpecPrettyPrintingMacro, "a/b", {
|
||||
name: "a/b",
|
||||
version: undefined,
|
||||
path: undefined,
|
||||
});
|
||||
test(packSpecPrettyPrintingMacro, "a/b@~1.2.3", {
|
||||
name: "a/b",
|
||||
version: "~1.2.3",
|
||||
path: undefined,
|
||||
});
|
||||
test(packSpecPrettyPrintingMacro, "a/b@~1.2.3:abc/def", {
|
||||
name: "a/b",
|
||||
version: "~1.2.3",
|
||||
path: "abc/def",
|
||||
});
|
||||
test(packSpecPrettyPrintingMacro, "a/b:abc/def", {
|
||||
name: "a/b",
|
||||
version: undefined,
|
||||
path: "abc/def",
|
||||
});
|
||||
test(packSpecPrettyPrintingMacro, " a/b:abc/def ", {
|
||||
name: "a/b",
|
||||
version: undefined,
|
||||
path: "abc/def",
|
||||
});
|
||||
|
||||
/**
|
||||
* Test macro for testing the packs block and the packs input
|
||||
*/
|
||||
@@ -1865,3 +1919,23 @@ test(
|
||||
"security-and-quality",
|
||||
"0.0.1"
|
||||
);
|
||||
// Test that ML-powered queries are run on all platforms running `security-extended` on CodeQL
|
||||
// CLI 2.9.3+.
|
||||
test(
|
||||
mlPoweredQueriesMacro,
|
||||
"2.9.3",
|
||||
true,
|
||||
undefined,
|
||||
"security-extended",
|
||||
"~0.3.0"
|
||||
);
|
||||
// Test that ML-powered queries are run on all platforms running `security-and-quality` on CodeQL
|
||||
// CLI 2.9.3+.
|
||||
test(
|
||||
mlPoweredQueriesMacro,
|
||||
"2.9.3",
|
||||
true,
|
||||
undefined,
|
||||
"security-and-quality",
|
||||
"~0.3.0"
|
||||
);
|
||||
|
||||
@@ -49,8 +49,38 @@ export interface UserConfig {
|
||||
// language. If this is a single language analysis, then no split by
|
||||
// language is necessary.
|
||||
packs?: Record<string, string[]> | string[];
|
||||
|
||||
// Set of query filters to include and exclude extra queries based on
|
||||
// codeql query suite `include` and `exclude` properties
|
||||
"query-filters"?: QueryFilter[];
|
||||
}
|
||||
|
||||
export type QueryFilter = ExcludeQueryFilter | IncludeQueryFilter;
|
||||
|
||||
interface ExcludeQueryFilter {
|
||||
exclude: Record<string, string[] | string>;
|
||||
}
|
||||
|
||||
interface IncludeQueryFilter {
|
||||
include: Record<string, string[] | string>;
|
||||
}
|
||||
|
||||
export type QuerySuitePackEntry = {
|
||||
version?: string;
|
||||
} & (
|
||||
| {
|
||||
qlpack: string;
|
||||
}
|
||||
| {
|
||||
from?: string;
|
||||
query?: string;
|
||||
queries?: string;
|
||||
apply?: string;
|
||||
}
|
||||
);
|
||||
|
||||
export type QuerySuiteEntry = QuerySuitePackEntry | QueryFilter;
|
||||
|
||||
/**
|
||||
* Lists of query files for each language.
|
||||
* Will only contain .ql files and not other kinds of files,
|
||||
@@ -157,6 +187,12 @@ export interface Config {
|
||||
|
||||
export type Packs = Partial<Record<Language, string[]>>;
|
||||
|
||||
export interface Pack {
|
||||
name: string;
|
||||
version?: string;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of queries from https://github.com/github/codeql that
|
||||
* we don't want to run. Disabling them here is a quicker alternative to
|
||||
@@ -319,11 +355,7 @@ async function addBuiltinSuiteQueries(
|
||||
}
|
||||
|
||||
function isMlPoweredJsQueriesPack(pack: string) {
|
||||
return (
|
||||
pack === ML_POWERED_JS_QUERIES_PACK_NAME ||
|
||||
pack.startsWith(`${ML_POWERED_JS_QUERIES_PACK_NAME}@`) ||
|
||||
pack.startsWith(`${ML_POWERED_JS_QUERIES_PACK_NAME}:`)
|
||||
);
|
||||
return parsePacksSpecification(pack).name === ML_POWERED_JS_QUERIES_PACK_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1170,10 +1202,10 @@ export function parsePacksFromConfig(
|
||||
if (!languages.includes(lang as Language)) {
|
||||
throw new Error(getPacksRequireLanguage(lang, configFile));
|
||||
}
|
||||
packs[lang] = [];
|
||||
for (const packStr of packsArr) {
|
||||
packs[lang].push(validatePacksSpecification(packStr, configFile));
|
||||
}
|
||||
|
||||
packs[lang] = packsArr.map((packStr) =>
|
||||
validatePackSpecification(packStr, configFile)
|
||||
);
|
||||
}
|
||||
return packs;
|
||||
}
|
||||
@@ -1206,7 +1238,7 @@ function parsePacksFromInput(
|
||||
|
||||
return {
|
||||
[languages[0]]: packsInput.split(",").reduce((packs, pack) => {
|
||||
packs.push(validatePacksSpecification(pack, ""));
|
||||
packs.push(validatePackSpecification(pack));
|
||||
return packs;
|
||||
}, [] as string[]),
|
||||
};
|
||||
@@ -1230,10 +1262,10 @@ function parsePacksFromInput(
|
||||
* @param packStr the package specification to verify.
|
||||
* @param configFile Config file to use for error reporting
|
||||
*/
|
||||
export function validatePacksSpecification(
|
||||
export function parsePacksSpecification(
|
||||
packStr: string,
|
||||
configFile?: string
|
||||
): string {
|
||||
): Pack {
|
||||
if (typeof packStr !== "string") {
|
||||
throw new Error(getPacksStrInvalid(packStr, configFile));
|
||||
}
|
||||
@@ -1286,9 +1318,21 @@ export function validatePacksSpecification(
|
||||
throw new Error(getPacksStrInvalid(packStr, configFile));
|
||||
}
|
||||
|
||||
return (
|
||||
packName + (version ? `@${version}` : "") + (packPath ? `:${packPath}` : "")
|
||||
);
|
||||
return {
|
||||
name: packName,
|
||||
version,
|
||||
path: packPath,
|
||||
};
|
||||
}
|
||||
|
||||
export function prettyPrintPack(pack: Pack) {
|
||||
return `${pack.name}${pack.version ? `@${pack.version}` : ""}${
|
||||
pack.path ? `:${pack.path}` : ""
|
||||
}`;
|
||||
}
|
||||
|
||||
export function validatePackSpecification(pack: string, configFile?: string) {
|
||||
return prettyPrintPack(parsePacksSpecification(pack, configFile));
|
||||
}
|
||||
|
||||
// exported for testing
|
||||
@@ -1448,7 +1492,7 @@ function getLocalConfig(configFile: string, workspacePath: string): UserConfig {
|
||||
throw new Error(getConfigFileDoesNotExistErrorMessage(configFile));
|
||||
}
|
||||
|
||||
return yaml.load(fs.readFileSync(configFile, "utf8"));
|
||||
return yaml.load(fs.readFileSync(configFile, "utf8")) as UserConfig;
|
||||
}
|
||||
|
||||
async function getRemoteConfig(
|
||||
@@ -1483,7 +1527,9 @@ async function getRemoteConfig(
|
||||
throw new Error(getConfigFileFormatInvalidMessage(configFile));
|
||||
}
|
||||
|
||||
return yaml.load(Buffer.from(fileContents, "base64").toString("binary"));
|
||||
return yaml.load(
|
||||
Buffer.from(fileContents, "base64").toString("binary")
|
||||
) as UserConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"bundleVersion": "codeql-bundle-20220512"
|
||||
"bundleVersion": "codeql-bundle-20220615"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ export enum Language {
|
||||
javascript = "javascript",
|
||||
python = "python",
|
||||
ruby = "ruby",
|
||||
swift = "swift",
|
||||
}
|
||||
|
||||
// Additional names for languages
|
||||
@@ -37,7 +38,7 @@ export function parseLanguage(language: string): Language | undefined {
|
||||
|
||||
export function isTracedLanguage(language: Language): boolean {
|
||||
return (
|
||||
["cpp", "java", "csharp"].includes(language) ||
|
||||
["cpp", "java", "csharp", "swift"].includes(language) ||
|
||||
(process.env["CODEQL_EXTRACTOR_GO_BUILD_TRACING"] === "on" &&
|
||||
language === Language.go)
|
||||
);
|
||||
|
||||
@@ -298,13 +298,13 @@ const ML_POWERED_JS_STATUS_TESTS: Array<[string[], string]> = [
|
||||
// If no packs are loaded, status is false.
|
||||
[[], "false"],
|
||||
// If another pack is loaded but not the ML-powered query pack, status is false.
|
||||
[["someOtherPack"], "false"],
|
||||
[["some-other/pack"], "false"],
|
||||
// If the ML-powered query pack is loaded with a specific version, status is that version.
|
||||
[[`${util.ML_POWERED_JS_QUERIES_PACK_NAME}@~0.1.0`], "~0.1.0"],
|
||||
// If the ML-powered query pack is loaded with a specific version and another pack is loaded, the
|
||||
// status is the version of the ML-powered query pack.
|
||||
[
|
||||
["someOtherPack", `${util.ML_POWERED_JS_QUERIES_PACK_NAME}@~0.1.0`],
|
||||
["some-other/pack", `${util.ML_POWERED_JS_QUERIES_PACK_NAME}@~0.1.0`],
|
||||
"~0.1.0",
|
||||
],
|
||||
// If the ML-powered query pack is loaded without a version, the status is "latest".
|
||||
@@ -319,7 +319,7 @@ const ML_POWERED_JS_STATUS_TESTS: Array<[string[], string]> = [
|
||||
],
|
||||
// If the ML-powered query pack is loaded with no specific version, and another pack is loaded,
|
||||
// the status is "latest".
|
||||
[["someOtherPack", util.ML_POWERED_JS_QUERIES_PACK_NAME], "latest"],
|
||||
[["some-other/pack", util.ML_POWERED_JS_QUERIES_PACK_NAME], "latest"],
|
||||
];
|
||||
|
||||
for (const [packs, expectedStatus] of ML_POWERED_JS_STATUS_TESTS) {
|
||||
|
||||
29
src/util.ts
29
src/util.ts
@@ -11,7 +11,11 @@ import * as api from "./api-client";
|
||||
import { getApiClient, GitHubApiDetails } from "./api-client";
|
||||
import * as apiCompatibility from "./api-compatibility.json";
|
||||
import { CodeQL, CODEQL_VERSION_NEW_TRACING } from "./codeql";
|
||||
import { Config } from "./config-utils";
|
||||
import {
|
||||
Config,
|
||||
parsePacksSpecification,
|
||||
prettyPrintPack,
|
||||
} from "./config-utils";
|
||||
import { Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
|
||||
@@ -664,10 +668,18 @@ export const ML_POWERED_JS_QUERIES_PACK_NAME =
|
||||
export async function getMlPoweredJsQueriesPack(
|
||||
codeQL: CodeQL
|
||||
): Promise<string> {
|
||||
if (await codeQlVersionAbove(codeQL, "2.8.4")) {
|
||||
return `${ML_POWERED_JS_QUERIES_PACK_NAME}@~0.2.0`;
|
||||
let version;
|
||||
if (await codeQlVersionAbove(codeQL, "2.9.3")) {
|
||||
version = `~0.3.0`;
|
||||
} else if (await codeQlVersionAbove(codeQL, "2.8.4")) {
|
||||
version = `~0.2.0`;
|
||||
} else {
|
||||
version = `~0.1.0`;
|
||||
}
|
||||
return `${ML_POWERED_JS_QUERIES_PACK_NAME}@~0.1.0`;
|
||||
return prettyPrintPack({
|
||||
name: ML_POWERED_JS_QUERIES_PACK_NAME,
|
||||
version,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -693,11 +705,10 @@ export async function getMlPoweredJsQueriesPack(
|
||||
*/
|
||||
export function getMlPoweredJsQueriesStatus(config: Config): string {
|
||||
const mlPoweredJsQueryPacks = (config.packs.javascript || [])
|
||||
.map((pack) => pack.split("@"))
|
||||
.map((p) => parsePacksSpecification(p))
|
||||
.filter(
|
||||
(packNameVersion) =>
|
||||
packNameVersion[0] === "codeql/javascript-experimental-atm-queries" &&
|
||||
packNameVersion.length <= 2
|
||||
(pack) =>
|
||||
pack.name === "codeql/javascript-experimental-atm-queries" && !pack.path
|
||||
);
|
||||
switch (mlPoweredJsQueryPacks.length) {
|
||||
case 1:
|
||||
@@ -706,7 +717,7 @@ export function getMlPoweredJsQueriesStatus(config: Config): string {
|
||||
// with each version of the CodeQL Action. Therefore in practice we should only hit the
|
||||
// `latest` case here when customers have explicitly added the ML-powered query pack to their
|
||||
// CodeQL config.
|
||||
return mlPoweredJsQueryPacks[0][1] || "latest";
|
||||
return mlPoweredJsQueryPacks[0].version || "latest";
|
||||
case 0:
|
||||
return "false";
|
||||
default:
|
||||
|
||||
10
tests/multi-language-repo/.github/codeql/codeql-config-query-filters1.yml
vendored
Normal file
10
tests/multi-language-repo/.github/codeql/codeql-config-query-filters1.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
name: "Check SARIF for default queries with Single include, Single exclude"
|
||||
|
||||
query-filters:
|
||||
# This should run js/path-injection and js/zipslip
|
||||
- include:
|
||||
tags contain: external/cwe/cwe-022
|
||||
|
||||
# Removes js/path-injection
|
||||
- exclude:
|
||||
id: js/path-injection
|
||||
21
tests/multi-language-repo/.github/codeql/codeql-config-query-filters2.yml
vendored
Normal file
21
tests/multi-language-repo/.github/codeql/codeql-config-query-filters2.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: "Check SARIF for query packs with Single include, Single exclude"
|
||||
|
||||
disable-default-queries: true
|
||||
|
||||
packs:
|
||||
javascript:
|
||||
- codeql/javascript-queries
|
||||
- dsp-testing/codeql-pack1@1.0.0
|
||||
|
||||
query-filters:
|
||||
# This should run js/path-injection and js/zipslip
|
||||
- include:
|
||||
tags contain: external/cwe/cwe-022
|
||||
|
||||
# Removes js/path-injection
|
||||
- exclude:
|
||||
id: js/path-injection
|
||||
|
||||
# Query from extra pack
|
||||
- include:
|
||||
id: javascript/example/empty-or-one-block
|
||||
35
tests/multi-language-repo/.github/codeql/codeql-config-query-filters3.yml
vendored
Normal file
35
tests/multi-language-repo/.github/codeql/codeql-config-query-filters3.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: "Check SARIF for query packs and local queries with Single include, Single exclude"
|
||||
|
||||
disable-default-queries: true
|
||||
|
||||
queries:
|
||||
# Local query
|
||||
- name: Run an extra local query
|
||||
uses: ./codeql-qlpacks/javascript-qlpack/show_ifs.ql
|
||||
|
||||
# These queries are ignored
|
||||
- name: Ignored queries
|
||||
uses: ./codeql-qlpacks/complex-python-qlpack/rootAndBar.qls
|
||||
|
||||
|
||||
packs:
|
||||
javascript:
|
||||
- codeql/javascript-queries
|
||||
- dsp-testing/codeql-pack1@1.0.0
|
||||
|
||||
query-filters:
|
||||
# This should run js/path-injection and js/zipslip
|
||||
- include:
|
||||
tags contain: external/cwe/cwe-022
|
||||
|
||||
# Removes js/path-injection
|
||||
- exclude:
|
||||
id: js/path-injection
|
||||
|
||||
# Query from extra pack
|
||||
- include:
|
||||
id: javascript/example/empty-or-one-block
|
||||
|
||||
# Local query
|
||||
- include:
|
||||
id: inrepo-javascript-querypack/show-ifs
|
||||
Reference in New Issue
Block a user