Merge pull request #1827 from github/koesie10/filter-sarif-snippets

Limit SARIF code snippet size
This commit is contained in:
Koen Vlaswinkel
2022-12-02 18:46:19 +01:00
committed by GitHub
3 changed files with 76 additions and 6 deletions

View File

@@ -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 {

View File

@@ -1,5 +1,6 @@
import * as sarif from "sarif";
import {
parseHighlightedLine,
parseSarifPlainTextMessage,
parseSarifRegion,
} from "../pure/sarif-utils";
@@ -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(
@@ -163,17 +169,44 @@ export function tryGetRule(
}
function getCodeSnippet(
contextRegion?: sarif.Region,
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,

View File

@@ -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) {