Skip to content

Commit b238f69

Browse files
authored
fix: fix layer highlights for Dockerfiles (#8)
1 parent 01c451c commit b238f69

9 files changed

Lines changed: 63 additions & 22 deletions

File tree

package-lock.json

Lines changed: 28 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"publisher": "sysdig",
44
"displayName": "Sysdig Scanner",
55
"description": "Sysdig Scanner for Visual Studio Code",
6-
"version": "0.2.6",
6+
"version": "0.2.7",
77
"icon": "img/logo.png",
88
"repository": "https://github.com/sysdiglabs/vscode-extension",
99
"engines": {

src/fileScanners/Dockerfile/dockerfileScanner.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export async function scanDockerfile(document: vscode.TextDocument, buildAndScan
3131
if (!report) {
3232
vscode.window.showErrorMessage('Failed to scan base image ' + baseImage);
3333
} else {
34-
highlightImage(report, baseImage, document, baseImageRange);
34+
highlightImage(report, document, baseImageRange);
3535
}
3636
}
3737

@@ -51,7 +51,7 @@ export async function scanDockerfile(document: vscode.TextDocument, buildAndScan
5151
const isBuilt = await imageExists(imageName);
5252
if (buildResult && isBuilt) {
5353
// 3. Scan the built image
54-
report = await vscode.commands.executeCommand('sysdig-vscode-ext.scanImage', imageName, /* updateTrees: */ true, /* source: */ document, baseImageRange);
54+
report = await vscode.commands.executeCommand('sysdig-vscode-ext.scanImage', imageName, /* updateTrees: */ true, /* source: */ document);
5555
if (!report) {
5656
vscode.window.showErrorMessage('Failed to scan built image ' + imageName);
5757
} else if (!report.result.layers) {

src/fileScanners/docker-compose/dockercomposeScanner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export async function scanComposeFile(document: vscode.TextDocument) {
1818
continue;
1919
}
2020

21-
highlightImage(report, image, document, range);
21+
highlightImage(report, document, range);
2222
}
2323
}
2424

src/fileScanners/highlighters.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
22
import { createMarkdownSummary, Report } from '../types';
33
import { Instruction } from 'dockerfile-ast';
44
import { createMarkdownVulnsForLayer } from '../types/report';
5+
import { vulnTreeDataProvider } from '../extension';
56

67
interface DecorationsMap {
78
[key: string]: [
@@ -55,7 +56,7 @@ export function clearDecorations(document: vscode.TextDocument) {
5556
}
5657
}
5758

58-
export function highlightImage(report: Report, image: string, document: vscode.TextDocument, baseImageRange?: vscode.Range) {
59+
export function highlightImage(report: Report, document: vscode.TextDocument, baseImageRange?: vscode.Range) {
5960
if (!baseImageRange) {
6061
return;
6162
}
@@ -95,14 +96,17 @@ export function highlightLayer(report: Report, instructions : Instruction[], doc
9596
let instructionIndex = instructions.length - 1;
9697
let layerIndex = layers.length - 1;
9798
let decorations : vscode.DecorationOptions[] = [];
98-
99+
let imageRange : vscode.Range | undefined;
100+
let layerRanges : Map<string, vscode.Range> = new Map<string, vscode.Range>();
101+
99102
while (instructionIndex >= 0 && layerIndex >= 0) {
100103
const instruction = instructions[instructionIndex];
101104
const layer = layers[layerIndex];
102105

103106
// Skip FROM instructions as base image is already scanned
104107
if (instruction.getInstruction() === 'FROM') {
105108
instructionIndex = -1;
109+
imageRange = instruction.getRange() as vscode.Range;
106110
break;
107111
}
108112

@@ -150,6 +154,10 @@ export function highlightLayer(report: Report, instructions : Instruction[], doc
150154
}
151155
};
152156

157+
if (layer.digest) {
158+
layerRanges = layerRanges.set(layer.digest, instruction.getRange() as vscode.Range);
159+
}
160+
153161
decorations.push(decorationOptions);
154162
}
155163
}
@@ -160,6 +168,8 @@ export function highlightLayer(report: Report, instructions : Instruction[], doc
160168
});
161169

162170
addDecorations(document, decorations, decorationType);
171+
172+
vulnTreeDataProvider.updateVulnTree(report.result.packages, report.info.resultUrl, document, imageRange, layerRanges);
163173
}
164174

165175
export function grepString(document: vscode.TextDocument, searchString: string): vscode.Range[] | undefined {

src/fileScanners/kubernetes-yaml/kubernetesScanner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export async function scanKubernetesFile(document: vscode.TextDocument) {
3434
}
3535

3636
scannedImages.push(image);
37-
highlightImage(report, image, document);
37+
highlightImage(report, document);
3838
}
3939
}
4040

src/fileScanners/test/highlighters.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ suite('Highlighters Tests', () => {
9090
editBuilder.insert(new vscode.Position(0, 0), image);
9191
});
9292

93-
highlightImage(report, image, document, range);
93+
highlightImage(report, document, range);
9494

9595
assert.deepEqual(decorationsMap[document.uri.toString()][0].decorations as vscode.DecorationOptions[], expectedDecorations);
9696
});
@@ -248,7 +248,7 @@ suite('Highlighters Tests', () => {
248248
}
249249
};
250250
const image = 'not-found-image';
251-
highlightImage(report, image, document);
251+
highlightImage(report, document);
252252

