Skip to content

Commit

Permalink
hotfix: properly handle purl encoding
Browse files Browse the repository at this point in the history
* remove unneed exception raising for the version param
* do not skip URL encoding `:` and `+` characters
* add test cases from old issues

refs: #45, #46, #57

Signed-off-by: Steven Esser <[email protected]>
  • Loading branch information
steven-esser committed Nov 9, 2023
1 parent aa6d185 commit 09776a6
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 15 deletions.
14 changes: 2 additions & 12 deletions src/package-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ class PackageURL {
purl.push('/');
}

purl.push(encodeURIComponent(this.name).replace(/%3A/g, ':'));
purl.push(encodeURIComponent(this.name));

if (this.version) {
purl.push('@');
purl.push(encodeURIComponent(this.version).replace(/%3A/g, ':').replace(/%2B/g,'+'));
purl.push(encodeURIComponent(this.version));
}

if (this.qualifiers) {
Expand All @@ -126,7 +126,6 @@ class PackageURL {
if (this.subpath) {
purl.push('#');
purl.push(encodeURIComponent(this.subpath)
.replace(/%3A/g, ':')
.replace(/%2F/g, '/'));
}

Expand Down Expand Up @@ -186,15 +185,6 @@ class PackageURL {
let rawVersion= path.substring(index + 1);
version = decodeURIComponent(rawVersion);

// Convert percent-encoded colons (:) back, to stay in line with the `toString`
// implementation of this library.
// https://github.com/package-url/packageurl-js/blob/58026c86978c6e356e5e07f29ecfdccbf8829918/src/package-url.js#L98C10-L98C10
let versionEncoded = encodeURIComponent(version).replace(/%3A/g, ':').replace(/%2B/g,'+');

if (rawVersion !== versionEncoded) {
throw new Error('Invalid purl: version must be percent-encoded');
}

remainder = path.substring(0, index);
} else {
remainder = path;
Expand Down
90 changes: 87 additions & 3 deletions test/data/test-suite-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
{
"description": "debian can have debian versions as part of version with plus sign",
"purl": "pkg:deb/debian/[email protected]+deb10u3?arch=amd64&distro=debian-10",
"canonical_purl": "pkg:deb/debian/[email protected]+deb10u3?arch=amd64&distro=debian-10",
"canonical_purl": "pkg:deb/debian/[email protected]%2Bdeb10u3?arch=amd64&distro=debian-10",
"type": "deb",
"namespace": "debian",
"name": "libssl1.1",
Expand All @@ -122,7 +122,7 @@
{
"description": "docker uses qualifiers and hash image id as versions",
"purl": "pkg:docker/customer/dockerimage@sha256:244fd47e07d1004f0aed9c?repository_url=gcr.io",
"canonical_purl": "pkg:docker/customer/dockerimage@sha256:244fd47e07d1004f0aed9c?repository_url=gcr.io",
"canonical_purl": "pkg:docker/customer/dockerimage@sha256%3A244fd47e07d1004f0aed9c?repository_url=gcr.io",
"type": "docker",
"namespace": "customer",
"name": "dockerimage",
Expand Down Expand Up @@ -422,13 +422,97 @@
{
"description": "colon present in name is a valid PURL",
"purl": "pkg:maven/:[email protected]",
"canonical_purl": "pkg:maven/:spring[email protected]",
"canonical_purl": "pkg:maven/%3Aspring[email protected]",
"type": "maven",
"namespace": null,
"name": ":spring-context",
"version": "5.2.8-RELEASE",
"qualifiers": null,
"subpath": null,
"is_invalid": false
},
{
"description": "Plus sign handled correctly in version",
"purl": "pkg:maven/a@2+3",
"canonical_purl": "pkg:maven/a@2%2B3",
"type": "maven",
"namespace": null,
"name": "a",
"version": "2+3",
"qualifiers": null,
"subpath": null,
"is_invalid": false
},
{
"description": "Encoded plus sign handled correctly in version",
"purl": "pkg:maven/a@2%2B3",
"canonical_purl": "pkg:maven/a@2%2B3",
"type": "maven",
"namespace": null,
"name": "a",
"version": "2+3",
"qualifiers": null,
"subpath": null,
"is_invalid": false
},
{
"description": "Plus sign handled correctly in version 2",
"purl": "pkg:pypi/[email protected]+cpu",
"canonical_purl": "pkg:pypi/[email protected]%2Bcpu",
"type": "pypi",
"namespace": null,
"name": "torchaudio",
"version": "2.0.1+cpu",
"qualifiers": null,
"subpath": null,
"is_invalid": false
},
{
"description": "Plus sign handled correctly in version 3",
"purl": "pkg:deb/debian/[email protected]+deb9u1?arch=amd64&upstream=gettext&distro=debian-9",
"canonical_purl": "pkg:deb/debian/[email protected]%2Bdeb9u1?arch=amd64&distro=debian-9&upstream=gettext",
"type": "deb",
"namespace": "debian",
"name": "gettext-base",
"version": "0.19.8.1-2+deb9u1",
"qualifiers": {"arch": "amd64", "distro": "debian-9", "upstream": "gettext"},
"subpath": null,
"is_invalid": false
},
{
"description": "Plus sign handled correctly in version 4",
"purl": "pkg:deb/debian/libprocps3@2:3.3.9-9+deb8u1?arch=amd64&upstream=procps&distro=debian-8",
"canonical_purl": "pkg:deb/debian/libprocps3@2%3A3.3.9-9%2Bdeb8u1?arch=amd64&distro=debian-8&upstream=procps",
"type": "deb",
"namespace": "debian",
"name": "libprocps3",
"version": "2:3.3.9-9+deb8u1",
"qualifiers": {"arch": "amd64", "distro": "debian-8", "upstream": "procps"},
"subpath": null,
"is_invalid": false
},
{
"description": "Plus sign handled correctly in version 5",
"purl": "pkg:deb/debian/[email protected]+deb10u3?arch=amd64&upstream=openssl&distro=debian-10",
"canonical_purl": "pkg:deb/debian/[email protected]%2Bdeb10u3?arch=amd64&distro=debian-10&upstream=openssl",
"type": "deb",
"namespace": "debian",
"name": "libssl1.1",
"version": "1.1.1n-0+deb10u3",
"qualifiers": {"arch": "amd64", "distro": "debian-10", "upstream": "openssl"},
"subpath": null,
"is_invalid": false
},
{
"description": "Handle colon in package name",
"purl": "pkg:generic/:[email protected]",
"canonical_purl": "pkg:generic/%[email protected]",
"type": "generic",
"namespace": null,
"name": ":name",
"version": "1.0.0",
"qualifiers": null,
"subpath": null,
"is_invalid": false
}
]

0 comments on commit 09776a6

Please sign in to comment.