Description
ComparablePackageURL in cyclonedx/_internal/compare.py builds its comparison tuple from type, namespace, version, qualifiers and subpath, but not name:
return super().__new__(cls, (
p.type,
p.namespace,
p.version,
ComparableDict(p.qualifiers) if isinstance(p.qualifiers, dict) else p.qualifiers,
p.subpath
))
So two different packages compare equal whenever everything except the name matches:
>>> ComparablePackageURL(PackageURL(type="pypi", name="foo", version="1.0.0")) \
... == ComparablePackageURL(PackageURL(type="pypi", name="bar", version="1.0.0"))
True
Both produce the tuple ("pypi", None, "1.0.0", (), None).
name is a required component of a purl and is the main thing that distinguishes one package from another, so leaving it out makes the comparison much weaker than intended. Anything that sorts or compares components by purl treats unrelated packages as interchangeable, and ordering between them is then decided by whatever the sort algorithm happens to do, which is not stable across inputs.
Expected
name participates in the comparison, in its canonical purl position between namespace and version.
I have a fix and a regression test ready and will open a PR referencing this issue.
Description
ComparablePackageURLincyclonedx/_internal/compare.pybuilds its comparison tuple from type, namespace, version, qualifiers and subpath, but notname:So two different packages compare equal whenever everything except the name matches:
Both produce the tuple
("pypi", None, "1.0.0", (), None).nameis a required component of a purl and is the main thing that distinguishes one package from another, so leaving it out makes the comparison much weaker than intended. Anything that sorts or compares components by purl treats unrelated packages as interchangeable, and ordering between them is then decided by whatever the sort algorithm happens to do, which is not stable across inputs.Expected
nameparticipates in the comparison, in its canonical purl position between namespace and version.I have a fix and a regression test ready and will open a PR referencing this issue.