@@ -262,24 +262,25 @@ def parse_cyclonedx_spdx(self) -> [(str, str, str)]:
262
262
# If Package URL or CPE record found, use this data in preference to package data
263
263
ext_ref = package .get ("externalreference" )
264
264
if ext_ref is not None :
265
- vendor , package_name , version = self .parse_ext_ref (ext_ref = ext_ref )
266
-
267
- # For any data not found in CPE or the Package URL get from package data
268
- if not vendor :
269
- pass # Because no vendor was detected then all vendors with this named package
270
- # will be included in the output.
271
-
272
- if not package_name :
273
- package_name = package ["name" ]
274
-
275
- if (not version ) and (package .get ("version" ) is not None ):
276
- version = package ["version" ]
277
- elif version is None :
278
- LOGGER .debug (f"No version found in { package } " )
279
-
280
- if version :
281
- # Found at least package and version, save the results
282
- modules .append ([vendor , package_name , version ])
265
+ external_references = self .parse_ext_ref (ext_ref = ext_ref )
266
+ # Store the data for each external reference
267
+ for vendor , package_name , version in external_references :
268
+ # For any data not found in CPE or the Package URL get from package data
269
+ if not vendor :
270
+ pass # Because no vendor was detected then all vendors with this named package
271
+ # will be included in the output.
272
+
273
+ if not package_name :
274
+ package_name = package ["name" ]
275
+
276
+ if (not version ) and (package .get ("version" ) is not None ):
277
+ version = package ["version" ]
278
+ elif version is None :
279
+ LOGGER .debug (f"No version found in { package } " )
280
+
281
+ if version :
282
+ # Found at least package and version, save the results
283
+ modules .append ([vendor , package_name , version ])
283
284
284
285
LOGGER .debug (f"Parsed SBOM { self .filename } { modules } " )
285
286
return modules
@@ -320,7 +321,7 @@ def extract(self, swid: str) -> list[str]:
320
321
# As some version numbers have leading 'v', it is removed
321
322
return [item [0 ].strip (" " ), item [1 ], item [2 ].upper ().replace ("V" , "" )]
322
323
323
- def parse_ext_ref (self , ext_ref ) -> ( str | None , str | None , str | None ) :
324
+ def parse_ext_ref (self , ext_ref ) -> list [ tuple [ str | None , str | None , str | None ]] :
324
325
"""
325
326
Parse external references in an SBOM to extract module information.
326
327
@@ -337,34 +338,40 @@ def parse_ext_ref(self, ext_ref) -> (str | None, str | None, str | None):
337
338
338
339
"""
339
340
decoded = {}
341
+ results = []
340
342
for ref in ext_ref :
341
343
ref_type = ref [1 ]
342
344
ref_string = ref [2 ]
345
+ if ref_type == "purl" :
346
+ # Validation of purl is performed implicitly within the decode_purl function
347
+ decoded ["purl" ] = self .decode_purl (ref_string )
348
+
343
349
if ref_type == "cpe23Type" and self .is_valid_string ("cpe23" , ref_string ):
344
350
decoded ["cpe23Type" ] = decode_cpe23 (ref_string )
345
351
346
- elif ref_type == "cpe22Type" and self .is_valid_string ("cpe22" , ref_string ):
352
+ if ref_type == "cpe22Type" and self .is_valid_string ("cpe22" , ref_string ):
347
353
decoded ["cpe22Type" ] = decode_cpe22 (ref_string )
348
354
349
- elif ref_type == "purl" :
350
- # Validation of purl is performed implicitly within the decode_purl function
351
- decoded ["purl" ] = self .decode_purl (ref_string )
352
-
353
355
# No ext-ref matches, return none
354
356
if decoded .get ("purl" ) is not None :
355
357
LOGGER .debug ("Found PURL" )
356
- return decoded .get ("purl" )
357
- elif decoded .get ("cpe23Type" ) is not None :
358
+ results .append (decoded .get ("purl" ))
359
+
360
+ if decoded .get ("cpe23Type" ) is not None :
358
361
LOGGER .debug ("Found CPE23" )
359
- return decoded .get ("cpe23Type" )
360
- elif decoded .get ("cpe22Type" ) is not None :
362
+ results .append (decoded .get ("cpe23Type" ))
363
+
364
+ if decoded .get ("cpe22Type" ) is not None :
361
365
LOGGER .debug ("Found CPE22" )
362
- return decoded .get ("cpe22Type" )
363
- else :
366
+ results .append (decoded .get ("cpe22Type" ))
367
+
368
+ if results == []:
364
369
LOGGER .debug ("Nothing found" )
365
- return [None , None , None ]
370
+ results .append ([None , None , None ])
371
+
372
+ return results
366
373
367
- def decode_purl (self , purl ) -> ( str | None , str | None , str | None ) :
374
+ def decode_purl (self , purl ) -> tuple [ str | None , str | None , str | None ] :
368
375
"""
369
376
Decode a Package URL (purl) to extract version information.
370
377
0 commit comments