Skip to content

Commit 6fdcbbb

Browse files
committedAug 20, 2024
Correctly encode PURLs in SBOM output
1 parent fe36a0d commit 6fdcbbb

File tree

7 files changed

+38
-7
lines changed

7 files changed

+38
-7
lines changed
 

‎node/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [5.2.2]
4+
5+
### Bugfix
6+
7+
- Encode purls correctly in SBOM
8+
39
## [5.2.1]
410

511
### Bugfix

‎node/lib/retire.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
var exports = exports || {};
7-
exports.version = '5.2.1';
7+
exports.version = '5.2.2';
88

99
function isDefined(o) {
1010
return typeof o !== 'undefined';

‎node/package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎node/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"author": "Erlend Oftedal <erlend@oftedal.no>",
33
"name": "retire",
44
"description": "Retire is a tool for detecting use of vulnerable libraries",
5-
"version": "5.2.1",
5+
"version": "5.2.2",
66
"license": "Apache-2.0",
77
"repository": {
88
"type": "git",

‎node/spec/tests/purl.spec.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { should } from 'chai';
2+
import 'mocha';
3+
should();
4+
import { generatePURL } from '../../lib/reporters/utils';
5+
6+
describe('purl encoding', () => {
7+
it('should not touch a simple string', () => {
8+
generatePURL({ component: 'jquery', version: '1.2.3' }).should.equal('pkg:npm/jquery@1.2.3');
9+
});
10+
it('should encode @ in package scopes', () => {
11+
generatePURL({ component: '@angular/core', version: '1.2.3' }).should.equal('pkg:npm/%40angular/core@1.2.3');
12+
});
13+
it('should not doulbe encode', () => {
14+
generatePURL({ component: '%40angular/core', version: '1.2.3' }).should.equal('pkg:npm/%40angular/core@1.2.3');
15+
});
16+
});

‎node/src/repo.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export function validateRepository(
104104
bowername: z.array(z.string().regex(/^[a-z0-9.-]+$/i)).optional(),
105105
basePurl: z
106106
.string()
107-
.regex(/^pkg:[a-z0-9/]+$/i)
107+
.regex(/^pkg:[a-z0-9%.-/]+$/i)
108108
.optional(),
109109
npmname: z
110110
.string()

‎node/src/reporters/utils.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
import { Component } from '../types';
22

3+
function encodePURLchars(str: string): string {
4+
return str.replace(
5+
/[^A-Za-z0-9.+/=-%]/g,
6+
(match) => '%' + ('0' + match.charCodeAt(0).toString(16).toUpperCase()).slice(-2),
7+
);
8+
}
9+
310
export function generatePURL(component: Component): string {
411
if (component.basePurl) {
5-
return component.basePurl + '@' + component.version;
12+
const [pType, ...rest] = component.basePurl.split(':');
13+
const pathElements = rest.join(':').split('/').map(encodePURLchars).join('/');
14+
return `${pType}:${pathElements}@${encodePURLchars(component.version)}`;
615
}
716
const compName = component.npmname || component.component;
8-
return `pkg:npm/${compName}@${component.version}`;
17+
return `pkg:npm/${encodePURLchars(compName)}@${encodePURLchars(component.version)}`;
918
}

0 commit comments

Comments
 (0)
Failed to load comments.