Merge pull request #109 from advanced-security/feature/handle-null-purls
Improve missing package URL handling
This commit is contained in:
@@ -50,4 +50,21 @@ describe("ComponentDetection.makePackageUrl", () => {
|
|||||||
"pkg:npm/github/[email protected]"
|
"pkg:npm/github/[email protected]"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("returns an empty string when packageUrlJson is null", () => {
|
||||||
|
const packageUrl = ComponentDetection.makePackageUrl(null);
|
||||||
|
expect(packageUrl).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("returns an empty string for null packageUrlJson properties", () => {
|
||||||
|
const packageUrl = ComponentDetection.makePackageUrl({
|
||||||
|
Scheme: null,
|
||||||
|
Type: null,
|
||||||
|
Namespace: null,
|
||||||
|
Name: null,
|
||||||
|
Version: null,
|
||||||
|
Qualifiers: null
|
||||||
|
});
|
||||||
|
expect(packageUrl).toBe("");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+53
-1
@@ -75,8 +75,24 @@ export default class ComponentDetection {
|
|||||||
|
|
||||||
var json: any = JSON.parse(results);
|
var json: any = JSON.parse(results);
|
||||||
json.componentsFound.forEach(async (component: any) => {
|
json.componentsFound.forEach(async (component: any) => {
|
||||||
|
// Skip components without packageUrl
|
||||||
|
if (!component.component.packageUrl) {
|
||||||
|
core.debug(`Skipping component detected without packageUrl: ${JSON.stringify({
|
||||||
|
id: component.component.id,
|
||||||
|
name: component.component.name || 'unnamed',
|
||||||
|
type: component.component.type || 'unknown'
|
||||||
|
}, null, 2)}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const packageUrl = ComponentDetection.makePackageUrl(component.component.packageUrl);
|
const packageUrl = ComponentDetection.makePackageUrl(component.component.packageUrl);
|
||||||
|
|
||||||
|
// Skip if the packageUrl is empty (indicates an invalid or missing packageUrl)
|
||||||
|
if (!packageUrl) {
|
||||||
|
core.debug(`Skipping component with invalid packageUrl: ${component.component.id}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!packageCache.hasPackage(packageUrl)) {
|
if (!packageCache.hasPackage(packageUrl)) {
|
||||||
const pkg = new ComponentDetectionPackage(packageUrl, component.component.id,
|
const pkg = new ComponentDetectionPackage(packageUrl, component.component.id,
|
||||||
component.isDevelopmentDependency, component.topLevelReferrers, component.locationsFoundAt, component.containerDetailIds, component.containerLayerIds);
|
component.isDevelopmentDependency, component.topLevelReferrers, component.locationsFoundAt, component.containerDetailIds, component.containerLayerIds);
|
||||||
@@ -89,10 +105,28 @@ export default class ComponentDetection {
|
|||||||
core.debug("Sorting out transitive dependencies");
|
core.debug("Sorting out transitive dependencies");
|
||||||
packages.forEach(async (pkg: ComponentDetectionPackage) => {
|
packages.forEach(async (pkg: ComponentDetectionPackage) => {
|
||||||
pkg.topLevelReferrers.forEach(async (referrer: any) => {
|
pkg.topLevelReferrers.forEach(async (referrer: any) => {
|
||||||
const referrerPackage = packageCache.lookupPackage(ComponentDetection.makePackageUrl(referrer.packageUrl));
|
// Skip if referrer doesn't have a valid packageUrl
|
||||||
|
if (!referrer.packageUrl) {
|
||||||
|
core.debug(`Skipping referrer without packageUrl for component: ${pkg.id}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const referrerUrl = ComponentDetection.makePackageUrl(referrer.packageUrl);
|
||||||
|
|
||||||
|
// Skip if the generated packageUrl is empty
|
||||||
|
if (!referrerUrl) {
|
||||||
|
core.debug(`Skipping referrer with invalid packageUrl for component: ${pkg.id}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const referrerPackage = packageCache.lookupPackage(referrerUrl);
|
||||||
if (referrerPackage) {
|
if (referrerPackage) {
|
||||||
referrerPackage.dependsOn(pkg);
|
referrerPackage.dependsOn(pkg);
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
core.debug(`Error looking up referrer package: ${error}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -121,6 +155,19 @@ export default class ComponentDetection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static makePackageUrl(packageUrlJson: any): string {
|
public static makePackageUrl(packageUrlJson: any): string {
|
||||||
|
// Handle case when packageUrlJson is null or undefined
|
||||||
|
if (
|
||||||
|
!packageUrlJson ||
|
||||||
|
typeof packageUrlJson.Scheme !== 'string' ||
|
||||||
|
typeof packageUrlJson.Type !== 'string' ||
|
||||||
|
!packageUrlJson.Scheme ||
|
||||||
|
!packageUrlJson.Type
|
||||||
|
) {
|
||||||
|
core.debug(`Warning: Received null or undefined packageUrlJson. Unable to create package URL.`);
|
||||||
|
return ""; // Return a blank string for unknown packages
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
var packageUrl = `${packageUrlJson.Scheme}:${packageUrlJson.Type}/`;
|
var packageUrl = `${packageUrlJson.Scheme}:${packageUrlJson.Type}/`;
|
||||||
if (packageUrlJson.Namespace) {
|
if (packageUrlJson.Namespace) {
|
||||||
packageUrl += `${packageUrlJson.Namespace.replaceAll("@", "%40")}/`;
|
packageUrl += `${packageUrlJson.Namespace.replaceAll("@", "%40")}/`;
|
||||||
@@ -138,6 +185,11 @@ export default class ComponentDetection {
|
|||||||
packageUrl += `?${qualifierString}`;
|
packageUrl += `?${qualifierString}`;
|
||||||
}
|
}
|
||||||
return packageUrl;
|
return packageUrl;
|
||||||
|
} catch (error) {
|
||||||
|
core.debug(`Error creating package URL from packageUrlJson: ${JSON.stringify(packageUrlJson, null, 2)}`);
|
||||||
|
core.debug(`Error details: ${error}`);
|
||||||
|
return ""; // Return a blank string for error cases
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async getLatestReleaseURL(): Promise<string> {
|
private static async getLatestReleaseURL(): Promise<string> {
|
||||||
|
|||||||
+47
-1
@@ -36059,7 +36059,21 @@ class ComponentDetection {
|
|||||||
const results = yield fs_1.default.readFileSync(this.outputPath, 'utf8');
|
const results = yield fs_1.default.readFileSync(this.outputPath, 'utf8');
|
||||||
var json = JSON.parse(results);
|
var json = JSON.parse(results);
|
||||||
json.componentsFound.forEach((component) => __awaiter(this, void 0, void 0, function* () {
|
json.componentsFound.forEach((component) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
// Skip components without packageUrl
|
||||||
|
if (!component.component.packageUrl) {
|
||||||
|
core.debug(`Skipping component detected without packageUrl: ${JSON.stringify({
|
||||||
|
id: component.component.id,
|
||||||
|
name: component.component.name || 'unnamed',
|
||||||
|
type: component.component.type || 'unknown'
|
||||||
|
}, null, 2)}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const packageUrl = ComponentDetection.makePackageUrl(component.component.packageUrl);
|
const packageUrl = ComponentDetection.makePackageUrl(component.component.packageUrl);
|
||||||
|
// Skip if the packageUrl is empty (indicates an invalid or missing packageUrl)
|
||||||
|
if (!packageUrl) {
|
||||||
|
core.debug(`Skipping component with invalid packageUrl: ${component.component.id}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!packageCache.hasPackage(packageUrl)) {
|
if (!packageCache.hasPackage(packageUrl)) {
|
||||||
const pkg = new ComponentDetectionPackage(packageUrl, component.component.id, component.isDevelopmentDependency, component.topLevelReferrers, component.locationsFoundAt, component.containerDetailIds, component.containerLayerIds);
|
const pkg = new ComponentDetectionPackage(packageUrl, component.component.id, component.isDevelopmentDependency, component.topLevelReferrers, component.locationsFoundAt, component.containerDetailIds, component.containerLayerIds);
|
||||||
packageCache.addPackage(pkg);
|
packageCache.addPackage(pkg);
|
||||||
@@ -36070,10 +36084,26 @@ class ComponentDetection {
|
|||||||
core.debug("Sorting out transitive dependencies");
|
core.debug("Sorting out transitive dependencies");
|
||||||
packages.forEach((pkg) => __awaiter(this, void 0, void 0, function* () {
|
packages.forEach((pkg) => __awaiter(this, void 0, void 0, function* () {
|
||||||
pkg.topLevelReferrers.forEach((referrer) => __awaiter(this, void 0, void 0, function* () {
|
pkg.topLevelReferrers.forEach((referrer) => __awaiter(this, void 0, void 0, function* () {
|
||||||
const referrerPackage = packageCache.lookupPackage(ComponentDetection.makePackageUrl(referrer.packageUrl));
|
// Skip if referrer doesn't have a valid packageUrl
|
||||||
|
if (!referrer.packageUrl) {
|
||||||
|
core.debug(`Skipping referrer without packageUrl for component: ${pkg.id}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const referrerUrl = ComponentDetection.makePackageUrl(referrer.packageUrl);
|
||||||
|
// Skip if the generated packageUrl is empty
|
||||||
|
if (!referrerUrl) {
|
||||||
|
core.debug(`Skipping referrer with invalid packageUrl for component: ${pkg.id}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const referrerPackage = packageCache.lookupPackage(referrerUrl);
|
||||||
if (referrerPackage) {
|
if (referrerPackage) {
|
||||||
referrerPackage.dependsOn(pkg);
|
referrerPackage.dependsOn(pkg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
core.debug(`Error looking up referrer package: ${error}`);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
// Create manifests
|
// Create manifests
|
||||||
@@ -36101,6 +36131,16 @@ class ComponentDetection {
|
|||||||
return pkg.isDevelopmentDependency ? 'development' : 'runtime';
|
return pkg.isDevelopmentDependency ? 'development' : 'runtime';
|
||||||
}
|
}
|
||||||
static makePackageUrl(packageUrlJson) {
|
static makePackageUrl(packageUrlJson) {
|
||||||
|
// Handle case when packageUrlJson is null or undefined
|
||||||
|
if (!packageUrlJson ||
|
||||||
|
typeof packageUrlJson.Scheme !== 'string' ||
|
||||||
|
typeof packageUrlJson.Type !== 'string' ||
|
||||||
|
!packageUrlJson.Scheme ||
|
||||||
|
!packageUrlJson.Type) {
|
||||||
|
core.debug(`Warning: Received null or undefined packageUrlJson. Unable to create package URL.`);
|
||||||
|
return ""; // Return a blank string for unknown packages
|
||||||
|
}
|
||||||
|
try {
|
||||||
var packageUrl = `${packageUrlJson.Scheme}:${packageUrlJson.Type}/`;
|
var packageUrl = `${packageUrlJson.Scheme}:${packageUrlJson.Type}/`;
|
||||||
if (packageUrlJson.Namespace) {
|
if (packageUrlJson.Namespace) {
|
||||||
packageUrl += `${packageUrlJson.Namespace.replaceAll("@", "%40")}/`;
|
packageUrl += `${packageUrlJson.Namespace.replaceAll("@", "%40")}/`;
|
||||||
@@ -36119,6 +36159,12 @@ class ComponentDetection {
|
|||||||
}
|
}
|
||||||
return packageUrl;
|
return packageUrl;
|
||||||
}
|
}
|
||||||
|
catch (error) {
|
||||||
|
core.debug(`Error creating package URL from packageUrlJson: ${JSON.stringify(packageUrlJson, null, 2)}`);
|
||||||
|
core.debug(`Error details: ${error}`);
|
||||||
|
return ""; // Return a blank string for error cases
|
||||||
|
}
|
||||||
|
}
|
||||||
static getLatestReleaseURL() {
|
static getLatestReleaseURL() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let githubToken = core.getInput('token') || process.env.GITHUB_TOKEN || "";
|
let githubToken = core.getInput('token') || process.env.GITHUB_TOKEN || "";
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user