HEX
Server: Apache
System: Linux webd004.cluster130.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
User: frenchy (106757)
PHP: 7.4.33
Disabled: _dyuweyrj4,_dyuweyrj4r,dl
Upload Files
File: /home/f/r/e/frenchy/www/french-american.org/current/node_modules/snyk-docker-plugin/dist/index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const Debug = require("debug");
const path = require("path");
const analyzer = require("./analyzer");
const docker_1 = require("./docker");
const dockerFile = require("./docker-file");
exports.dockerFile = dockerFile;
const response_builder_1 = require("./response-builder");
const debug = Debug("snyk");
function inspect(root, targetFile, options) {
    const dockerOptions = options
        ? {
            host: options.host,
            tlsverify: options.tlsverify,
            tlscert: options.tlscert,
            tlscacert: options.tlscacert,
            tlskey: options.tlskey,
            manifestGlobs: options.manifestGlobs,
        }
        : {};
    const targetImage = root;
    return dockerFile
        .readDockerfileAndAnalyse(targetFile)
        .then((dockerfileAnalysis) => {
        return Promise.all([
            getRuntime(dockerOptions),
            getDependencies(targetImage, dockerfileAnalysis, dockerOptions),
            getManifestFiles(targetImage, dockerOptions),
        ]).then((res) => {
            return response_builder_1.buildResponse(res[0], res[1], dockerfileAnalysis, res[2], options);
        });
    });
}
exports.inspect = inspect;
function getRuntime(options) {
    return docker_1.Docker.run(["version"], options)
        .then((output) => {
        const versionMatch = /Version:\s+(.*)\n/.exec(output.stdout);
        if (versionMatch) {
            return "docker " + versionMatch[1];
        }
        return undefined;
    })
        .catch((error) => {
        throw new Error(`Docker error: ${error.stderr}`);
    });
}
function handleCommonErrors(error, targetImage) {
    if (error.indexOf("command not found") !== -1) {
        throw new Error("Snyk docker CLI was not found");
    }
    if (error.indexOf("Cannot connect to the Docker daemon") !== -1) {
        throw new Error("Cannot connect to the Docker daemon. Is the docker" + " daemon running?");
    }
    const ERROR_LOADING_IMAGE_STR = "Error loading image from docker engine:";
    if (error.indexOf(ERROR_LOADING_IMAGE_STR) !== -1) {
        if (error.indexOf("reference does not exist") !== -1) {
            throw new Error(`Docker image was not found locally: ${targetImage}`);
        }
        if (error.indexOf("permission denied while trying to connect") !== -1) {
            let errString = error.split(ERROR_LOADING_IMAGE_STR)[1];
            errString = (errString || "").slice(0, -2); // remove trailing \"
            throw new Error("Permission denied connecting to docker daemon. " +
                "Please make sure user has the required permissions. " +
                "Error string: " +
                errString);
        }
    }
    if (error.indexOf("Error getting docker client:") !== -1) {
        throw new Error("Failed getting docker client");
    }
    if (error.indexOf("Error processing image:") !== -1) {
        throw new Error("Failed processing image:" + targetImage);
    }
}
function getDependencies(targetImage, dockerfileAnalysis, options) {
    let result;
    return analyzer
        .analyze(targetImage, dockerfileAnalysis, options)
        .then((output) => {
        result = parseAnalysisResults(targetImage, output, dockerfileAnalysis);
        return buildTree(targetImage, result.type, result.depInfosList, result.targetOS);
    })
        .then((pkg) => {
        return {
            package: pkg,
            packageManager: result.type,
            imageId: result.imageId,
            binaries: result.binaries,
            imageLayers: result.imageLayers,
        };
    })
        .catch((error) => {
        if (typeof error === "string") {
            debug(`Error while running analyzer: '${error}'`);
            handleCommonErrors(error, targetImage);
            let errorMsg = error;
            const errorMatch = /msg="(.*)"/g.exec(errorMsg);
            if (errorMatch) {
                errorMsg = errorMatch[1];
            }
            throw new Error(errorMsg);
        }
        throw error;
    });
}
function getManifestFiles(targetImage, options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        if (!options.manifestGlobs) {
            return [];
        }
        const globs = options.manifestGlobs;
        const docker = new docker_1.Docker(targetImage, options);
        const contents = yield Promise.all(globs.map((g) => docker.catSafe(g)));
        return globs
            .map((g, i) => {
            return {
                name: path.basename(g),
                path: path.dirname(g),
                contents: Buffer.from(contents[i].stdout).toString("base64"),
            };
        })
            .filter((i) => i.contents !== "");
    });
}
function parseAnalysisResults(targetImage, analysisJson, dockerfileAnalysis) {
    let analysisResult = analysisJson.results.filter((res) => {
        return res.Analysis && res.Analysis.length > 0;
    })[0];
    if (!analysisResult) {
        if (dockerfileAnalysis && dockerfileAnalysis.baseImage === "scratch") {
            // Special case when we have no package management
            // on scratch images
            analysisResult = {
                Image: targetImage,
                AnalyzeType: "linux",
                Analysis: [],
            };
        }
        else {
            throw new Error("Failed to detect a supported Linux package manager (deb/rpm/apk)");
        }
    }
    let depType;
    switch (analysisResult.AnalyzeType) {
        case "Apt": {
            depType = "deb";
            break;
        }
        default: {
            depType = analysisResult.AnalyzeType.toLowerCase();
        }
    }
    return {
        imageId: analysisJson.imageId,
        targetOS: analysisJson.osRelease,
        type: depType,
        depInfosList: analysisResult.Analysis,
        binaries: analysisJson.binaries.Analysis,
        imageLayers: analysisJson.imageLayers,
    };
}
function buildTree(targetImage, depType, depInfosList, targetOS) {
    // A tag can only occur in the last section of a docker image name, so
    // check any colon separator after the final '/'. If there are no '/',
    // which is common when using Docker's official images such as
    // "debian:stretch", just check for ':'
    const finalSlash = targetImage.lastIndexOf("/");
    const hasVersion = (finalSlash >= 0 && targetImage.slice(finalSlash).includes(":")) ||
        targetImage.includes(":");
    // Defaults for simple images from dockerhub, like "node" or "centos"
    let imageName = targetImage;
    let imageVersion = "latest";
    // If we have a version, split on the last ':' to avoid the optional
    // port on a hostname (i.e. localhost:5000)
    if (hasVersion) {
        const versionSeparator = targetImage.lastIndexOf(":");
        imageName = targetImage.slice(0, versionSeparator);
        imageVersion = targetImage.slice(versionSeparator + 1);
    }
    const shaString = "@sha256";
    if (imageName.endsWith(shaString)) {
        imageName = imageName.slice(0, imageName.length - shaString.length);
        imageVersion = "";
    }
    const root = {
        // don't use the real image name to avoid scanning it as an issue
        name: "docker-image|" + imageName,
        version: imageVersion,
        targetOS,
        packageFormatVersion: depType + ":0.0.1",
        dependencies: {},
    };
    const depsMap = depInfosList.reduce((acc, depInfo) => {
        const name = depInfo.Name;
        acc[name] = depInfo;
        return acc;
    }, {});
    const virtualDepsMap = depInfosList.reduce((acc, depInfo) => {
        const providesNames = depInfo.Provides || [];
        providesNames.forEach((name) => {
            acc[name] = depInfo;
        });
        return acc;
    }, {});
    const depsCounts = {};
    depInfosList.forEach((depInfo) => {
        countDepsRecursive(depInfo.Name, new Set(), depsMap, virtualDepsMap, depsCounts);
    });
    const DEP_FREQ_THRESHOLD = 100;
    const tooFrequentDepNames = Object.keys(depsCounts).filter((depName) => {
        return depsCounts[depName] > DEP_FREQ_THRESHOLD;
    });
    const attachDeps = (depInfos) => {
        const depNamesToSkip = new Set(tooFrequentDepNames);
        depInfos.forEach((depInfo) => {
            const subtree = buildTreeRecurisve(depInfo.Name, new Set(), depsMap, virtualDepsMap, depNamesToSkip);
            if (subtree) {
                root.dependencies[subtree.name] = subtree;
            }
        });
    };
    // attach (as direct deps) pkgs not marked auto-installed:
    const manuallyInstalledDeps = depInfosList.filter((depInfo) => {
        return !depInfo.AutoInstalled;
    });
    attachDeps(manuallyInstalledDeps);
    // attach (as direct deps) pkgs marked as auto-insatalled,
    //  but not dependant upon:
    const notVisitedDeps = depInfosList.filter((depInfo) => {
        const depName = depInfo.Name;
        return !depsMap[depName]._visited;
    });
    attachDeps(notVisitedDeps);
    // group all the "too frequest" deps under a meta package:
    if (tooFrequentDepNames.length > 0) {
        const tooFrequentDeps = tooFrequentDepNames.map((name) => {
            return depsMap[name];
        });
        const metaSubtree = {
            name: "meta-common-packages",
            version: "meta",
            dependencies: {},
        };
        tooFrequentDeps.forEach((depInfo) => {
            const pkg = {
                name: depFullName(depInfo),
                version: depInfo.Version,
            };
            metaSubtree.dependencies[pkg.name] = pkg;
        });
        root.dependencies[metaSubtree.name] = metaSubtree;
    }
    return root;
}
function buildTreeRecurisve(depName, ancestors, depsMap, virtualDepsMap, depNamesToSkip) {
    const depInfo = depsMap[depName] || virtualDepsMap[depName];
    if (!depInfo) {
        return null;
    }
    // "realName" as the argument depName might be a virtual pkg
    const realName = depInfo.Name;
    const fullName = depFullName(depInfo);
    if (ancestors.has(fullName) || depNamesToSkip.has(realName)) {
        return null;
    }
    const tree = {
        name: fullName,
        version: depInfo.Version,
    };
    if (depInfo._visited) {
        return tree;
    }
    depInfo._visited = true;
    const newAncestors = new Set(ancestors).add(fullName);
    const deps = depInfo.Deps || {};
    Object.keys(deps).forEach((name) => {
        const subTree = buildTreeRecurisve(name, newAncestors, depsMap, virtualDepsMap, depNamesToSkip);
        if (subTree) {
            if (!tree.dependencies) {
                tree.dependencies = {};
            }
            if (!tree.dependencies[subTree.name]) {
                tree.dependencies[subTree.name] = subTree;
            }
        }
    });
    return tree;
}
function countDepsRecursive(depName, ancestors, depsMap, virtualDepsMap, depCounts) {
    const depInfo = depsMap[depName] || virtualDepsMap[depName];
    if (!depInfo) {
        return;
    }
    // "realName" as the argument depName might be a virtual pkg
    const realName = depInfo.Name;
    if (ancestors.has(realName)) {
        return;
    }
    depCounts[realName] = (depCounts[realName] || 0) + 1;
    const newAncestors = new Set(ancestors).add(realName);
    const deps = depInfo.Deps || {};
    Object.keys(deps).forEach((name) => {
        countDepsRecursive(name, newAncestors, depsMap, virtualDepsMap, depCounts);
    });
}
function depFullName(depInfo) {
    let fullName = depInfo.Name;
    if (depInfo.Source) {
        fullName = depInfo.Source + "/" + fullName;
    }
    return fullName;
}
//# sourceMappingURL=index.js.map