Skip to content

Commit 66cda90

Browse files
authored
fix(extractor): implement two-pass OCI extraction and fix path normalization
This commit resolves a long-standing issue where OCI archives (and the "hybrid" format produced by Docker Desktop's containerd store) would fail to scan silently. Root Cause: The previous implementation attempted to pipe a single blob stream to both a JSON parser and a tar extractor simultaneously. This resulted in stream corruption, causing both parsers to fail and the plugin to swallow errors, ultimately returning zero results to the CLI. Changes: - Implemented a two-pass extraction strategy: 1. Pass 1: Scans the archive to extract only JSON metadata (manifests, configs). 2. Pass 2: Re-opens the archive to extract only the layers needed for the target platform. - Robust Path Parsing: Added .filter(Boolean) to path splitting logic to gracefully handle archives using absolute paths (starting with /). - Code Cleanup: Removed the unused platformInfo return variable as identified during review. Impact: - Successfully restores scanning functionality for images like ubuntu:latest and mongo:8.0.17 on systems using the containerd image store. - Improves error visibility by removing blanket catch-alls that hid failures. Tickets: CN-731, CN-659, CN-657, CN-169, CN-554
1 parent 215e156 commit 66cda90

File tree

3 files changed

+899
-91
lines changed

3 files changed

+899
-91
lines changed

lib/extractor/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as Debug from "debug";
12
import path = require("path");
23
import {
34
getLayersFromPackages,
@@ -20,6 +21,8 @@ import {
2021
OciArchiveManifest,
2122
} from "./types";
2223

24+
const debug = Debug("snyk");
25+
2326
export class InvalidArchiveError extends Error {
2427
constructor(message) {
2528
super();
@@ -157,10 +160,14 @@ export async function extractImageContent(
157160
async function extractArchiveContentFallback(
158161
extractors: Map<ImageType, ArchiveExtractor>,
159162
): Promise<[ExtractedLayersAndManifest, ArchiveExtractor]> {
160-
for (const extractor of extractors.values()) {
163+
for (const [imageType, extractor] of extractors.entries()) {
161164
try {
162165
return [await extractor.getLayersAndManifest(), extractor];
163166
} catch (error) {
167+
// imageType is a string enum value like "docker-archive", "oci-archive"
168+
debug(
169+
`Error getting layers and manifest content from ${imageType} archive: ${error.message}`,
170+
);
164171
continue;
165172
}
166173
}

0 commit comments

Comments
 (0)