Merge pull request #3378 from github/koesie10/ignore-more-location-indexes

Ignore more location indexes in SARIF comparison
This commit is contained in:
Koen Vlaswinkel
2024-02-21 10:37:47 +01:00
committed by GitHub
2 changed files with 420 additions and 21 deletions

View File

@@ -1,4 +1,29 @@
import type { Result } from "sarif";
import type { Location, Result } from "sarif";
function toCanonicalLocation(location: Location): Location {
if (location.physicalLocation?.artifactLocation?.index !== undefined) {
const canonicalLocation = {
...location,
};
canonicalLocation.physicalLocation = {
...canonicalLocation.physicalLocation,
};
canonicalLocation.physicalLocation.artifactLocation = {
...canonicalLocation.physicalLocation.artifactLocation,
};
// The index is dependent on the result of the SARIF file and usually doesn't really tell
// us anything useful, so we remove it from the comparison.
delete canonicalLocation.physicalLocation.artifactLocation.index;
return canonicalLocation;
}
// Don't create a new object if we don't need to
return location;
}
function toCanonicalResult(result: Result): Result {
const canonicalResult = {
@@ -6,29 +31,45 @@ function toCanonicalResult(result: Result): Result {
};
if (canonicalResult.locations) {
canonicalResult.locations = canonicalResult.locations.map((location) => {
if (location.physicalLocation?.artifactLocation?.index !== undefined) {
const canonicalLocation = {
...location,
canonicalResult.locations =
canonicalResult.locations.map(toCanonicalLocation);
}
if (canonicalResult.relatedLocations) {
canonicalResult.relatedLocations =
canonicalResult.relatedLocations.map(toCanonicalLocation);
}
if (canonicalResult.codeFlows) {
canonicalResult.codeFlows = canonicalResult.codeFlows.map((codeFlow) => {
if (codeFlow.threadFlows) {
return {
...codeFlow,
threadFlows: codeFlow.threadFlows.map((threadFlow) => {
if (threadFlow.locations) {
return {
...threadFlow,
locations: threadFlow.locations.map((threadFlowLocation) => {
if (threadFlowLocation.location) {
return {
...threadFlowLocation,
location: toCanonicalLocation(
threadFlowLocation.location,
),
};
}
return threadFlowLocation;
}),
};
}
return threadFlow;
}),
};
canonicalLocation.physicalLocation = {
...canonicalLocation.physicalLocation,
};
canonicalLocation.physicalLocation.artifactLocation = {
...canonicalLocation.physicalLocation.artifactLocation,
};
// The index is dependent on the result of the SARIF file and usually doesn't really tell
// us anything useful, so we remove it from the comparison.
delete canonicalLocation.physicalLocation.artifactLocation.index;
return canonicalLocation;
}
// Don't create a new object if we don't need to
return location;
return codeFlow;
});
}

View File

@@ -138,6 +138,364 @@ describe("sarifDiff", () => {
});
});
it("does not take into account the location index when in thread flows or related locations", () => {
const result1: Result = {
ruleId: "java/static-initialization-vector",
ruleIndex: 0,
rule: {
id: "java/static-initialization-vector",
index: 0,
},
message: {
text: "A [static initialization vector](1) should not be used for encryption.",
},
locations: [
{
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/sun/security/ssl/SSLCipher.java",
uriBaseId: "%SRCROOT%",
index: 126,
},
region: {
startLine: 1272,
startColumn: 55,
endColumn: 61,
},
},
},
],
partialFingerprints: {
primaryLocationLineHash: "9a2a0c085da38206:3",
primaryLocationStartColumnFingerprint: "38",
},
codeFlows: [
{
threadFlows: [
{
locations: [
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/sun/security/ssl/SSLCipher.java",
uriBaseId: "%SRCROOT%",
index: 126,
},
region: {
startLine: 1270,
startColumn: 50,
endColumn: 76,
},
},
message: {
text: "new byte[] : byte[]",
},
},
},
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/javax/crypto/spec/IvParameterSpec.java",
uriBaseId: "%SRCROOT%",
index: 12,
},
region: {
startLine: 52,
startColumn: 28,
endColumn: 37,
},
},
message: {
text: "iv : byte[]",
},
},
},
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/javax/crypto/spec/IvParameterSpec.java",
uriBaseId: "%SRCROOT%",
index: 12,
},
region: {
startLine: 53,
startColumn: 14,
endColumn: 16,
},
},
message: {
text: "iv : byte[]",
},
},
},
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/javax/crypto/spec/IvParameterSpec.java",
uriBaseId: "%SRCROOT%",
index: 12,
},
region: {
startLine: 53,
startColumn: 9,
endColumn: 32,
},
},
message: {
text: "this <constr(this)> [post update] : IvParameterSpec",
},
},
},
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/sun/security/ssl/SSLCipher.java",
uriBaseId: "%SRCROOT%",
index: 126,
},
region: {
startLine: 1270,
startColumn: 30,
endColumn: 77,
},
},
message: {
text: "new IvParameterSpec(...) : IvParameterSpec",
},
},
},
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/sun/security/ssl/SSLCipher.java",
uriBaseId: "%SRCROOT%",
index: 126,
},
region: {
startLine: 1272,
startColumn: 55,
endColumn: 61,
},
},
message: {
text: "params",
},
},
},
],
},
],
},
],
relatedLocations: [
{
id: 1,
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/sun/security/ssl/SSLCipher.java",
uriBaseId: "%SRCROOT%",
index: 126,
},
region: {
startLine: 1270,
startColumn: 50,
endColumn: 76,
},
},
message: {
text: "static initialization vector",
},
},
],
};
const result2: Result = {
ruleId: "java/static-initialization-vector",
ruleIndex: 0,
rule: {
id: "java/static-initialization-vector",
index: 0,
},
message: {
text: "A [static initialization vector](1) should not be used for encryption.",
},
locations: [
{
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/sun/security/ssl/SSLCipher.java",
uriBaseId: "%SRCROOT%",
index: 141,
},
region: {
startLine: 1272,
startColumn: 55,
endColumn: 61,
},
},
},
],
partialFingerprints: {
primaryLocationLineHash: "9a2a0c085da38206:3",
primaryLocationStartColumnFingerprint: "38",
},
codeFlows: [
{
threadFlows: [
{
locations: [
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/sun/security/ssl/SSLCipher.java",
uriBaseId: "%SRCROOT%",
index: 141,
},
region: {
startLine: 1270,
startColumn: 50,
endColumn: 76,
},
},
message: {
text: "new byte[] : byte[]",
},
},
},
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/javax/crypto/spec/IvParameterSpec.java",
uriBaseId: "%SRCROOT%",
index: 12,
},
region: {
startLine: 52,
startColumn: 28,
endColumn: 37,
},
},
message: {
text: "iv : byte[]",
},
},
},
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/javax/crypto/spec/IvParameterSpec.java",
uriBaseId: "%SRCROOT%",
index: 12,
},
region: {
startLine: 53,
startColumn: 14,
endColumn: 16,
},
},
message: {
text: "iv : byte[]",
},
},
},
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/javax/crypto/spec/IvParameterSpec.java",
uriBaseId: "%SRCROOT%",
index: 12,
},
region: {
startLine: 53,
startColumn: 9,
endColumn: 32,
},
},
message: {
text: "this <constr(this)> [post update] : IvParameterSpec",
},
},
},
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/sun/security/ssl/SSLCipher.java",
uriBaseId: "%SRCROOT%",
index: 141,
},
region: {
startLine: 1270,
startColumn: 30,
endColumn: 77,
},
},
message: {
text: "new IvParameterSpec(...) : IvParameterSpec",
},
},
},
{
location: {
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/sun/security/ssl/SSLCipher.java",
uriBaseId: "%SRCROOT%",
index: 141,
},
region: {
startLine: 1272,
startColumn: 55,
endColumn: 61,
},
},
message: {
text: "params",
},
},
},
],
},
],
},
],
relatedLocations: [
{
id: 1,
physicalLocation: {
artifactLocation: {
uri: "src/java.base/share/classes/sun/security/ssl/SSLCipher.java",
uriBaseId: "%SRCROOT%",
index: 141,
},
region: {
startLine: 1270,
startColumn: 50,
endColumn: 76,
},
},
message: {
text: "static initialization vector",
},
},
],
};
expect(sarifDiff([result1], [result2])).toEqual({
from: [],
to: [],
});
});
it("does not modify the input", () => {
const result1: Result = {
message: {