diff --git a/.github/workflows/repotests.yml b/.github/workflows/repotests.yml index ae7e3eba2..89bfae6f0 100644 --- a/.github/workflows/repotests.yml +++ b/.github/workflows/repotests.yml @@ -516,8 +516,8 @@ jobs: shell: bash - name: repotests rust run: | - bin/cdxgen.js -p -r -t rust repotests/rs-rust -o bomresults/bom-rs-rust.json --fail-on-error - bin/cdxgen.js -p -r -t rust repotests/rs-cargo -o bomresults/bom-rs-cargo.json --fail-on-error + bin/cdxgen.js -p -r -t rust repotests/rs-rust -o bomresults/bom-rs-rust.json --exclude "**/tests/**" --fail-on-error + bin/cdxgen.js -p -r -t rust repotests/rs-cargo -o bomresults/bom-rs-cargo.json --exclude "**/tests/**" --fail-on-error cargo generate-lockfile --manifest-path repotests/rs-validator/validator/Cargo.toml bin/cdxgen.js -p -r -t rust repotests/rs-validator -o bomresults/bom-rs-validator.json --fail-on-error bin/cdxgen.js -p -r -t rust repotests/rs-axum -o bomresults/bom-rs-axum.json --fail-on-error diff --git a/lib/helpers/utils.js b/lib/helpers/utils.js index aa7a77272..5a30d2f6a 100644 --- a/lib/helpers/utils.js +++ b/lib/helpers/utils.js @@ -218,6 +218,7 @@ const MAX_GET_REPO_LICENSE_ERRORS = 5; const MAX_LICENSE_ID_LENGTH = 100; export const JAVA_CMD = getJavaCommand(); + export function getJavaCommand() { let javaCmd = "java"; if (process.env.JAVA_CMD) { @@ -231,7 +232,9 @@ export function getJavaCommand() { } return javaCmd; } + export const PYTHON_CMD = getPythonCommand(); + export function getPythonCommand() { let pythonCmd = "python"; if (process.env.PYTHON_CMD) { @@ -241,6 +244,7 @@ export function getPythonCommand() { } return pythonCmd; } + export let DOTNET_CMD = "dotnet"; if (process.env.DOTNET_CMD) { DOTNET_CMD = process.env.DOTNET_CMD; @@ -4665,6 +4669,7 @@ export function parsePyProjectTomlFile(tomlFile) { ]; } } + let poetryMode = false; let uvMode = false; let hatchMode = false; @@ -5676,6 +5681,7 @@ export function parsePixiLockFile(pixiLockFileName, path) { `${path}/.pixi/envs/default`; return p; } + // create the pkgList pkgList = pixiLockData["packages"].map(pixiMapper); pkgList = pkgList.map(mapAddEvidenceValue); @@ -7449,6 +7455,69 @@ function fileListToComponents(fileList) { return components; } +/** + * Parse dependency info from the `[package]` node in `cargo.toml` or `cargo.lock` + * @param {Object} packageNode + * @returns {Object} dependency info + * @throws {Error} if dependency name or version is invalid + */ +function parseCargoDependencyFromPackageNode(packageNode) { + const pkg = {}; + const pkgName = packageNode["name"]; + let group = dirname(pkgName.toString()); + if (group === ".") { + group = ""; + } + const pkgChecksum = packageNode["checksum"]; + const pkgVersion = packageNode["version"]; + const pkgAuthors = packageNode["authors"]; + const pkgHomepage = packageNode["homepage"]; + const pkgRepository = packageNode["repository"]; + const pkgLicense = packageNode["license"]; + const pkgDependencies = packageNode["dependencies"]; + + // the value of attributes like: + // - `version = 1.0.0` + // - `version.workspace = true` + const isExtendFromWorkspace = (attribute) => { + return attribute?.workspace; + }; + if (!pkgName || !pkgVersion) { + throw new Error("name or version is not defined"); + } + + if (!isExtendFromWorkspace(pkgChecksum) && pkgChecksum) { + pkg._integrity = `${pkgChecksum}`; + } + if (!isExtendFromWorkspace(pkgName) && pkgName) { + pkg.group = group; + pkg.name = basename(pkgName.toString()); + } + if (!isExtendFromWorkspace(pkgVersion) && pkgVersion) { + pkg.version = pkgVersion; + } + if (!isExtendFromWorkspace(pkgAuthors) && pkgAuthors) { + if (Array.isArray(pkgAuthors)) { + pkg.author = pkgAuthors.join(","); + } else { + pkg.author = Object.prototype.toString.call(pkgAuthors); + } + } + if (!isExtendFromWorkspace(pkgHomepage) && pkgHomepage) { + pkg.homepage = { url: pkgHomepage }; + } + if (!isExtendFromWorkspace(pkgRepository) && pkgRepository) { + pkg.repository = { url: pkgRepository }; + } + if (!isExtendFromWorkspace(pkgLicense) && pkgLicense) { + pkg.license = pkgLicense; + } + if (!isExtendFromWorkspace(pkgDependencies) && pkgDependencies) { + pkg.dependencies = pkgDependencies; + } + return pkg; +} + /** * Method to parse cargo.toml data * @@ -7530,111 +7599,69 @@ export async function parseCargoTomlData( if (!cargoTomlFile || !safeExistsSync(cargoTomlFile)) { return pkgList; } - const cargoData = readFileSync(cargoTomlFile, { encoding: "utf-8" }); + let cargoData; + try { + cargoData = toml.parse(readFileSync(cargoTomlFile, { encoding: "utf-8" })); + } catch (e) { + console.log(e); + } if (!cargoData) { return pkgList; } - let pkg = null; - let dependencyMode = false; - let packageMode = false; - cargoData.split("\n").forEach((l) => { - let key = null; - let value = null; - l = l.replace("\r", ""); - if (l.indexOf("[package]") > -1) { - packageMode = true; - addPackageToList(pkgList, pkg, { packageMode, simple }); - pkg = {}; - } - if (l.startsWith("[dependencies]")) { - dependencyMode = true; - packageMode = false; - } - - // Properly parsing project with workspaces is currently unsupported. Some - // projects may have a top-level Cargo.toml file containing only - // workspace definitions and no package name. That will make the parent - // component unreliable. - // See: https://doc.rust-lang.org/cargo/reference/workspaces.html#virtual-workspace - if (l.startsWith("[workspace]") && DEBUG_MODE) { - console.log( - `Found [workspace] section in ${cargoTomlFile}. Workspaces are currently not fully supported. Verify that the parent component is correct.`, + const packageNode = cargoData["package"]; + // parse `[package]` + if (packageNode instanceof Object && !Array.isArray(packageNode)) { + /** @type {Object} */ + const packageObjNode = packageNode; + try { + const pkg = parseCargoDependencyFromPackageNode(packageNode); + addPackageToList(pkgList, pkg, { packageMode: true, simple }); + } catch (e) { + console.warn( + `Failed to parse package: ${packageObjNode?.name}@${packageObjNode?.version},fail with:${e.message}`, ); } - - if ( - l.startsWith("[") && - !l.startsWith("[dependencies]") && - (!packageMode || l.startsWith("[[")) - ) { - dependencyMode = false; - packageMode = false; - } - if (packageMode && l.indexOf("=") > -1) { - const tmpA = l.split("="); - key = tmpA[0].trim(); - value = tmpA[1].trim().replace(/"/g, ""); - switch (key) { - case "checksum": - pkg._integrity = `sha384-${value}`; - break; - case "name": - value = value.split(" ")[0]; - pkg.group = dirname(value); - if (pkg.group === ".") { - pkg.group = ""; - } - pkg.name = basename(value); - break; - case "version": - pkg.version = value.split(" ")[0]; - break; - case "authors": - pkg.author = value.replace(/[[\]]/g, ""); - break; - case "homepage": - pkg.homepage = { url: value }; - break; - case "repository": - pkg.repository = { url: value }; - break; - case "license": - pkg.license = value; - break; - } - } else if (dependencyMode && l.indexOf("=") > -1) { - if (pkg) { - addPackageToList(pkgList, pkg, { packageMode, simple }); - } - pkg = undefined; - const tmpA = l.split(" = "); - let tmpB = undefined; - let name = tmpA[0]; - let version = undefined; - if (l.indexOf("version =") > -1) { - tmpB = l.split(" { version = "); - if (tmpB && tmpB.length > 1) { - version = tmpB[1].split(",")[0]; - } - } else if (l.includes("git =")) { - tmpB = l.split(" { git = "); - if (tmpB && tmpB.length > 1) { - version = `git+${tmpB[1].split(" }")[0]}`; + } + // parse `[dependencies]` + const dependenciesNode = cargoData["dependencies"]; + if (dependenciesNode) { + for (const dependencyName in dependenciesNode) { + const dependencyNode = dependenciesNode[dependencyName]; + let version = ""; + if ( + typeof dependencyNode === "string" || + dependencyNode instanceof String + ) { + // like `libc = 0.2.79` + version = dependencyNode; + } else if (Object.keys(dependencyNode).length > 0) { + // like `libc = { version = "0.2.79", features = ['rustc-dep-of-std'], default-features = false }` + version = dependencyNode?.version; + const git = dependencyNode?.git; + if (!version && git) { + version = `git+${git}`; } - } else if (l.indexOf("path =") === -1 && tmpA.length > 1) { - version = tmpA[1]; } - if (name && version) { - name = name.replace(/["']/g, ""); - version = version.replace(/["']/g, ""); - const apkg = { name, version }; - addPackageToList(pkgList, apkg, { packageMode, simple }); + if (dependencyName && version) { + const pkg = {}; + pkg.name = dependencyName; + pkg.version = version; + addPackageToList(pkgList, pkg, { packageMode: false, simple }); } } - }); - if (pkg) { - addPackageToList(pkgList, pkg, { packageMode, simple }); } + + // Properly parsing project with workspaces is currently unsupported. Some + // projects may have a top-level Cargo.toml file containing only + // workspace definitions and no package name. That will make the parent + // component unreliable. + // See: https://doc.rust-lang.org/cargo/reference/workspaces.html#virtual-workspace + if (cargoData.workspace && DEBUG_MODE) { + console.log( + `Found [workspace] section in ${cargoTomlFile}. Workspaces are currently not fully supported. Verify that the parent component is correct.`, + ); + } + if (!simple && shouldFetchLicense()) { return await getCratesMetadata(pkgList); } @@ -7681,7 +7708,7 @@ export async function parseCargoData( component.hashes = [ { alg: "SHA-384", - content: pkg._integrity, + content: newPackage._integrity, }, ]; } @@ -7715,7 +7742,7 @@ export async function parseCargoData( value: cargoLockFile, }, ]; - if (pkgFilesMap?.[pkg.name]) { + if (pkgFilesMap?.[newPackage.name]) { component.components = fileListToComponents( pkgFilesMap[component.name], ); @@ -7723,57 +7750,31 @@ export async function parseCargoData( } packageList.push(component); }; - const pkgList = []; if (!cargoLockFile) { return pkgList; } - const cargoData = readFileSync(cargoLockFile, { encoding: "utf-8" }); + const cargoData = toml.parse( + readFileSync(cargoLockFile, { encoding: "utf-8" }), + ); if (!cargoData) { return pkgList; } - let pkg = null; - cargoData.split("\n").forEach((l) => { - let key = null; - let value = null; - l = l.replace("\r", ""); - // Ignore version = 3 found at the top of newer lock files - if (!pkg && l.startsWith("version =")) { - return; - } - if (l.indexOf("[[package]]") > -1) { - if (pkg) { + const packageNode = cargoData["package"]; + // parse `[[package]]` + if (Array.isArray(packageNode)) { + packageNode.forEach((packageItem) => { + try { + const pkg = parseCargoDependencyFromPackageNode(packageItem); addPackageToList(pkgList, pkg, { simple }); + } catch (e) { + console.warn( + `Failed to parse package: ${packageItem["name"]}@${packageItem["version"]},fail with:${e.message}`, + ); } - pkg = {}; - } - if (l.indexOf("=") > -1) { - const tmpA = l.split("="); - key = tmpA[0].trim(); - value = tmpA[1].trim().replace(/"/g, ""); - switch (key) { - case "checksum": - pkg._integrity = value; - break; - case "name": - pkg.group = dirname(value); - if (pkg.group === ".") { - pkg.group = ""; - } - pkg.name = basename(value); - break; - case "version": - pkg.version = value; - break; - } - } - }); - // The last package will not be followed by a [[package]]-table, so the - // last package has no termination condition, other than end-of-file. - if (pkg) { - addPackageToList(pkgList, pkg, { simple }); + }); } if (shouldFetchLicense() && !simple) { return await getCratesMetadata(pkgList); @@ -7782,145 +7783,62 @@ export async function parseCargoData( } export function parseCargoDependencyData(cargoLockData) { - // The patterns to parse the Cargo.lock file makes no attempt to parse - // toml-files properly. They match the structure of Cargo.lock specifically. - - // Cargo.lock files generates packages separated by blank lines. There does - // not seem to be a specification for the lock files, but cargo - // generate-lockfile seems to consistently create them that way. Important - // note to perform an eager match, so as to not match the first header with - // the entire document. - // If the Cargo.lock file do not contain a footer with metadata, the last - // package section only has one trailing newline trailed by the end-of-file - // instead. - const packagePattern = /\[\[package]][\s\S]+?(\r?\n)((\r?\n)|$)/g; - - // Match each key-value pair. This assumes the value to only be a string or - // an array (either single- or multi-line). - const keyValuePattern = /\w+\s?=\s?(".+"|\[[\s\S]+])\r?\n/g; - const purlFromPackageInfo = (pkg) => decodeURIComponent( new PackageURL("cargo", "", pkg.name, pkg.version, null, null).toString(), ); - - // The dependency list may appear as a single-line list: - // ["ansi_term", "openssl-sys"] - // or as a multi-line list with a trailing comma for the last item: - // [ - // "ansi_term", - // "openssl-sys", - // ] - // Names in the dependency-list may appear is simple names: - // "ansi_term", "openssl-sys" - // or with a version attached, delimited by a space: - // "winapi 0.3.8", "semver-parser 0.9.0" - // or possibly with a registry link: - // "base64 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" - const parseDependencyValue = (dependencyValue) => { - return ( - dependencyValue - // Remove starting and trailing brackets, with surrounding whitespace - .replace(/^\s*\[\s+/g, "") - .replace(/\s*]\s+$/g, "") - // Remove the quotes from each dependency name, making the dependency - // list a comma-separated list of names. - .replace(/"/g, "") - // Trim any whitespace surrounding the commas - .replace(/\s*,\s*/g, ",") - // In order to not end up with an empty item at the end in case of a - // trailing comma, remove one if it exists. - .replace(/,$/, "") - // Finally, create a list from the comma separated values - .split(",") - // In order to not drop the version from the dependency name, we return - // both the name and the version, if one exists. If it doesn't exist, we - // can assume it is the version of the component in the component list. - // The registry link is always dropped. - .map((dependencyName) => { - const [name, version] = dependencyName.split(" "); - return { - name, - version, - }; - }) - ); - }; - - // To fulfill the specification, the list of dependencies has to be sweeped - // twice. References (the PURL) to entries in the component list requires - // both the package name and specific package version. And packages may - // appear as a dependency before it is "defined" in the Cargo.lock file. - // So, the first sweep creates an inventory of packages in the Cargo.lock - // file. With a full inventory of the packages in the Cargo.lock file, a - // second sweep can construct the objects for the depndencies-list. - - // First sweep: Construct inventory of Cargo.lock contents. - const lockfileInventory = {}; - const allPackages = cargoLockData.matchAll(packagePattern); - [...allPackages].forEach((packageObject) => { - const packageTable = packageObject[0].matchAll(keyValuePattern); - const packageInfo = {}; - [...packageTable].forEach((keyValue) => { - const [key, value] = keyValue[0].split(" = "); - switch (key) { - // Only "dependencies" is expected to be a list. All other keys are - // expected to be strings. - case "dependencies": - packageInfo[key] = parseDependencyValue(value); - break; - default: - packageInfo[key] = value.replace(/\s*"\s*/g, ""); - break; + const cargoData = toml.parse(cargoLockData); + const packageNode = cargoData?.package; + if (!packageNode || !Array.isArray(packageNode)) { + return []; + } + /** @type {Array} */ + const packageArrayNode = packageNode; + /** @type {Array<{ name: string, version: string, dependencies: Array}>} */ + const pkgList = []; + packageArrayNode.forEach((packageItem) => { + try { + const pkg = parseCargoDependencyFromPackageNode(packageItem); + pkgList.push(pkg); + } catch (e) { + console.warn( + `Failed to parse package: ${packageItem["name"]}@${packageItem["version"]},fail with:${e.message}`, + ); + } + }); + // Create a map of package names to package objects + const pkgMap = pkgList.reduce((acc, item) => { + acc[item.name] = item; + return acc; + }, {}); + const result = []; + // parse dependency version + Object.values(pkgMap).forEach((pkg) => { + const dependsOn = new Set(); + pkg.dependencies?.forEach((dep) => { + if (dep.indexOf(" ") !== -1) { + // fill version in dependency definition like `libc 0.2.79` + const depSplit = dep.split(" "); + dependsOn.add( + purlFromPackageInfo({ + name: depSplit[0].trim(), + version: depSplit[1].trim(), + }), + ); + } else if (pkgMap[dep]) { + dependsOn.add(purlFromPackageInfo(pkgMap[dep])); + } else if (DEBUG_MODE) { + console.warn( + `The package "${dep.name}" appears as a dependency to "${pkg.name}" but is not itself listed in the Cargo.lock file. The Cargo.lock file is invalid! The produced SBOM will not list ${dep.name} as a dependency.`, + ); } }); - lockfileInventory[packageInfo.name] = packageInfo; - }); - - // Second sweep, construct the dependencies-list. - return Object.values(lockfileInventory).map((pkg) => { - if (!pkg.dependencies) { - return { - ref: purlFromPackageInfo(pkg), - dependsOn: [], - }; - } - return { + result.push({ ref: purlFromPackageInfo(pkg), - dependsOn: [ - ...new Set( - pkg.dependencies - .map((dependency) => { - // If the package has a dependency with a specific version, it needs - // to be respected. - if (dependency.version) { - return purlFromPackageInfo(dependency); - } - - if (!lockfileInventory[dependency.name]) { - // We have found a package listed as a dependency that does not - // appear as a package in the Cargo.lock-file. This is an error! - // If this happens, the Cargo.lock-file is incomplete and have - // most likely been manually tampered with. Add a warning to - // signal to the user that the file is invalid, skip the package, - // and continue. - if (DEBUG_MODE) { - console.warn( - `The package "${dependency.name}" appears as a dependency to "${pkg.name}" but is not itself listed in the Cargo.lock file. The Cargo.lock file is invalid! The produced SBOM will not list ${dependency.name} as a dependency.`, - ); - } - return undefined; - } - - // If no version was specified for the dependency, default to the - // version known from the package table. - return purlFromPackageInfo(lockfileInventory[dependency.name]); - }) - .filter((pkg) => pkg), // Filter undefined entries, which should only happen when packages listed as a dependency are not defined as packages. - ), - ].sort(), - }; + dependsOn: [...dependsOn], + }); }); + return result; } export async function parseCargoAuditableData(cargoData) { @@ -13951,12 +13869,14 @@ async function queryNuget(p, NUGET_URL) { } return version; } + // Coerce only when missing patch/minor version function coerceUp(version) { return version.split(".").length < 3 ? coerce(version, { loose: true }).version : version; } + if (DEBUG_MODE) { console.log(`Querying nuget for ${p.name}`); } diff --git a/lib/helpers/utils.test.js b/lib/helpers/utils.test.js index 5b56481ef..c855c0e06 100644 --- a/lib/helpers/utils.test.js +++ b/lib/helpers/utils.test.js @@ -1758,7 +1758,7 @@ test("parse cargo lock dependencies tests", async () => { readFileSync("./test/Cargo.lock", { encoding: "utf-8" }), ); const purlIsPackage = (purl, packageName) => - new RegExp(`^pkg:cargo/${packageName}.+`).test(purl); + new RegExp(`^pkg:cargo/${packageName}@.+`).test(purl); expect(dependencyData.length).toBeGreaterThan(0); @@ -1790,8 +1790,8 @@ test("parse cargo lock dependencies tests", async () => { const kernel32Sys = dependencyData.find((dependency) => purlIsPackage(dependency.ref, "kernel32-sys"), ); - expect(purlIsPackage(kernel32Sys.dependsOn[1], "winapi")).toBeTruthy(); - expect(kernel32Sys.dependsOn[1]).toContain("0.2.8"); + expect(purlIsPackage(kernel32Sys.dependsOn[0], "winapi")).toBeTruthy(); + expect(kernel32Sys.dependsOn[0]).toContain("0.2.8"); }); test("parse dependency tree from cargo lock files without metadata footer", async () => { diff --git a/types/lib/helpers/utils.d.ts b/types/lib/helpers/utils.d.ts index 05edbfadb..78095045b 100644 --- a/types/lib/helpers/utils.d.ts +++ b/types/lib/helpers/utils.d.ts @@ -702,10 +702,7 @@ export function parseCargoTomlData(cargoTomlFile: string, simple?: boolean, pkgF * @returns {Array} A list of the project's components as described by the Cargo.lock-file. */ export function parseCargoData(cargoLockFile: string, simple?: boolean, pkgFilesMap?: any): any[]; -export function parseCargoDependencyData(cargoLockData: any): { - ref: string; - dependsOn: any[]; -}[]; +export function parseCargoDependencyData(cargoLockData: any): any[]; export function parseCargoAuditableData(cargoData: any): Promise; /** * Method to parse pubspec.lock files. diff --git a/types/lib/helpers/utils.d.ts.map b/types/lib/helpers/utils.d.ts.map index 500b33e96..7ac3d603e 100644 --- a/types/lib/helpers/utils.d.ts.map +++ b/types/lib/helpers/utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/helpers/utils.js"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/helpers/utils.js"],"names":[],"mappings":"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"} \ No newline at end of file