Skip to content
Draft
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
64 changes: 32 additions & 32 deletions test-suite-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,57 +27,57 @@
"description": "valid go purl without version and with subpath",
"purl": "pkg:GOLANG/google.golang.org/genproto#/googleapis/api/annotations/",
"canonical_purl": "pkg:golang/google.golang.org/genproto#googleapis/api/annotations",
"type": "golang",
"type": "GOLANG",
"namespace": "google.golang.org",
"name": "genproto",
"version": null,
"qualifiers": null,
"subpath": "googleapis/api/annotations",
"subpath": "/googleapis/api/annotations/",
Copy link
Member

Choose a reason for hiding this comment

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

The subpath is speced as normalized by stripping slashes:
Leading and trailing slashes '/' are not significant and SHOULD be stripped in the canonical form .... we need to clarify what is the relationship between each test fields first.

Copy link
Member Author

@jkowalleck jkowalleck Mar 12, 2025

Choose a reason for hiding this comment

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

we need to clarify what is the relationship between each test fields first.

is this not clear from current spec?

To test ``purl`` parsing and building, a tool can use this test suite and for
every listed test object, run these tests:
- parsing the test canonical ``purl`` then re-building a ``purl`` from these parsed
components should return the test canonical ``purl``
- parsing the test ``purl`` should return the components parsed from the test
canonical ``purl``
- parsing the test ``purl`` then re-building a ``purl`` from these parsed components
should return the test canonical ``purl``
- building a ``purl`` from the test components should return the test canonical ``purl``

it is stated, that test fields are used only as an input for crafting a purl. and the result is expected to be the canonical purl.

building a purl from the test components should return the test canonical purl

Copy link
Contributor

Choose a reason for hiding this comment

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

This field should have the unnormalized form for the tests to work properly.

contains an array of objects. Each object represents a test with these key/value
pairs some of which may not be normalized:

- parsing the test canonical ``purl`` then re-building a ``purl`` from these parsed
components should return the test canonical ``purl``
- parsing the test ``purl`` should return the components parsed from the test
canonical ``purl``
- parsing the test ``purl`` then re-building a ``purl`` from these parsed components
should return the test canonical ``purl``
- building a ``purl`` from the test components should return the test canonical ``purl``

If these fields contain the normalized form, then the tests do not ensure that normalization happens when building a PURL from components. An implementation that normalizes only during parsing would incorrectly pass the current version of the test because the PURL is built from the pre-normalized components and those components do not require further normalization, but that implementation would correctly fail with the proposed components.

Of course some implementations of the test suite have this backwards and parse the canonical PURL and assert that its fields match the components here, and those implementations will not work with the new version of the file, but those implementations of the test suite do not ensure that normalization happens when building a PURL from components because they have no way to obtain the unnormalized components of the purl field to use as inputs.

