Make purl comparisons case insensitive

This commit is contained in:
Justin Holguín
2026-02-20 22:01:04 +00:00
committed by GitHub
parent b49f407d39
commit 8cf743c0ea
4 changed files with 40 additions and 7 deletions

View File

@@ -225,3 +225,25 @@ test('purlsMatch matches packages without namespaces', () => {
const b = parsePURL('pkg:npm/lodash@5.0.0')
expect(purlsMatch(a, b)).toBe(true)
})
test('purlsMatch is case-insensitive for GitHub Actions', () => {
const a = parsePURL('pkg:githubactions/MyOrg/MyAction@1.0.0')
const b = parsePURL('pkg:githubactions/myorg/myaction@1.0.0')
expect(purlsMatch(a, b)).toBe(true)
})
test('purlsMatch is case-insensitive for scoped npm packages', () => {
const a = parsePURL('pkg:npm/@MyScope/MyPackage')
const b = parsePURL('pkg:npm/@myscope/mypackage')
expect(purlsMatch(a, b)).toBe(true)
})
test('purlsMatch is case-insensitive for GitHub Actions with file paths', () => {
const a = parsePURL(
'pkg:githubactions/MyOrg/MyWorkflows/.github/workflows/general.yml'
)
const b = parsePURL(
'pkg:githubactions/myorg/myworkflows/.github/workflows/general.yml'
)
expect(purlsMatch(a, b)).toBe(true)
})

16
dist/index.js generated vendored
View File

@@ -1151,11 +1151,15 @@ function fullName(purl) {
// 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'}.
//
// The comparison is case-insensitive because most ecosystems and registries
// treat names that way (npm, PyPI, GitHub org/repo names, etc.).
function purlsMatch(a, b) {
if (a.type !== b.type) {
var _a, _b;
if (a.type.toLowerCase() !== b.type.toLowerCase()) {
return false;
}
return fullName(a) === fullName(b);
return ((_a = fullName(a)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === ((_b = fullName(b)) === null || _b === void 0 ? void 0 : _b.toLowerCase());
}
@@ -98064,11 +98068,15 @@ function fullName(purl) {
// 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'}.
//
// The comparison is case-insensitive because most ecosystems and registries
// treat names that way (npm, PyPI, GitHub org/repo names, etc.).
function purlsMatch(a, b) {
if (a.type !== b.type) {
var _a, _b;
if (a.type.toLowerCase() !== b.type.toLowerCase()) {
return false;
}
return fullName(a) === fullName(b);
return ((_a = fullName(a)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === ((_b = fullName(b)) === null || _b === void 0 ? void 0 : _b.toLowerCase());
}

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@@ -86,9 +86,12 @@ function fullName(purl: PackageURL): string | null {
// 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'}.
//
// The comparison is case-insensitive because most ecosystems and registries
// treat names that way (npm, PyPI, GitHub org/repo names, etc.).
export function purlsMatch(a: PackageURL, b: PackageURL): boolean {
if (a.type !== b.type) {
if (a.type.toLowerCase() !== b.type.toLowerCase()) {
return false
}
return fullName(a) === fullName(b)
return fullName(a)?.toLowerCase() === fullName(b)?.toLowerCase()
}