diff --git a/src/encode.js b/src/encode.js index a7a6a66..c548d70 100644 --- a/src/encode.js +++ b/src/encode.js @@ -10,6 +10,12 @@ const { isNonEmptyString } = require('./strings') const { encodeURIComponent } = globalThis +function encodeName(name) { + return isNonEmptyString(name) + ? encodeURIComponent(name).replace(/%3A/g, ':') + : '' +} + function encodeNamespace(namespace) { return isNonEmptyString(namespace) ? encodeURIComponent(namespace) @@ -63,6 +69,7 @@ function replacePlusSignWithPercentEncodedSpace(str) { } module.exports = { + encodeName, encodeNamespace, encodeVersion, encodeQualifiers, diff --git a/src/purl-component.js b/src/purl-component.js index 4a03aa2..20828dc 100644 --- a/src/purl-component.js +++ b/src/purl-component.js @@ -1,6 +1,7 @@ 'use strict' const { + encodeName, encodeNamespace, encodeVersion, encodeQualifiers, @@ -66,6 +67,7 @@ module.exports = { PurlComponent: createHelpersNamespaceObject( { encode: { + name: encodeName, namespace: encodeNamespace, version: encodeVersion, qualifiers: encodeQualifiers, diff --git a/test/data/contrib-tests.json b/test/data/contrib-tests.json index 4f689f7..7a414b6 100644 --- a/test/data/contrib-tests.json +++ b/test/data/contrib-tests.json @@ -1,13 +1,13 @@ [ { - "description": "scheme is lowercased", - "purl": "PkG:type/foo/bar@1.0.0", - "canonical_purl": "pkg:type/foo/bar@1.0.0", - "type": "type", - "namespace": "foo", - "name": "bar", - "version": "1.0.0", - "qualifiers": null, + "description": "debian can have debian versions as part of version with plus sign", + "purl": "pkg:deb/debian/libssl1.1@1.1.1n-0+deb10u3?arch=amd64&distro=debian-10", + "canonical_purl": "pkg:deb/debian/libssl1.1@1.1.1n-0+deb10u3?arch=amd64&distro=debian-10", + "type": "deb", + "namespace": "debian", + "name": "libssl1.1", + "version": "1.1.1n-0+deb10u3", + "qualifiers": {"arch": "amd64", "distro": "debian-10"}, "subpath": null, "is_invalid": false }, @@ -23,18 +23,6 @@ "subpath": null, "is_invalid": false }, - { - "description": "debian can have debian versions as part of version with plus sign", - "purl": "pkg:deb/debian/libssl1.1@1.1.1n-0+deb10u3?arch=amd64&distro=debian-10", - "canonical_purl": "pkg:deb/debian/libssl1.1@1.1.1n-0+deb10u3?arch=amd64&distro=debian-10", - "type": "deb", - "namespace": "debian", - "name": "libssl1.1", - "version": "1.1.1n-0+deb10u3", - "qualifiers": {"arch": "amd64", "distro": "debian-10"}, - "subpath": null, - "is_invalid": false - }, { "description": "valid go purl with namespace that has more than one forward slash", "purl": "pkg:golang/github.com/cncf/xds/go@v0.0.0-20210922020428-25de7278fc84", @@ -47,6 +35,18 @@ "subpath": null, "is_invalid": false }, + { + "description": "maven requires a namespace", + "purl": "pkg:maven/io@1.3.4", + "canonical_purl": "pkg:maven/io@1.3.4", + "type": "maven", + "namespace": null, + "name": null, + "version": null, + "qualifiers": null, + "subpath": null, + "is_invalid": true + }, { "description": "validates pub name (valid)", "purl": "pkg:pub/flutter_downloader@1.0.0", @@ -59,6 +59,18 @@ "subpath": null, "is_invalid": false }, + { + "description": "scheme is lowercased", + "purl": "PkG:type/foo/bar@1.0.0", + "canonical_purl": "pkg:type/foo/bar@1.0.0", + "type": "type", + "namespace": "foo", + "name": "bar", + "version": "1.0.0", + "qualifiers": null, + "subpath": null, + "is_invalid": false + }, { "description": "namespace can contain special characters", "purl": "pkg:type/%40namespace%40%3F%23/name@1.0.0", @@ -108,25 +120,25 @@ "is_invalid": false }, { - "description": "maven requires a namespace", - "purl": "pkg:maven/io@1.3.4", - "canonical_purl": "pkg:maven/io@1.3.4", - "type": "maven", - "namespace": null, - "name": null, - "version": null, + "description": "leading and trailing slashes '/' are not significant and should be stripped in the canonical form", + "purl": "pkg:type//github.com///ll////xlog@v1.0.0", + "canonical_purl": "pkg:type/github.com/ll/xlog@v1.0.0", + "type": "type", + "namespace": "github.com/ll", + "name": "xlog", + "version": "v1.0.0", "qualifiers": null, "subpath": null, - "is_invalid": true + "is_invalid": false }, { - "description": "leading and trailing slashes '/' are not significant and should be stripped in the canonical form", - "purl": "pkg:golang//github.com///ll////xlog@v2.0.0", - "canonical_purl": "pkg:golang/github.com/ll/xlog@v2.0.0", - "type": "golang", - "namespace": "github.com/ll", - "name": "xlog", - "version": "v2.0.0", + "description": "the colon ':' does not need to be encoded as '%3A'", + "purl": "pkg:type/fo:o/ba:r@v1.0.0", + "canonical_purl": "pkg:type/fo:o/ba:r@v1.0.0", + "type": "type", + "namespace": "fo:o", + "name": "ba:r", + "version": "v1.0.0", "qualifiers": null, "subpath": null, "is_invalid": false