"is_invalid": false
},
{
"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",
"type": "GOLANG",
"namespace": "google.golang.org",
"name": "genproto",
"version": "abcdedf",
"qualifiers": null,
"subpath": "googleapis/api/annotations",
"subpath": "/googleapis/api/annotations/",
"is_invalid": false
},
{
"description": "invalid subpath - unencoded subpath cannot contain '..'",
"purl": "pkg:GOLANG/google.golang.org/genproto@abcdedf#/googleapis/%2E%2E/api/annotations/",
"canonical_purl": "pkg:golang/google.golang.org/genproto@abcdedf#googleapis/api/annotations",
"type": "golang",
"type": "GOLANG",
"namespace": "google.golang.org",
"name": "genproto",
"version": "abcdedf",
"qualifiers": null,
"subpath": "googleapis/../api/annotations",
"subpath": "/googleapis/../api/annotations/",
"is_invalid": false
},
{
"description": "invalid subpath - unencoded subpath cannot contain '.'",
"purl": "pkg:GOLANG/google.golang.org/genproto@abcdedf#/googleapis/%2E/api/annotations/",
"canonical_purl": "pkg:golang/google.golang.org/genproto@abcdedf#googleapis/api/annotations",
"type": "golang",
"type": "GOLANG",
"namespace": "google.golang.org",
"name": "genproto",
"version": "abcdedf",
"qualifiers": null,
"subpath": "googleapis/./api/annotations",
"subpath": "/googleapis/./api/annotations/",
"is_invalid": false
},
{
"description": "bitbucket namespace and name should be lowercased",
"purl": "pkg:bitbucket/birKenfeld/pyGments-main@244fd47e07d1014f0aed9c",
"canonical_purl": "pkg:bitbucket/birkenfeld/pygments-main@244fd47e07d1014f0aed9c",
"type": "bitbucket",
"namespace": "birkenfeld",
"name": "pygments-main",
"namespace": "birKenfeld",
"name": "pyGments-main",
"version": "244fd47e07d1014f0aed9c",
"qualifiers": null,
"subpath": null,
Expand All @@ -88,8 +88,8 @@
"purl": "pkg:github/Package-url/purl-Spec@244fd47e07d1004f0aed9c",
"canonical_purl": "pkg:github/package-url/purl-spec@244fd47e07d1004f0aed9c",
"type": "github",
"namespace": "package-url",
"name": "purl-spec",
"namespace": "Package-url",
"name": "purl-Spec",
"version": "244fd47e07d1004f0aed9c",
"qualifiers": null,
"subpath": null,
Expand Down Expand Up @@ -127,39 +127,39 @@
"namespace": null,
"name": "jruby-launcher",
"version": "1.1.2",
"qualifiers": {"platform": "java"},
"qualifiers": {"Platform": "java"},
"subpath": null,
"is_invalid": false
},
{
"description": "maven often uses qualifiers",
"purl": "pkg:Maven/org.apache.xmlgraphics/batik-anim@1.9.1?classifier=sources&repositorY_url=repo.spring.io/release",
"canonical_purl": "pkg:maven/org.apache.xmlgraphics/batik-anim@1.9.1?classifier=sources&repository_url=repo.spring.io/release",
"type": "maven",
"type": "Maven",
"namespace": "org.apache.xmlgraphics",
"name": "batik-anim",
"version": "1.9.1",
"qualifiers": {"classifier": "sources", "repository_url": "repo.spring.io/release"},
"qualifiers": {"classifier": "sources", "repositorY_url": "repo.spring.io/release"},
"subpath": null,
"is_invalid": false
},
{
"description": "maven pom reference",
"purl": "pkg:Maven/org.apache.xmlgraphics/batik-anim@1.9.1?extension=pom&repositorY_url=repo.spring.io/release",
"canonical_purl": "pkg:maven/org.apache.xmlgraphics/batik-anim@1.9.1?extension=pom&repository_url=repo.spring.io/release",
"type": "maven",
"type": "Maven",
"namespace": "org.apache.xmlgraphics",
"name": "batik-anim",
"version": "1.9.1",
"qualifiers": {"extension": "pom", "repository_url": "repo.spring.io/release"},
"qualifiers": {"extension": "pom", "repositorY_url": "repo.spring.io/release"},
"subpath": null,
"is_invalid": false
},
{
"description": "maven can come with a type qualifier",
"purl": "pkg:Maven/net.sf.jacob-project/jacob@1.14.3?classifier=x86&type=dll",
"canonical_purl": "pkg:maven/net.sf.jacob-project/jacob@1.14.3?classifier=x86&type=dll",
"type": "maven",
"type": "Maven",
"namespace": "net.sf.jacob-project",
"name": "jacob",
"version": "1.14.3",
Expand All @@ -183,7 +183,7 @@
"description": "nuget names are case sensitive",
"purl": "pkg:Nuget/EnterpriseLibrary.Common@6.0.1304",
"canonical_purl": "pkg:nuget/EnterpriseLibrary.Common@6.0.1304",
"type": "nuget",
"type": "Nuget",
"namespace": null,
"name": "EnterpriseLibrary.Common",
"version": "6.0.1304",
Expand All @@ -195,9 +195,9 @@
"description": "pypi names have special rules and not case sensitive",
"purl": "pkg:PYPI/Django_package@1.11.1.dev1",
"canonical_purl": "pkg:pypi/django-package@1.11.1.dev1",
"type": "pypi",
"type": "PYPI",
"namespace": null,
"name": "django-package",
"name": "Django_package",
"version": "1.11.1.dev1",
"qualifiers": null,
"subpath": null,
Expand All @@ -207,11 +207,11 @@
"description": "rpm often use qualifiers",
"purl": "pkg:Rpm/fedora/curl@7.50.3-1.fc25?Arch=i386&Distro=fedora-25",
"canonical_purl": "pkg:rpm/fedora/curl@7.50.3-1.fc25?arch=i386&distro=fedora-25",
"type": "rpm",
"type": "Rpm",
"namespace": "fedora",
"name": "curl",
"version": "7.50.3-1.fc25",
"qualifiers": {"arch": "i386", "distro": "fedora-25"},
"qualifiers": {"Arch": "i386", "Distro": "fedora-25"},
"subpath": null,
"is_invalid": false
},
Expand Down Expand Up @@ -449,7 +449,7 @@
"canonical_purl": "pkg:swift/github.com/Alamofire/@5.4.3",
"type": "swift",
"namespace": "github.com/Alamofire",
"name": null,
"name": "",
"version": "5.4.3",
"qualifiers": null,
"subpath": null,
Expand Down Expand Up @@ -522,7 +522,7 @@
"type": "huggingface",
"namespace": "EleutherAI",
"name": "gpt-neo-1.3B",
"version": "797174552ae47f449ab70b684cabcb6603e5e85e",
"version": "797174552AE47F449AB70B684CABCB6603E5E85E",
"qualifiers": null,
"subpath": null,
"is_invalid": false
Expand All @@ -533,7 +533,7 @@
"canonical_purl": "pkg:mlflow/creditfraud@3?repository_url=https://adb-5245952564735461.0.azuredatabricks.net/api/2.0/mlflow",
"type": "mlflow",
"namespace": null,
"name": "creditfraud",
"name": "CreditFraud",
"version": "3",
"qualifiers": {"repository_url": "https://adb-5245952564735461.0.azuredatabricks.net/api/2.0/mlflow"},
"subpath": null,
Expand Down Expand Up @@ -568,8 +568,8 @@
"purl": "pkg:composer/Laravel/Laravel@5.5.0",
"canonical_purl": "pkg:composer/laravel/laravel@5.5.0",
"type": "composer",
"namespace": "laravel",
"name": "laravel",
"namespace": "Laravel",
"name": "Laravel",
"version": "5.5.0",
"qualifiers": null,
"subpath": null,
Expand Down Expand Up @@ -618,7 +618,7 @@
"type": "cpan",
"namespace": "GDT",
"name": "URI::PackageURL",
"version": null,
"version": "2.11",
"qualifiers": null,
"subpath": null,
"is_invalid": true
Expand Down Expand Up @@ -675,7 +675,7 @@
"description": "check for invalid character in type",
"purl": "pkg:n&g?inx/nginx@0.8.9",
"canonical_purl": null,
"type": null,
"type": "n&g?inx",
"namespace": null,
"name": "nginx",
"version": "0.8.9",
Expand All @@ -687,7 +687,7 @@
"description": "check for type that starts with number",
"purl": "pkg:3nginx/nginx@0.8.9",
"canonical_purl": null,
"type": null,
"type": "3nginx",
"namespace": null,
"name": "nginx",
"version": "0.8.9",
Expand All @@ -699,7 +699,7 @@
"description": "check for colon in type",
"purl": "pkg:nginx:a/nginx@0.8.9",
"canonical_purl": null,
"type": null,
"type": "nginx:a",
"namespace": null,
"name": "nginx",
"version": "0.8.9",
Expand Down