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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion extensions/ql-vscode/src/pure/sarif-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as Sarif from "sarif";
import { HighlightedRegion } from "../remote-queries/shared/analysis-result";
import type { HighlightedRegion } from "../remote-queries/shared/analysis-result";
import { ResolvableLocationValue } from "./bqrs-cli-types";

export interface SarifLink {
Expand Down
43 changes: 38 additions & 5 deletions extensions/ql-vscode/src/remote-queries/sarif-processing.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as sarif from "sarif";
import {
parseHighlightedLine,
parseSarifPlainTextMessage,
parseSarifRegion,
} from "../pure/sarif-utils";
Expand All @@ -15,6 +16,11 @@ import {
HighlightedRegion,
} from "./shared/analysis-result";

// A line of more than 8k characters is probably generated.
const CODE_SNIPPET_LARGE_LINE_SIZE_LIMIT = 8192;
// If less than 1% of the line is highlighted, we consider it a small snippet.
const CODE_SNIPPET_HIGHLIGHTED_REGION_MINIMUM_RATIO = 0.01;

const defaultSeverity = "Warning";

export function extractAnalysisAlerts(
Expand Down Expand Up @@ -163,17 +169,44 @@ export function tryGetRule(
}

function getCodeSnippet(
contextRegion?: sarif.Region,
Comment thread
koesie10 marked this conversation as resolved.
region?: sarif.Region,
alternateRegion?: sarif.Region,
): CodeSnippet | undefined {
region = region ?? alternateRegion;
const actualRegion = contextRegion ?? region;

if (!region) {
if (!actualRegion) {
return undefined;
}

const text = region.snippet?.text || "";
const { startLine, endLine } = parseSarifRegion(region);
const text = actualRegion.snippet?.text || "";
const { startLine, endLine } = parseSarifRegion(actualRegion);

if (
contextRegion &&
region &&
text.length > CODE_SNIPPET_LARGE_LINE_SIZE_LIMIT
) {
const code = text.split("\n");

const highlightedRegion = parseSarifRegion(region);

const highlightedLines = code.map((line, index) => {
return parseHighlightedLine(line, startLine + index, highlightedRegion);
});

const highlightedCharactersCount = highlightedLines.reduce(
(a, line) => a + line.highlightedSection.length,
0,
);

const highlightedRatio = highlightedCharactersCount / text.length;

if (highlightedRatio < CODE_SNIPPET_HIGHLIGHTED_REGION_MINIMUM_RATIO) {
// If not enough is highlighted and the snippet is large, it's probably generated or bundled code and
// we don't want to show it.
return undefined;
}
}

return {
startLine,
Expand Down
37 changes: 37 additions & 0 deletions extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,43 @@ describe("SARIF processing", () => {
expect(message.tokens[2].t).toBe("text");
expect(message.tokens[2].text).toBe(".");
});

it("should not include snippets for large snippets", () => {
const sarif = buildValidSarifLog();
// Build string of 10 kilobytes
const snippet = new Array(10 * 1024).fill("a").join("");
sarif.runs![0]!.results![0]!.locations![0]!.physicalLocation!.contextRegion!.snippet =
{
text: snippet,
};

const result = extractAnalysisAlerts(sarif, fakefileLinkPrefix);

const actualCodeSnippet = result.alerts[0].codeSnippet;

expect(result).toBeTruthy();
expectNoParsingError(result);
expect(actualCodeSnippet).toBeUndefined();
});

it("should include snippets for large snippets which are relevant", () => {
const sarif = buildValidSarifLog();
// Build string of 10 kilobytes
const snippet = new Array(10 * 1024).fill("a").join("");
sarif.runs![0]!.results![0]!.locations![0]!.physicalLocation!.contextRegion!.snippet =
{
text: snippet,
};
sarif.runs![0]!.results![0]!.locations![0]!.physicalLocation!.region!.endColumn = 1000;

const result = extractAnalysisAlerts(sarif, fakefileLinkPrefix);

const actualCodeSnippet = result.alerts[0].codeSnippet;

expect(result).toBeTruthy();
expectNoParsingError(result);
expect(actualCodeSnippet).not.toBeUndefined();
});
});

function expectResultParsingError(msg: string) {
Expand Down