253253
assert.equal(decorationsMap[document.uri.toString()], undefined);
254254
});

src/runners/vmScanRunner.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export async function runScan(context: vscode.ExtensionContext, binaryPath: stri
6565
let outputScanFile : string = `${tempDir}/${VM_SCAN_FILE}`;
6666
let dbPath : string = `${tempDir}/main.db`;
6767
let cachePath : string = `${tempDir}/cache`;
68-
let skipUpload : boolean = !(configuration.get('vulnerabilityManagement.uploadResults') || false) || imageOverride !== undefined;
68+
let skipUpload : boolean = !(configuration.get('vulnerabilityManagement.uploadResults') || false);
6969
let policies : Array<string> = configuration.get('vulnerabilityManagement.addPolicies') || [];
7070
let imageToScan : string = imageOverride || configuration.get('vulnerabilityManagement.imageToScan') || "";
7171
let standalone : string = configuration.get('vulnerabilityManagement.standaloneMode') || "Never";
@@ -164,10 +164,14 @@ function updateVulnerabilities(statusBar: vscode.StatusBarItem, report: Report,
164164
statusBar.text = `$(shield) C ${summary.critical} H ${summary.high} M ${summary.medium} L ${summary.low} N ${summary.negligible}`;
165165
statusBar.show();
166166

167-
vulnTreeDataProvider.updateVulnTree(report.result.packages, report.info.resultUrl, report.result.layers, source, range);
167+
168+
vulnTreeDataProvider.updateVulnTree(report.result.packages, report.info.resultUrl, source, range);
168169
policyTreeDataProvider.addPolicies(report.result.policyEvaluations || []);
169170
if (source) {
170-
clearDecorations(source);
171-
highlightImage(report, "", source, range);
171+
if (range) { /* If new highlight range is provided, clear the previous decorations */
172+
clearDecorations(source);
173+
} /* If not, just add upon the previous decorations */
174+
175+
highlightImage(report, source, range);
172176
}
173177
}

src/trees/treeVulns.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import * as vscode from 'vscode';
33
import {
44
Vulnerability, vulnToColor, vulnToMarkdownString, doesVulnPassFilter,
55
Package, sortPackages,
6-
Layer
76
} from '../types';
87

98
export class VulnTreeItem extends vscode.TreeItem {
@@ -78,8 +77,8 @@ export class VulnTreeDataProvider implements vscode.TreeDataProvider<VulnTreeIte
7877

7978
private backlink : string = "";
8079
private source : vscode.TextDocument | undefined = undefined;
81-
private range: vscode.Range | undefined = undefined;
82-
private layers : Layer[] | undefined;
80+
private imageRange: vscode.Range | undefined = undefined;
81+
private ranges: Map<string, vscode.Range> | undefined = undefined;
8382

8483
constructor(source? : vscode.TextDocument) {
8584
this.source = source;
@@ -150,8 +149,9 @@ export class VulnTreeDataProvider implements vscode.TreeDataProvider<VulnTreeIte
150149

151150
// Filter out packages without vulnerabilities
152151
return Promise.resolve(this.filteredPackages.map(pkg => {
153-
if (this.source && pkg.layerDigest && this.layers) {
154-
return new TreePackage(pkg, undefined, undefined, this.source, this.range);
152+
if (this.source && pkg.layerDigest) {
153+
const range = this.ranges?.get(pkg.layerDigest) || this.imageRange;
154+
return new TreePackage(pkg, undefined, undefined, this.source, range);
155155
} else {
156156
return new TreePackage(pkg);
157157
}
@@ -164,10 +164,10 @@ export class VulnTreeDataProvider implements vscode.TreeDataProvider<VulnTreeIte
164164
}
165165
}
166166

167-
updateVulnTree(packages: Package[], backlink: string, layers?: Layer[], source?: vscode.TextDocument, range?: vscode.Range) {
168-
this.layers = layers;
167+
updateVulnTree(packages: Package[], backlink: string, source?: vscode.TextDocument, imageRange?: vscode.Range, layerRanges?: Map<string, vscode.Range>) {
169168
this.source = source;
170-
this.range = range;
169+
this.imageRange = imageRange;
170+
this.ranges = layerRanges;
171171
this.addPackages(packages);
172172
vscode.commands.executeCommand('setContext', 'sysdig-vscode-ext.showBacklink', false);
173173

0 commit comments

Comments
 (0)