Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions PURL-SPECIFICATION.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,11 @@ The rules for each component are:

- **type**:

- The package ``type`` is composed only of ASCII letters and numbers, '.', '+'
and '-' (period, plus, and dash)
- The ``type`` cannot start with a number
- The ``type`` cannot contain spaces
- The ``type`` must NOT be percent-encoded
- The ``type`` is case insensitive. The canonical form is lowercase
- The package ``type`` MUST be composed only of ASCII letters and numbers,
'.', '+' and '-' (period, plus, and dash).
- The ``type`` MUST start with an ASCII letter.
- The ``type`` MUST NOT be percent-encoded.
- The ``type`` is case insensitive. The canonical form is lowercase.
Copy link
Member

@jkowalleck jkowalleck Feb 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️ we have the canonicalization in the test suite already:

"description": "valid go purl with version and subpath",
"purl": "pkg:GOLANG/google.golang.org/genproto@abcdedf#/googleapis/api/annotations/",
"canonical_purl": "pkg:golang/google.golang.org/genproto@abcdedf#googleapis/api/annotations",
"type": "golang",
"namespace": "google.golang.org",
"name": "genproto",
"version": "abcdedf",
"qualifiers": null,
"subpath": "googleapis/api/annotations",
"is_invalid": false



- **namespace**:
Expand Down Expand Up @@ -265,7 +264,7 @@ To build a ``purl`` string from its components:

- Start a ``purl`` string with the "pkg:" ``scheme`` as a lowercase ASCII string

- Append the ``type`` string to the ``purl`` as a lowercase ASCII string
- Append the ``type`` string to the ``purl`` as an unencoded lowercase ASCII string

- Append '/' to the ``purl``

Expand Down
15 changes: 15 additions & 0 deletions faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,18 @@ For example, although these two purls are strictly equivalent, the first is in c
The "Rules for each ``purl`` component" section provides that "[t]he ``scheme`` MUST be followed by an unencoded colon ':'.

In this case, the colon ':' between ``scheme`` and ``type`` is being used as a separator, and consequently should be used as-is, never encoded and never requiring any decoding. Moreover, it should be a parsing error if the colon ':' does not come directly after 'pkg'. Tools are welcome to recover from this error to help with malformed purls, but that's not a requirement.


Type
~~~~

**QUESTION**: What behavior is expected from a purl spec implementation if a
``type`` contains a character like a slash '/' or a colon ':'?

The "Rules for each purl component" section provides that

[t]he package ``type`` MUST be composed only of ASCII letters and numbers,
'.', '+' and '-' (period, plus, and dash)

As a result, a purl spec implementation must return an error when encountering
a ``type`` that contains a prohibited character.
42 changes: 39 additions & 3 deletions test-suite-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@
"type": null,
"namespace": null,
"name": "EnterpriseLibrary.Common",
"version": null,
"version": "6.0.1304",
"qualifiers": null,
"subpath": null,
"is_invalid": true
Expand Down Expand Up @@ -252,7 +252,7 @@
"is_invalid": false
},
{
"description": "slash /// after type is not significant",
"description": "slash /// after scheme is not significant",
"purl": "pkg:///maven/org.apache.commons/io",
"canonical_purl": "pkg:maven/org.apache.commons/io",
"type": "maven",
Expand Down Expand Up @@ -638,13 +638,49 @@
{
"description": "invalid encoded colon : between scheme and type",
"purl": "pkg%3Amaven/org.apache.commons/io",
"canonical_purl": "pkg:maven/org.apache.commons/io",
"canonical_purl": null,
"type": "maven",
"namespace": "org.apache.commons",
"name": "io",
"version": null,
"qualifiers": null,
"subpath": null,
"is_invalid": true
},
{
"description": "check for invalid character in type",
"purl": "pkg:n&g?inx/[email protected]",
"canonical_purl": null,
"type": null,
"namespace": null,
"name": "nginx",
"version": "0.8.9",
"qualifiers": null,
"subpath": null,
"is_invalid": true
},
{
"description": "check for type that starts with number",
"purl": "pkg:3nginx/[email protected]",
"canonical_purl": null,
"type": null,
"namespace": null,
"name": "nginx",
"version": "0.8.9",
"qualifiers": null,
"subpath": null,
"is_invalid": true
},
{
"description": "check for colon in type",
"purl": "pkg:nginx:a/[email protected]",
"canonical_purl": null,
"type": null,
"namespace": null,
"name": "nginx",
"version": "0.8.9",
"qualifiers": null,
"subpath": null,
"is_invalid": true
}
]