Repository: spdx/tools-python

Issue:
TV-Parser raises IndexError if package has no SPDXID
When trying to parse a tag value which has a package without spdxid which precedes a file (so implying a CONTAINS relationship) an uncaught `IndexError` is raised.

Discussion:

Patch:
diff --git a/src/spdx_tools/spdx/parser/tagvalue/parser.py b/src/spdx_tools/spdx/parser/tagvalue/parser.py
index e6ce74d..623226b 100644
--- a/src/spdx_tools/spdx/parser/tagvalue/parser.py
+++ b/src/spdx_tools/spdx/parser/tagvalue/parser.py
@@ -580,6 +580,12 @@ class Parser:
         # information that follows any package information is assigned to the last parsed package by creating a
         # corresponding contains relationship.
         # (see https://spdx.github.io/spdx-spec/v2.3/composition-of-an-SPDX-document/#5.2.2)
+        if not self.elements_built["packages"]:
+            self.logger.append(
+                f"Error while building contains relationship for file {file_spdx_id}, "
+                f"preceding package was not parsed successfully."
+            )
+            return
         package_spdx_id = self.elements_built["packages"][-1].spdx_id
         relationship = Relationship(package_spdx_id, RelationshipType.CONTAINS, file_spdx_id)
         if relationship not in self.elements_built.setdefault("relationships", []):


Test patch:
diff --git a/tests/spdx/parser/tagvalue/test_tag_value_parser.py b/tests/spdx/parser/tagvalue/test_tag_value_parser.py
index cb53814..33defcb 100644
--- a/tests/spdx/parser/tagvalue/test_tag_value_parser.py
+++ b/tests/spdx/parser/tagvalue/test_tag_value_parser.py
@@ -54,6 +54,31 @@ def test_building_contains_relationship():
     ]
 
 
+def test_build_contains_relationship_with_error():
+    parser = Parser()
+    file_spdx_ids = ["SPDXRef-File-in-Package", "SPDXRef-Second-File-in-Package"]
+    document_str = "\n".join(
+        [
+            DOCUMENT_STR,
+            "PackageName: Package with two files",
+            "PackageDownloadLocation: https://download.com",
+            "FileName: File in package",
+            f"SPDXID: {file_spdx_ids[0]}",
+            "FileChecksum: SHA1: d6a770ba38583ed4bb4525bd96e50461655d2759",
+            "FileName: Second file in package",
+            f"SPDXID: {file_spdx_ids[1]}",
+            "FileChecksum: SHA1: d6a770ba38583ed4bb4525bd96e50461655d2759",
+        ]
+    )
+    with pytest.raises(SPDXParsingError) as err:
+        parser.parse(document_str)
+    for file_spdx_id in file_spdx_ids:
+        assert (
+            f"Error while building contains relationship for file {file_spdx_id}, preceding package was not "
+            "parsed successfully." in err.value.get_messages()
+        )
+
+
 def test_document_with_mixed_values():
     parser = Parser()
     document_str = "\n".join(