@@ -55,31 +55,36 @@ def digest_hex_val(self) -> str:
5555 _ , val = self .digest .split (":" )
5656 return val
5757
58- def purls (self , index_digest : Optional [str ] = None ) -> list [str ]:
59- ans = []
60- if index_digest and self .arch :
61- ans .append (
62- PackageURL (
63- type = "oci" ,
64- name = self .name ,
65- version = index_digest ,
66- qualifiers = {"arch" : self .arch , "repository_url" : self .repository },
67- ).to_string ()
68- )
69- ans .append (
70- PackageURL (
71- type = "oci" ,
72- name = self .name ,
73- version = self .digest ,
74- qualifiers = {"repository_url" : self .repository },
75- ).to_string ()
76- )
77- return ans
58+ def purls (self , index_digest : str ) -> list [str ]:
59+ purl = PackageURL (
60+ type = "oci" ,
61+ name = self .name ,
62+ version = index_digest ,
63+ qualifiers = {"arch" : self .arch , "repository_url" : self .repository },
64+ ).to_string ()
65+
66+ # HACK: There's a bug in PackageURL python that incorrectly handles
67+ # encoding of ':' characters. When this PR is merged, the hack should be
68+ # removed: https://github.com/package-url/packageurl-python/pull/178
69+ return [self ._hack_purl_encoding (purl )]
7870
7971 def propose_spdx_id (self ) -> str :
8072 purl_hex_digest = hashlib .sha256 (self .purls ()[0 ].encode ()).hexdigest ()
8173 return f"SPDXRef-image-{ self .name } -{ purl_hex_digest } "
8274
75+ def _hack_purl_encoding (purl : str ) -> str :
76+ """
77+ Encode ':' characters in PURL that are not the scheme and type separator.
78+ """
79+ if purl .count (":" ) == 1 :
80+ return purl
81+
82+ first_idx = purl .find (":" )
83+ after_first = purl [first_idx + 1 :]
84+ after_first = after_first .replace (":" , "%3A" )
85+
86+ return f"{ purl [:first_idx ]} :{ after_first } "
87+
8388
8489def create_package (image : Image , spdxid : Optional [str ] = None , image_index_digest : Optional [str ] = None ) -> dict :
8590 return {
0 commit comments