Skip to content
Open
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
20 changes: 17 additions & 3 deletions src/packageurl/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,17 +142,31 @@ def _validate_namespace(cls, purl):
message=f"Namespace is not lowercased for purl type: {cls.type!r}",
)

if purl.namespace and any(
segment in (".", "..") for segment in purl.namespace.split("/")
):
yield ValidationMessage(
severity=ValidationSeverity.ERROR,
message=f"Namespace contains a '.' or '..' path segment: {purl.namespace!r}",
)

@classmethod
def _validate_name(cls, purl):
if not cls.name_case_sensitive and purl.name and purl.name.lower() != purl.name:
from packageurl import ValidationMessage
from packageurl import ValidationSeverity
from packageurl import ValidationMessage
from packageurl import ValidationSeverity

if not cls.name_case_sensitive and purl.name and purl.name.lower() != purl.name:
yield ValidationMessage(
severity=ValidationSeverity.WARNING,
message=f"Name is not lowercased for purl type: {cls.type!r}",
)

if purl.name in (".", ".."):
yield ValidationMessage(
severity=ValidationSeverity.ERROR,
message=f"Name cannot be a '.' or '..' path segment: {purl.name!r}",
)

@classmethod
def _validate_version(cls, purl):
if not cls.version_case_sensitive and purl.version and purl.version.lower() != purl.version:
Expand Down
37 changes: 37 additions & 0 deletions tests/test_packageurl.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,3 +388,40 @@ def test_no_encoding_to_string():
p.to_string(encode=False)
== "pkg:nuget/an:odd:space/libiconv: character set conversion library@1.9?package-id=e11a609df352e292"
)


def test_validate_string_reports_dot_segments_in_namespace():
# https://github.com/package-url/packageurl-python/issues/228
from packageurl import PackageURL
from packageurl import ValidationSeverity

messages = PackageURL.validate_string("pkg:golang/busybox.org/../busybox@1.35.0")
assert any(
m.severity == ValidationSeverity.ERROR and "'.' or '..' path segment" in m.message
for m in messages
)

messages = PackageURL.validate_string("pkg:golang/busybox.org/./busybox@1.35.0")
assert any(
m.severity == ValidationSeverity.ERROR and "'.' or '..' path segment" in m.message
for m in messages
)


def test_validate_string_reports_dot_segments_as_name():
from packageurl import PackageURL
from packageurl import ValidationSeverity

messages = PackageURL.validate_string("pkg:golang/busybox.org/..@1.35.0")
assert any(
m.severity == ValidationSeverity.ERROR and "'.' or '..'" in m.message
for m in messages
)


def test_validate_string_accepts_dotted_names_and_namespaces():
from packageurl import PackageURL

assert not PackageURL.validate_string("pkg:golang/busybox.org/busybox@1.35.0")
# names and namespace segments that merely contain dots are fine
assert not PackageURL.validate_string("pkg:golang/example.com/my..pkg@1.0.0")