diff --git a/extensions/ql-vscode/src/databases/config/db-config-validator.ts b/extensions/ql-vscode/src/databases/config/db-config-validator.ts index dbfe1789c..a3401c99e 100644 --- a/extensions/ql-vscode/src/databases/config/db-config-validator.ts +++ b/extensions/ql-vscode/src/databases/config/db-config-validator.ts @@ -2,7 +2,7 @@ import { readJsonSync } from "fs-extra"; import { resolve } from "path"; import Ajv from "ajv"; import { clearLocalDbConfig, DbConfig } from "./db-config"; -import { findDuplicateStrings } from "../../text-utils"; +import { findDuplicateStrings } from "../../pure/text-utils"; import { DbConfigValidationError, DbConfigValidationErrorKind, diff --git a/extensions/ql-vscode/src/text-utils.ts b/extensions/ql-vscode/src/pure/text-utils.ts similarity index 100% rename from extensions/ql-vscode/src/text-utils.ts rename to extensions/ql-vscode/src/pure/text-utils.ts diff --git a/extensions/ql-vscode/src/remote-queries/export-results.ts b/extensions/ql-vscode/src/remote-queries/export-results.ts index afeed5c5a..76400e5b7 100644 --- a/extensions/ql-vscode/src/remote-queries/export-results.ts +++ b/extensions/ql-vscode/src/remote-queries/export-results.ts @@ -18,7 +18,7 @@ import { generateVariantAnalysisMarkdown, MarkdownFile, RepositorySummary, -} from "./remote-queries-markdown-generation"; +} from "./markdown-generation"; import { pluralize } from "../pure/word"; import { VariantAnalysisManager } from "./variant-analysis-manager"; import { assertNever } from "../pure/helpers-pure"; diff --git a/extensions/ql-vscode/src/remote-queries/remote-queries-markdown-generation.ts b/extensions/ql-vscode/src/remote-queries/markdown-generation.ts similarity index 96% rename from extensions/ql-vscode/src/remote-queries/remote-queries-markdown-generation.ts rename to extensions/ql-vscode/src/remote-queries/markdown-generation.ts index fd64fc3c7..272ee6f52 100644 --- a/extensions/ql-vscode/src/remote-queries/remote-queries-markdown-generation.ts +++ b/extensions/ql-vscode/src/remote-queries/markdown-generation.ts @@ -2,20 +2,20 @@ import { CellValue } from "../pure/bqrs-cli-types"; import { tryGetRemoteLocation } from "../pure/bqrs-utils"; import { createRemoteFileRef } from "../pure/location-link-utils"; import { parseHighlightedLine, shouldHighlightLine } from "../pure/sarif-utils"; -import { convertNonPrintableChars } from "../text-utils"; -import { +import { convertNonPrintableChars } from "../pure/text-utils"; +import type { AnalysisAlert, AnalysisRawResults, CodeSnippet, FileLink, HighlightedRegion, } from "./shared/analysis-result"; -import { +import type { VariantAnalysis, VariantAnalysisScannedRepository, VariantAnalysisScannedRepositoryResult, } from "./shared/variant-analysis"; -import { RepositoryWithMetadata } from "./shared/repository"; +import type { RepositoryWithMetadata } from "./shared/repository"; export type MarkdownLinkType = "local" | "gist"; @@ -39,7 +39,7 @@ export interface VariantAnalysisMarkdown { * Generates markdown files with variant analysis results. */ export async function generateVariantAnalysisMarkdown( - variantAnalysis: VariantAnalysis, + variantAnalysis: Pick, results: AsyncIterable< [VariantAnalysisScannedRepository, VariantAnalysisScannedRepositoryResult] >, @@ -91,7 +91,7 @@ export async function generateVariantAnalysisMarkdown( // Generate summary file with links to individual files const summaryFile: MarkdownFile = generateVariantAnalysisMarkdownSummary( - variantAnalysis, + variantAnalysis.query, summaries, linkType, ); @@ -103,20 +103,16 @@ export async function generateVariantAnalysisMarkdown( } export function generateVariantAnalysisMarkdownSummary( - variantAnalysis: VariantAnalysis, + query: VariantAnalysis["query"], summaries: RepositorySummary[], linkType: MarkdownLinkType, ): MarkdownFile { const lines: string[] = []; // Title - lines.push(`### Results for "${variantAnalysis.query.name}"`, ""); + lines.push(`### Results for "${query.name}"`, ""); // Expandable section containing query text - const queryCodeBlock = [ - "```ql", - ...variantAnalysis.query.text.split("\n"), - "```", - ]; + const queryCodeBlock = ["```ql", ...query.text.split("\n"), "```"]; lines.push(...buildExpandableMarkdownSection("Query", queryCodeBlock)); // Padding between sections diff --git a/extensions/ql-vscode/src/view/results/result-table-utils.tsx b/extensions/ql-vscode/src/view/results/result-table-utils.tsx index af1037dd1..7c75d4900 100644 --- a/extensions/ql-vscode/src/view/results/result-table-utils.tsx +++ b/extensions/ql-vscode/src/view/results/result-table-utils.tsx @@ -9,7 +9,7 @@ import { } from "../../pure/interface-types"; import { assertNever } from "../../pure/helpers-pure"; import { vscode } from "../vscode-api"; -import { convertNonPrintableChars } from "../../text-utils"; +import { convertNonPrintableChars } from "../../pure/text-utils"; import { sendTelemetry } from "../common/telemetry"; export interface ResultTableProps { diff --git a/extensions/ql-vscode/src/view/variant-analysis/RawResultsTable.tsx b/extensions/ql-vscode/src/view/variant-analysis/RawResultsTable.tsx index 9078651fc..3ebbde553 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/RawResultsTable.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/RawResultsTable.tsx @@ -9,7 +9,7 @@ import { } from "../../pure/bqrs-cli-types"; import { tryGetRemoteLocation } from "../../pure/bqrs-utils"; import TextButton from "../common/TextButton"; -import { convertNonPrintableChars } from "../../text-utils"; +import { convertNonPrintableChars } from "../../pure/text-utils"; import { sendTelemetry, useTelemetryOnChange } from "../common/telemetry"; const numOfResultsInContractedMode = 5; diff --git a/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/analyses-results.json b/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/analyses-results.json new file mode 100644 index 000000000..d5a339a58 --- /dev/null +++ b/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/analyses-results.json @@ -0,0 +1,756 @@ +[ + { + "repository": { + "id": 143040428, + "fullName": "github/codeql", + "private": false, + "stargazersCount": 5703, + "updatedAt": "2023-02-15T10:11:45Z" + }, + "analysisStatus": "succeeded", + "resultCount": 4, + "artifactSizeInBytes": 3785, + "interpretedResults": [ + { + "message": { + "tokens": [ + { + "t": "text", + "text": "This shell command depends on an uncontrolled " + }, + { + "t": "location", + "text": "absolute path", + "location": { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js" + }, + "highlightedRegion": { + "startLine": 4, + "startColumn": 35, + "endLine": 4, + "endColumn": 44 + } + } + }, + { "t": "text", "text": "." } + ] + }, + "shortDescription": "This shell command depends on an uncontrolled ,absolute path,.", + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js" + }, + "severity": "Warning", + "codeSnippet": { + "startLine": 3, + "endLine": 6, + "text": "function cleanupTemp() {\n let cmd = \"rm -rf \" + path.join(__dirname, \"temp\");\n cp.execSync(cmd); // BAD\n}\n" + }, + "highlightedRegion": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 18 + }, + "codeFlows": [ + { + "threadFlows": [ + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 2, + "endLine": 6, + "text": " path = require(\"path\");\nfunction cleanupTemp() {\n let cmd = \"rm -rf \" + path.join(__dirname, \"temp\");\n cp.execSync(cmd); // BAD\n}\n" + }, + "highlightedRegion": { + "startLine": 4, + "startColumn": 35, + "endLine": 4, + "endColumn": 44 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 2, + "endLine": 6, + "text": " path = require(\"path\");\nfunction cleanupTemp() {\n let cmd = \"rm -rf \" + path.join(__dirname, \"temp\");\n cp.execSync(cmd); // BAD\n}\n" + }, + "highlightedRegion": { + "startLine": 4, + "startColumn": 25, + "endLine": 4, + "endColumn": 53 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 2, + "endLine": 6, + "text": " path = require(\"path\");\nfunction cleanupTemp() {\n let cmd = \"rm -rf \" + path.join(__dirname, \"temp\");\n cp.execSync(cmd); // BAD\n}\n" + }, + "highlightedRegion": { + "startLine": 4, + "startColumn": 13, + "endLine": 4, + "endColumn": 53 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 2, + "endLine": 6, + "text": " path = require(\"path\");\nfunction cleanupTemp() {\n let cmd = \"rm -rf \" + path.join(__dirname, \"temp\");\n cp.execSync(cmd); // BAD\n}\n" + }, + "highlightedRegion": { + "startLine": 4, + "startColumn": 7, + "endLine": 4, + "endColumn": 53 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 3, + "endLine": 6, + "text": "function cleanupTemp() {\n let cmd = \"rm -rf \" + path.join(__dirname, \"temp\");\n cp.execSync(cmd); // BAD\n}\n" + }, + "highlightedRegion": { + "startLine": 5, + "startColumn": 15, + "endLine": 5, + "endColumn": 18 + } + } + ] + } + ] + }, + { + "message": { + "tokens": [ + { + "t": "text", + "text": "This shell command depends on an uncontrolled " + }, + { + "t": "location", + "text": "absolute path", + "location": { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "highlightedRegion": { + "startLine": 6, + "startColumn": 36, + "endLine": 6, + "endColumn": 45 + } + } + }, + { "t": "text", "text": "." } + ] + }, + "shortDescription": "This shell command depends on an uncontrolled ,absolute path,.", + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "severity": "Warning", + "codeSnippet": { + "startLine": 4, + "endLine": 8, + "text": "(function() {\n\tcp.execFileSync('rm', ['-rf', path.join(__dirname, \"temp\")]); // GOOD\n\tcp.execSync('rm -rf ' + path.join(__dirname, \"temp\")); // BAD\n\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n" + }, + "highlightedRegion": { + "startLine": 6, + "startColumn": 14, + "endLine": 6, + "endColumn": 54 + }, + "codeFlows": [ + { + "threadFlows": [ + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 4, + "endLine": 8, + "text": "(function() {\n\tcp.execFileSync('rm', ['-rf', path.join(__dirname, \"temp\")]); // GOOD\n\tcp.execSync('rm -rf ' + path.join(__dirname, \"temp\")); // BAD\n\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n" + }, + "highlightedRegion": { + "startLine": 6, + "startColumn": 36, + "endLine": 6, + "endColumn": 45 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 4, + "endLine": 8, + "text": "(function() {\n\tcp.execFileSync('rm', ['-rf', path.join(__dirname, \"temp\")]); // GOOD\n\tcp.execSync('rm -rf ' + path.join(__dirname, \"temp\")); // BAD\n\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n" + }, + "highlightedRegion": { + "startLine": 6, + "startColumn": 26, + "endLine": 6, + "endColumn": 54 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 4, + "endLine": 8, + "text": "(function() {\n\tcp.execFileSync('rm', ['-rf', path.join(__dirname, \"temp\")]); // GOOD\n\tcp.execSync('rm -rf ' + path.join(__dirname, \"temp\")); // BAD\n\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n" + }, + "highlightedRegion": { + "startLine": 6, + "startColumn": 14, + "endLine": 6, + "endColumn": 54 + } + } + ] + } + ] + }, + { + "message": { + "tokens": [ + { + "t": "text", + "text": "This shell command depends on an uncontrolled " + }, + { + "t": "location", + "text": "absolute path", + "location": { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "highlightedRegion": { + "startLine": 8, + "startColumn": 36, + "endLine": 8, + "endColumn": 45 + } + } + }, + { "t": "text", "text": "." } + ] + }, + "shortDescription": "This shell command depends on an uncontrolled ,absolute path,.", + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "severity": "Warning", + "codeSnippet": { + "startLine": 6, + "endLine": 10, + "text": "\tcp.execSync('rm -rf ' + path.join(__dirname, \"temp\")); // BAD\n\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\texeca.shellSync('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\n" + }, + "highlightedRegion": { + "startLine": 8, + "startColumn": 14, + "endLine": 8, + "endColumn": 54 + }, + "codeFlows": [ + { + "threadFlows": [ + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 6, + "endLine": 10, + "text": "\tcp.execSync('rm -rf ' + path.join(__dirname, \"temp\")); // BAD\n\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\texeca.shellSync('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\n" + }, + "highlightedRegion": { + "startLine": 8, + "startColumn": 36, + "endLine": 8, + "endColumn": 45 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 6, + "endLine": 10, + "text": "\tcp.execSync('rm -rf ' + path.join(__dirname, \"temp\")); // BAD\n\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\texeca.shellSync('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\n" + }, + "highlightedRegion": { + "startLine": 8, + "startColumn": 26, + "endLine": 8, + "endColumn": 54 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 6, + "endLine": 10, + "text": "\tcp.execSync('rm -rf ' + path.join(__dirname, \"temp\")); // BAD\n\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\texeca.shellSync('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\n" + }, + "highlightedRegion": { + "startLine": 8, + "startColumn": 14, + "endLine": 8, + "endColumn": 54 + } + } + ] + } + ] + }, + { + "message": { + "tokens": [ + { + "t": "text", + "text": "This shell command depends on an uncontrolled " + }, + { + "t": "location", + "text": "absolute path", + "location": { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "highlightedRegion": { + "startLine": 9, + "startColumn": 40, + "endLine": 9, + "endColumn": 49 + } + } + }, + { "t": "text", "text": "." } + ] + }, + "shortDescription": "This shell command depends on an uncontrolled ,absolute path,.", + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "severity": "Warning", + "codeSnippet": { + "startLine": 7, + "endLine": 11, + "text": "\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\texeca.shellSync('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\n\tconst safe = \"\\\"\" + path.join(__dirname, \"temp\") + \"\\\"\";\n" + }, + "highlightedRegion": { + "startLine": 9, + "startColumn": 18, + "endLine": 9, + "endColumn": 58 + }, + "codeFlows": [ + { + "threadFlows": [ + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 7, + "endLine": 11, + "text": "\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\texeca.shellSync('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\n\tconst safe = \"\\\"\" + path.join(__dirname, \"temp\") + \"\\\"\";\n" + }, + "highlightedRegion": { + "startLine": 9, + "startColumn": 40, + "endLine": 9, + "endColumn": 49 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 7, + "endLine": 11, + "text": "\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\texeca.shellSync('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\n\tconst safe = \"\\\"\" + path.join(__dirname, \"temp\") + \"\\\"\";\n" + }, + "highlightedRegion": { + "startLine": 9, + "startColumn": 30, + "endLine": 9, + "endColumn": 58 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b", + "filePath": "javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js" + }, + "codeSnippet": { + "startLine": 7, + "endLine": 11, + "text": "\n\texeca.shell('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\texeca.shellSync('rm -rf ' + path.join(__dirname, \"temp\")); // NOT OK\n\n\tconst safe = \"\\\"\" + path.join(__dirname, \"temp\") + \"\\\"\";\n" + }, + "highlightedRegion": { + "startLine": 9, + "startColumn": 18, + "endLine": 9, + "endColumn": 58 + } + } + ] + } + ] + } + ] + }, + { + "repository": { + "id": 23578923, + "fullName": "test/no-results", + "private": false, + "stargazersCount": 7289, + "updatedAt": "2023-01-01T00:00:00Z" + }, + "analysisStatus": "succeeded", + "resultCount": 0, + "artifactSizeInBytes": 100, + "interpretedResults": [] + }, + { + "repository": { + "id": 3214406, + "fullName": "meteor/meteor", + "private": false, + "stargazersCount": 43274, + "updatedAt": "2023-02-14T21:06:55Z" + }, + "analysisStatus": "succeeded", + "resultCount": 1, + "artifactSizeInBytes": 2378, + "interpretedResults": [ + { + "message": { + "tokens": [ + { + "t": "text", + "text": "This shell command depends on an uncontrolled " + }, + { + "t": "location", + "text": "absolute path", + "location": { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/config.js" + }, + "highlightedRegion": { + "startLine": 39, + "startColumn": 20, + "endLine": 39, + "endColumn": 61 + } + } + }, + { "t": "text", "text": "." } + ] + }, + "shortDescription": "This shell command depends on an uncontrolled ,absolute path,.", + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/install.js" + }, + "severity": "Warning", + "codeSnippet": { + "startLine": 257, + "endLine": 261, + "text": " if (isWindows()) {\n //set for the current session and beyond\n child_process.execSync(`setx path \"${meteorPath}/;%path%`);\n return;\n }\n" + }, + "highlightedRegion": { + "startLine": 259, + "startColumn": 28, + "endLine": 259, + "endColumn": 62 + }, + "codeFlows": [ + { + "threadFlows": [ + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/config.js" + }, + "codeSnippet": { + "startLine": 37, + "endLine": 41, + "text": "\nconst meteorLocalFolder = '.meteor';\nconst meteorPath = path.resolve(rootPath, meteorLocalFolder);\n\nmodule.exports = {\n" + }, + "highlightedRegion": { + "startLine": 39, + "startColumn": 20, + "endLine": 39, + "endColumn": 61 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/config.js" + }, + "codeSnippet": { + "startLine": 37, + "endLine": 41, + "text": "\nconst meteorLocalFolder = '.meteor';\nconst meteorPath = path.resolve(rootPath, meteorLocalFolder);\n\nmodule.exports = {\n" + }, + "highlightedRegion": { + "startLine": 39, + "startColumn": 7, + "endLine": 39, + "endColumn": 61 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/config.js" + }, + "codeSnippet": { + "startLine": 42, + "endLine": 46, + "text": " METEOR_LATEST_VERSION,\n extractPath: rootPath,\n meteorPath,\n release: process.env.INSTALL_METEOR_VERSION || METEOR_LATEST_VERSION,\n rootPath,\n" + }, + "highlightedRegion": { + "startLine": 44, + "startColumn": 3, + "endLine": 44, + "endColumn": 13 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/install.js" + }, + "codeSnippet": { + "startLine": 10, + "endLine": 14, + "text": "const os = require('os');\nconst {\n meteorPath,\n release,\n startedPath,\n" + }, + "highlightedRegion": { + "startLine": 12, + "startColumn": 3, + "endLine": 12, + "endColumn": 13 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/install.js" + }, + "codeSnippet": { + "startLine": 9, + "endLine": 25, + "text": "const tmp = require('tmp');\nconst os = require('os');\nconst {\n meteorPath,\n release,\n startedPath,\n extractPath,\n isWindows,\n rootPath,\n sudoUser,\n isSudo,\n isMac,\n METEOR_LATEST_VERSION,\n shouldSetupExecPath,\n} = require('./config.js');\nconst { uninstall } = require('./uninstall');\nconst {\n" + }, + "highlightedRegion": { + "startLine": 11, + "startColumn": 7, + "endLine": 23, + "endColumn": 27 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/install.js" + }, + "codeSnippet": { + "startLine": 257, + "endLine": 261, + "text": " if (isWindows()) {\n //set for the current session and beyond\n child_process.execSync(`setx path \"${meteorPath}/;%path%`);\n return;\n }\n" + }, + "highlightedRegion": { + "startLine": 259, + "startColumn": 42, + "endLine": 259, + "endColumn": 52 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/install.js" + }, + "codeSnippet": { + "startLine": 257, + "endLine": 261, + "text": " if (isWindows()) {\n //set for the current session and beyond\n child_process.execSync(`setx path \"${meteorPath}/;%path%`);\n return;\n }\n" + }, + "highlightedRegion": { + "startLine": 259, + "startColumn": 42, + "endLine": 259, + "endColumn": 52 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/install.js" + }, + "codeSnippet": { + "startLine": 257, + "endLine": 261, + "text": " if (isWindows()) {\n //set for the current session and beyond\n child_process.execSync(`setx path \"${meteorPath}/;%path%`);\n return;\n }\n" + }, + "highlightedRegion": { + "startLine": 259, + "startColumn": 42, + "endLine": 259, + "endColumn": 52 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/install.js" + }, + "codeSnippet": { + "startLine": 257, + "endLine": 261, + "text": " if (isWindows()) {\n //set for the current session and beyond\n child_process.execSync(`setx path \"${meteorPath}/;%path%`);\n return;\n }\n" + }, + "highlightedRegion": { + "startLine": 259, + "startColumn": 42, + "endLine": 259, + "endColumn": 52 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/install.js" + }, + "codeSnippet": { + "startLine": 257, + "endLine": 261, + "text": " if (isWindows()) {\n //set for the current session and beyond\n child_process.execSync(`setx path \"${meteorPath}/;%path%`);\n return;\n }\n" + }, + "highlightedRegion": { + "startLine": 259, + "startColumn": 42, + "endLine": 259, + "endColumn": 52 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/install.js" + }, + "codeSnippet": { + "startLine": 257, + "endLine": 261, + "text": " if (isWindows()) {\n //set for the current session and beyond\n child_process.execSync(`setx path \"${meteorPath}/;%path%`);\n return;\n }\n" + }, + "highlightedRegion": { + "startLine": 259, + "startColumn": 28, + "endLine": 259, + "endColumn": 62 + } + } + ] + }, + { + "threadFlows": [ + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/config.js" + }, + "codeSnippet": { + "startLine": 37, + "endLine": 41, + "text": "\nconst meteorLocalFolder = '.meteor';\nconst meteorPath = path.resolve(rootPath, meteorLocalFolder);\n\nmodule.exports = {\n" + }, + "highlightedRegion": { + "startLine": 39, + "startColumn": 20, + "endLine": 39, + "endColumn": 61 + } + }, + { + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec", + "filePath": "npm-packages/meteor-installer/install.js" + }, + "codeSnippet": { + "startLine": 257, + "endLine": 261, + "text": " if (isWindows()) {\n //set for the current session and beyond\n child_process.execSync(`setx path \"${meteorPath}/;%path%`);\n return;\n }\n" + }, + "highlightedRegion": { + "startLine": 259, + "startColumn": 28, + "endLine": 259, + "endColumn": 62 + } + } + ] + } + ] + } + ] + } +] diff --git a/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/expected/_summary.md b/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/expected/_summary.md new file mode 100644 index 000000000..ad1eca260 --- /dev/null +++ b/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/expected/_summary.md @@ -0,0 +1,49 @@ +### Results for "Shell command built from environment values" + +
+Query + +```ql +/** + * @name Shell command built from environment values + * @description Building a shell command string with values from the enclosing + * environment may cause subtle bugs or vulnerabilities. + * @kind path-problem + * @problem.severity warning + * @security-severity 6.3 + * @precision high + * @id js/shell-command-injection-from-environment + * @tags correctness + * security + * external/cwe/cwe-078 + * external/cwe/cwe-088 + */ + +import javascript +import DataFlow::PathGraph +import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentQuery + +from + Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node highlight, + Source sourceNode +where + sourceNode = source.getNode() and + cfg.hasFlowPath(source, sink) and + if cfg.isSinkWithHighlight(sink.getNode(), _) + then cfg.isSinkWithHighlight(sink.getNode(), highlight) + else highlight = sink.getNode() +select highlight, source, sink, "This shell command depends on an uncontrolled $@.", sourceNode, + sourceNode.getSourceType() + +``` + +
+ +
+ +### Summary + +| Repository | Results | +| --- | --- | +| github/codeql | [4 result(s)](#file-result-1-github-codeql-md) | +| meteor/meteor | [1 result(s)](#file-result-2-meteor-meteor-md) | diff --git a/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/expected/result-1-github-codeql.md b/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/expected/result-1-github-codeql.md new file mode 100644 index 000000000..cd8eeac28 --- /dev/null +++ b/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/expected/result-1-github-codeql.md @@ -0,0 +1,195 @@ +### github/codeql + +[javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js#L5-L5) + +
function cleanupTemp() {
+  let cmd = "rm -rf " + path.join(__dirname, "temp");
+  cp.execSync(cmd); // BAD
+}
+
+ +*This shell command depends on an uncontrolled [absolute path](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js#L4-L4).* + +#### Paths + +
+Path with 5 steps + +1. [javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js#L4-L4) +
  path = require("path");
+   function cleanupTemp() {
+     let cmd = "rm -rf " + path.join(__dirname, "temp");
+     cp.execSync(cmd); // BAD
+   }
+   
+ +2. [javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js#L4-L4) +
  path = require("path");
+   function cleanupTemp() {
+     let cmd = "rm -rf " + path.join(__dirname, "temp");
+     cp.execSync(cmd); // BAD
+   }
+   
+ +3. [javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js#L4-L4) +
  path = require("path");
+   function cleanupTemp() {
+     let cmd = "rm -rf " + path.join(__dirname, "temp");
+     cp.execSync(cmd); // BAD
+   }
+   
+ +4. [javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js#L4-L4) +
  path = require("path");
+   function cleanupTemp() {
+     let cmd = "rm -rf " + path.join(__dirname, "temp");
+     cp.execSync(cmd); // BAD
+   }
+   
+ +5. [javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/src/Security/CWE-078/examples/shell-command-injection-from-environment.js#L5-L5) +
function cleanupTemp() {
+     let cmd = "rm -rf " + path.join(__dirname, "temp");
+     cp.execSync(cmd); // BAD
+   }
+   
+ + +
+ +---------------------------------------- + +[javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L6-L6) + +
(function() {
+	cp.execFileSync('rm',  ['-rf', path.join(__dirname, "temp")]); // GOOD
+	cp.execSync('rm -rf ' + path.join(__dirname, "temp")); // BAD
+
+	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+
+ +*This shell command depends on an uncontrolled [absolute path](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L6-L6).* + +#### Paths + +
+Path with 3 steps + +1. [javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L6-L6) +
(function() {
+   	cp.execFileSync('rm',  ['-rf', path.join(__dirname, "temp")]); // GOOD
+   	cp.execSync('rm -rf ' + path.join(__dirname, "temp")); // BAD
+   
+   	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   
+ +2. [javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L6-L6) +
(function() {
+   	cp.execFileSync('rm',  ['-rf', path.join(__dirname, "temp")]); // GOOD
+   	cp.execSync('rm -rf ' + path.join(__dirname, "temp")); // BAD
+   
+   	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   
+ +3. [javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L6-L6) +
(function() {
+   	cp.execFileSync('rm',  ['-rf', path.join(__dirname, "temp")]); // GOOD
+   	cp.execSync('rm -rf ' + path.join(__dirname, "temp")); // BAD
+   
+   	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   
+ + +
+ +---------------------------------------- + +[javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L8-L8) + +
	cp.execSync('rm -rf ' + path.join(__dirname, "temp")); // BAD
+
+	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+	execa.shellSync('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+
+
+ +*This shell command depends on an uncontrolled [absolute path](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L8-L8).* + +#### Paths + +
+Path with 3 steps + +1. [javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L8-L8) +
	cp.execSync('rm -rf ' + path.join(__dirname, "temp")); // BAD
+   
+   	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   	execa.shellSync('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   
+   
+ +2. [javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L8-L8) +
	cp.execSync('rm -rf ' + path.join(__dirname, "temp")); // BAD
+   
+   	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   	execa.shellSync('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   
+   
+ +3. [javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L8-L8) +
	cp.execSync('rm -rf ' + path.join(__dirname, "temp")); // BAD
+   
+   	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   	execa.shellSync('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   
+   
+ + +
+ +---------------------------------------- + +[javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L9-L9) + +

+	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+	execa.shellSync('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+
+	const safe = "\"" + path.join(__dirname, "temp") + "\"";
+
+ +*This shell command depends on an uncontrolled [absolute path](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L9-L9).* + +#### Paths + +
+Path with 3 steps + +1. [javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L9-L9) +

+   	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   	execa.shellSync('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   
+   	const safe = "\"" + path.join(__dirname, "temp") + "\"";
+   
+ +2. [javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L9-L9) +

+   	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   	execa.shellSync('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   
+   	const safe = "\"" + path.join(__dirname, "temp") + "\"";
+   
+ +3. [javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js](https://github.com/github/codeql/blob/48015e5a2e6202131f2d1062cc066dc33ed69a9b/javascript/ql/test/query-tests/Security/CWE-078/tst_shell-command-injection-from-environment.js#L9-L9) +

+   	execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   	execa.shellSync('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
+   
+   	const safe = "\"" + path.join(__dirname, "temp") + "\"";
+   
+ + +
+ +---------------------------------------- diff --git a/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/expected/result-2-meteor-meteor.md b/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/expected/result-2-meteor-meteor.md new file mode 100644 index 000000000..6a216f144 --- /dev/null +++ b/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/path-problem/expected/result-2-meteor-meteor.md @@ -0,0 +1,144 @@ +### meteor/meteor + +[npm-packages/meteor-installer/install.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/install.js#L259-L259) + +
  if (isWindows()) {
+    //set for the current session and beyond
+    child_process.execSync(`setx path "${meteorPath}/;%path%`);
+    return;
+  }
+
+ +*This shell command depends on an uncontrolled [absolute path](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/config.js#L39-L39).* + +#### Paths + +
+Path with 11 steps + +1. [npm-packages/meteor-installer/config.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/config.js#L39-L39) +

+   const meteorLocalFolder = '.meteor';
+   const meteorPath = path.resolve(rootPath, meteorLocalFolder);
+   
+   module.exports = {
+   
+ +2. [npm-packages/meteor-installer/config.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/config.js#L39-L39) +

+   const meteorLocalFolder = '.meteor';
+   const meteorPath = path.resolve(rootPath, meteorLocalFolder);
+   
+   module.exports = {
+   
+ +3. [npm-packages/meteor-installer/config.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/config.js#L44-L44) +
  METEOR_LATEST_VERSION,
+     extractPath: rootPath,
+     meteorPath,
+     release: process.env.INSTALL_METEOR_VERSION || METEOR_LATEST_VERSION,
+     rootPath,
+   
+ +4. [npm-packages/meteor-installer/install.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/install.js#L12-L12) +
const os = require('os');
+   const {
+     meteorPath,
+     release,
+     startedPath,
+   
+ +5. [npm-packages/meteor-installer/install.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/install.js#L11-L23) +
const tmp = require('tmp');
+   const os = require('os');
+   const {
+     meteorPath,
+     release,
+     startedPath,
+     extractPath,
+     isWindows,
+     rootPath,
+     sudoUser,
+     isSudo,
+     isMac,
+     METEOR_LATEST_VERSION,
+     shouldSetupExecPath,
+   } = require('./config.js');
+   const { uninstall } = require('./uninstall');
+   const {
+   
+ +6. [npm-packages/meteor-installer/install.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/install.js#L259-L259) +
  if (isWindows()) {
+       //set for the current session and beyond
+       child_process.execSync(`setx path "${meteorPath}/;%path%`);
+       return;
+     }
+   
+ +7. [npm-packages/meteor-installer/install.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/install.js#L259-L259) +
  if (isWindows()) {
+       //set for the current session and beyond
+       child_process.execSync(`setx path "${meteorPath}/;%path%`);
+       return;
+     }
+   
+ +8. [npm-packages/meteor-installer/install.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/install.js#L259-L259) +
  if (isWindows()) {
+       //set for the current session and beyond
+       child_process.execSync(`setx path "${meteorPath}/;%path%`);
+       return;
+     }
+   
+ +9. [npm-packages/meteor-installer/install.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/install.js#L259-L259) +
  if (isWindows()) {
+       //set for the current session and beyond
+       child_process.execSync(`setx path "${meteorPath}/;%path%`);
+       return;
+     }
+   
+ +10. [npm-packages/meteor-installer/install.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/install.js#L259-L259) +
  if (isWindows()) {
+        //set for the current session and beyond
+        child_process.execSync(`setx path "${meteorPath}/;%path%`);
+        return;
+      }
+    
+ +11. [npm-packages/meteor-installer/install.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/install.js#L259-L259) +
  if (isWindows()) {
+        //set for the current session and beyond
+        child_process.execSync(`setx path "${meteorPath}/;%path%`);
+        return;
+      }
+    
+ + +
+ +
+Path with 2 steps + +1. [npm-packages/meteor-installer/config.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/config.js#L39-L39) +

+   const meteorLocalFolder = '.meteor';
+   const meteorPath = path.resolve(rootPath, meteorLocalFolder);
+   
+   module.exports = {
+   
+ +2. [npm-packages/meteor-installer/install.js](https://github.com/meteor/meteor/blob/73b538fe201cbfe89dd0c709689023f9b3eab1ec/npm-packages/meteor-installer/install.js#L259-L259) +
  if (isWindows()) {
+       //set for the current session and beyond
+       child_process.execSync(`setx path "${meteorPath}/;%path%`);
+       return;
+     }
+   
+ + +
+ +---------------------------------------- diff --git a/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/problem/analyses-results.json b/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/problem/analyses-results.json new file mode 100644 index 000000000..b8db420bf --- /dev/null +++ b/extensions/ql-vscode/test/unit-tests/data/markdown-generation/interpreted-results/problem/analyses-results.json @@ -0,0 +1,198 @@ +[ + { + "repository": { + "id": 143040428, + "fullName": "github/codeql", + "private": false, + "stargazersCount": 5703, + "updatedAt": "2023-02-15T10:11:45Z" + }, + "analysisStatus": "succeeded", + "resultCount": 1, + "artifactSizeInBytes": 1038, + "interpretedResults": [ + { + "message": { + "tokens": [ + { + "t": "text", + "text": "This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'aa'." + } + ] + }, + "shortDescription": "This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'aa'.", + "fileLink": { + "fileLinkPrefix": "https://github.com/github/codeql/blob/d094bbc06d063d0da8d0303676943c345e61de53", + "filePath": "javascript/extractor/tests/regexp/input/multipart.js" + }, + "severity": "Warning", + "codeSnippet": { + "startLine": 15, + "endLine": 22, + "text": "\nvar bad95 = new RegExp(\n \"(a\" + \n \"|\" + \n \"aa)*\" + \n \"b$\"\n);\n\n" + }, + "highlightedRegion": { + "startLine": 17, + "startColumn": 6, + "endLine": 20, + "endColumn": 6 + }, + "codeFlows": [] + } + ] + }, + { + "repository": { + "id": 3214406, + "fullName": "meteor/meteor", + "private": false, + "stargazersCount": 43274, + "updatedAt": "2023-02-14T21:06:55Z" + }, + "analysisStatus": "succeeded", + "resultCount": 5, + "artifactSizeInBytes": 3478, + "interpretedResults": [ + { + "message": { + "tokens": [ + { + "t": "text", + "text": "This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '----'." + } + ] + }, + "shortDescription": "This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '----'.", + "fileLink": { + "fileLinkPrefix": "https://github.com/meteor/meteor/blob/53f3c4442d3542d3d2a012a854472a0d1bef9d12", + "filePath": "packages/deprecated/markdown/showdown.js" + }, + "severity": "Warning", + "codeSnippet": { + "startLine": 413, + "endLine": 417, + "text": "\t\t/g,hashElement);\n\t*/\n\ttext = text.replace(/(\\n\\n[ ]{0,3}[ \\t]*(?=\\n{2,}))/g,hashElement);\n\n\t// PHP and ASP-style processor instructions ( and <%...%>)\n" + }, + "highlightedRegion": { + "startLine": 415, + "startColumn": 41, + "endLine": 415, + "endColumn": 48 + }, + "codeFlows": [] + }, + { + "message": { + "tokens": [ + { + "t": "text", + "text": "This part of the regular expression may cause exponential backtracking on strings starting with '