Skip to content

Commit

Permalink
Merge pull request #583 from snyk/UNIFY-93-package-url-generation-in-…
Browse files Browse the repository at this point in the history
…snyk-docker-plugin

feat: fix purl generation for container
  • Loading branch information
paulrosca-snyk committed Apr 25, 2024
2 parents 0023da6 + 21d5762 commit b24ef00
Show file tree
Hide file tree
Showing 23 changed files with 3,458 additions and 3,417 deletions.
39 changes: 33 additions & 6 deletions lib/analyzer/package-managers/apt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import {
AnalyzedPackageWithVersion,
IAptFiles,
ImagePackagesAnalysis,
OSRelease,
} from "../types";

export function analyze(
targetImage: string,
aptFiles: IAptFiles,
osRelease?: OSRelease,
): Promise<ImagePackagesAnalysis> {
const pkgs = parseDpkgFile(aptFiles.dpkgFile);
const pkgs = parseDpkgFile(aptFiles.dpkgFile, osRelease);

if (aptFiles.extFile) {
setAutoInstalledPackages(aptFiles.extFile, pkgs);
Expand All @@ -27,11 +29,12 @@ export function analyze(
export function analyzeDistroless(
targetImage: string,
aptFiles: string[],
osRelease?: OSRelease,
): Promise<ImagePackagesAnalysis> {
const analyzedPackages: AnalyzedPackageWithVersion[] = [];

for (const fileContent of aptFiles) {
const currentPackages = parseDpkgFile(fileContent);
const currentPackages = parseDpkgFile(fileContent, osRelease);
analyzedPackages.push(...currentPackages);
}

Expand All @@ -42,19 +45,36 @@ export function analyzeDistroless(
});
}

function parseDpkgFile(text: string): AnalyzedPackageWithVersion[] {
function parseDpkgFile(
text: string,
osRelease?: OSRelease,
): AnalyzedPackageWithVersion[] {
const pkgs: AnalyzedPackageWithVersion[] = [];
let curPkg: AnalyzedPackageWithVersion | null = null;
for (const line of text.split("\n")) {
curPkg = parseDpkgLine(line, curPkg!, pkgs);
if (curPkg) {
curPkg.Purl = purl(curPkg);
curPkg.Purl = purl(curPkg, osRelease);
}
}
return pkgs;
}

export function purl(curPkg: AnalyzedPackageWithVersion): string | undefined {
const debianCodenames = new Map<string, string>([
["8", "jessie"],
["9", "stretch"],
["10", "buster"],
["11", "bullseye"],
["12", "bookworm"],
["13", "trixie"],
["unstable", "sid"],
]);

export function purl(
curPkg: AnalyzedPackageWithVersion,
osRelease?: OSRelease,
): string | undefined {
let vendor = "";
if (!curPkg.Name || !curPkg.Version) {
return undefined;
}
Expand All @@ -66,9 +86,16 @@ export function purl(curPkg: AnalyzedPackageWithVersion): string | undefined {
qualifiers.upstream = curPkg.Source;
}

if (osRelease) {
const codenameOrVersion =
debianCodenames.get(osRelease.version) ?? osRelease.version;
qualifiers.distro = `${osRelease.name}-${codenameOrVersion}`;
vendor = osRelease.name;
}

return new PackageURL(
"deb",
"",
vendor,
curPkg.Name,
curPkg.Version,
// make sure that we pass in undefined if there are no qualifiers, because
Expand Down
21 changes: 17 additions & 4 deletions lib/analyzer/package-managers/rpm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import {
AnalysisType,
AnalyzedPackageWithVersion,
ImagePackagesAnalysis,
OSRelease,
} from "../types";

export function analyze(
targetImage: string,
pkgs: PackageInfo[],
repositories: string[],
osRelease?: OSRelease,
): Promise<ImagePackagesAnalysis> {
return Promise.resolve({
Image: targetImage,
Expand All @@ -23,13 +25,18 @@ export function analyze(
Provides: [],
Deps: {},
AutoInstalled: undefined,
Purl: purl(pkgInfo, repositories),
Purl: purl(pkgInfo, repositories, osRelease),
};
}),
});
}

function purl(pkg: PackageInfo, repos: string[]): string {
function purl(
pkg: PackageInfo,
repos: string[],
osRelease?: OSRelease,
): string {
let vendor = "";
const qualifiers: { [key: string]: string } = {};
if (pkg.module) {
const [modName, modVersion] = pkg.module.split(":");
Expand All @@ -44,9 +51,14 @@ function purl(pkg: PackageInfo, repos: string[]): string {
qualifiers.epoch = String(pkg.epoch);
}

if (osRelease) {
qualifiers.distro = `${osRelease.name}-${osRelease.version}`;
vendor = osRelease.name;
}

return new PackageURL(
AnalysisType.Rpm.toLowerCase(),
"", // would be the Vendor according to the purl rpm spec
vendor,
pkg.name,
formatRpmPackageVersion(pkg),
// make sure that we pass in undefined if there are no qualifiers, because
Expand All @@ -60,6 +72,7 @@ export function mapRpmSqlitePackages(
targetImage: string,
rpmPackages: PackageInfo[],
repositories: string[],
osRelease?: OSRelease,
): ImagePackagesAnalysis {
let analysis: AnalyzedPackageWithVersion[] = [];

Expand All @@ -72,7 +85,7 @@ export function mapRpmSqlitePackages(
Provides: [],
Deps: {},
AutoInstalled: undefined,
Purl: purl(pkg, repositories),
Purl: purl(pkg, repositories, osRelease),
};
});
}
Expand Down
7 changes: 4 additions & 3 deletions lib/analyzer/static-analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,15 @@ export async function analyze(
try {
results = await Promise.all([
apkAnalyze(targetImage, apkDbFileContent),
aptAnalyze(targetImage, aptDbFileContent),
rpmAnalyze(targetImage, rpmDbFileContent, redHatRepositories),
aptAnalyze(targetImage, aptDbFileContent, osRelease),
rpmAnalyze(targetImage, rpmDbFileContent, redHatRepositories, osRelease),
mapRpmSqlitePackages(
targetImage,
rpmSqliteDbFileContent,
redHatRepositories,
osRelease,
),
aptDistrolessAnalyze(targetImage, distrolessAptFiles),
aptDistrolessAnalyze(targetImage, distrolessAptFiles, osRelease),
]);
} catch (err) {
debug(`Could not detect installed OS packages: ${err.message}`);
Expand Down

0 comments on commit b24ef00

Please sign in to comment.