Compare normalized purls to account for encoding quirks

This commit is contained in:
Justin Holguín
2026-02-20 00:02:42 +00:00
committed by GitHub
parent 9284e0c621
commit 2ced98cbe8
6 changed files with 140 additions and 11 deletions
Generated Vendored
+45 -3
View File
@@ -552,9 +552,7 @@ function groupChanges(changes_1) {
// We want to find if the licenseExclusion list contains the PackageURL of the Change
// If it does, we want to filter it out and therefore return false
// If it doesn't, we want to keep it and therefore return true
if (licenseExclusions.findIndex(exclusion => exclusion.type === changeAsPackageURL.type &&
exclusion.namespace === changeAsPackageURL.namespace &&
exclusion.name === changeAsPackageURL.name) !== -1) {
if (licenseExclusions.findIndex(exclusion => (0, purl_1.purlsMatch)(exclusion, changeAsPackageURL)) !== -1) {
return false;
}
else {
@@ -1070,6 +1068,7 @@ var __importStar = (this && this.__importStar) || (function () {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PurlSchema = void 0;
exports.parsePURL = parsePURL;
exports.purlsMatch = purlsMatch;
const z = __importStar(__nccwpck_require__(34809));
// the basic purl type, containing type, namespace, name, and version.
// other than type, all fields are nullable. this is for maximum flexibility
@@ -1137,6 +1136,27 @@ function parsePURL(purl) {
// we don't parse subpath or attributes, so we're done here
return result;
}
// Returns the full name of a package, combining namespace and name.
// This normalizes PURLs where the namespace separator '/' may have been
// percent-encoded as '%2F', causing it to be parsed as part of the name
// rather than splitting namespace and name.
function fullName(purl) {
var _a;
if (purl.namespace && purl.name) {
return `${purl.namespace}/${purl.name}`;
}
return (_a = purl.name) !== null && _a !== void 0 ? _a : purl.namespace;
}
// Compare two PackageURLs for equality, ignoring version and normalizing
// namespace/name splits. This handles the case where a PURL like
// 'pkg:npm/%40scope%2Fname' is parsed as {namespace: null, name: '@scope/name'}
// while 'pkg:npm/%40scope/name' is parsed as {namespace: '@scope', name: 'name'}.
function purlsMatch(a, b) {
if (a.type !== b.type) {
return false;
}
return fullName(a) === fullName(b);
}
/***/ }),
@@ -97961,6 +97981,7 @@ var __importStar = (this && this.__importStar) || (function () {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PurlSchema = void 0;
exports.parsePURL = parsePURL;
exports.purlsMatch = purlsMatch;
const z = __importStar(__nccwpck_require__(34809));
// the basic purl type, containing type, namespace, name, and version.
// other than type, all fields are nullable. this is for maximum flexibility
@@ -98028,6 +98049,27 @@ function parsePURL(purl) {
// we don't parse subpath or attributes, so we're done here
return result;
}
// Returns the full name of a package, combining namespace and name.
// This normalizes PURLs where the namespace separator '/' may have been
// percent-encoded as '%2F', causing it to be parsed as part of the name
// rather than splitting namespace and name.
function fullName(purl) {
var _a;
if (purl.namespace && purl.name) {
return `${purl.namespace}/${purl.name}`;
}
return (_a = purl.name) !== null && _a !== void 0 ? _a : purl.namespace;
}
// Compare two PackageURLs for equality, ignoring version and normalizing
// namespace/name splits. This handles the case where a PURL like
// 'pkg:npm/%40scope%2Fname' is parsed as {namespace: null, name: '@scope/name'}
// while 'pkg:npm/%40scope/name' is parsed as {namespace: '@scope', name: 'name'}.
function purlsMatch(a, b) {
if (a.type !== b.type) {
return false;
}
return fullName(a) === fullName(b);
}
/***/ }),
Generated Vendored
+1 -1
View File
File diff suppressed because one or more lines are too long