snyk-docker-plugin
Version:
Snyk CLI docker plugin
75 lines • 3.56 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractImageLayer = exports.isWhitedOutFile = void 0;
const Debug = require("debug");
const path = require("path");
const tar_stream_1 = require("tar-stream");
const error_utils_1 = require("../error-utils");
const callbacks_1 = require("./callbacks");
const decompress_maybe_1 = require("./decompress-maybe");
function isWhitedOutFile(filename) {
return filename.match(/.wh./gm);
}
exports.isWhitedOutFile = isWhitedOutFile;
const debug = Debug("snyk");
async function extractImageLayer(layerTarStream, extractActions) {
return new Promise((resolve, reject) => {
const result = {};
const symlinks = {};
const tarExtractor = (0, tar_stream_1.extract)();
tarExtractor.on("entry", async (headers, stream, next) => {
const absoluteFileName = path.join(path.sep, headers.name);
// Symlinks are path redirects; hard links are alternate names for the same
// inode and must not be treated as redirects during path canonicalization.
if (headers.type === "symlink") {
const linkTarget = headers.linkname;
if (linkTarget) {
symlinks[absoluteFileName] = absoluteLinkTarget(headers.name, linkTarget);
}
}
else if (headers.type === "file") {
const matchedActions = extractActions.filter((action) => action.filePathMatches(absoluteFileName));
if (matchedActions.length > 0) {
try {
const callbackResult = await (0, callbacks_1.applyCallbacks)(matchedActions, stream, headers.size);
if (!(0, callbacks_1.isResultEmpty)(callbackResult) ||
isWhitedOutFile(absoluteFileName)) {
result[absoluteFileName] = callbackResult;
}
}
catch (error) {
// An ExtractAction has thrown an uncaught exception, likely a bug in the code!
debug(`Exception thrown while applying callbacks during image layer extraction: ${(0, error_utils_1.getErrorMessage)(error)}`);
reject(error);
return;
}
}
else if (isWhitedOutFile(absoluteFileName)) {
result[absoluteFileName] = {};
}
}
stream.resume(); // auto drain the stream
next(); // ready for next entry
});
tarExtractor.on("finish", () => {
// all layer level entries read
resolve({ extractedLayers: result, symlinks });
});
tarExtractor.on("error", (error) => reject(error));
layerTarStream.pipe((0, decompress_maybe_1.decompressMaybe)()).pipe(tarExtractor);
});
}
exports.extractImageLayer = extractImageLayer;
/**
* Resolve a tar symlink target to an absolute path within the image.
* A relative target resolves against the symlink's own directory; tar entry
* names always use forward slashes, so this is posix math on every platform.
*/
function absoluteLinkTarget(entryName, linkTarget) {
if (linkTarget.startsWith("/")) {
return path.posix.normalize(linkTarget);
}
const linkDir = path.posix.dirname(path.posix.normalize("/" + entryName));
return path.posix.normalize(path.posix.join(linkDir, linkTarget));
}
//# sourceMappingURL=layer.js.map