Skip to content

Commit 0f41ee0

Browse files
author
Meret Behrens
committed
[issue-650] raise ParsingError if elements don't have an SPDXID
Signed-off-by: Meret Behrens <meret.behrens@tngtech.com>
1 parent 6a7e500 commit 0f41ee0

8 files changed

Lines changed: 113 additions & 10 deletions

File tree

src/spdx_tools/spdx/parser/rdf/file_parser.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# SPDX-FileCopyrightText: 2023 spdx contributors
22
#
33
# SPDX-License-Identifier: Apache-2.0
4-
from rdflib import RDFS, Graph, URIRef
4+
from typing import Union
5+
6+
from rdflib import RDFS, BNode, Graph, URIRef
57

68
from spdx_tools.spdx.model import File, FileType
79
from spdx_tools.spdx.parser.logger import Logger
@@ -23,7 +25,7 @@
2325
from spdx_tools.spdx.rdfschema.namespace import SPDX_NAMESPACE
2426

2527

26-
def parse_file(file_node: URIRef, graph: Graph, doc_namespace: str) -> File:
28+
def parse_file(file_node: Union[URIRef, BNode], graph: Graph, doc_namespace: str) -> File:
2729
logger = Logger()
2830
spdx_id = parse_spdx_id(file_node, doc_namespace, graph)
2931
name = parse_literal(logger, graph, file_node, SPDX_NAMESPACE.fileName)

src/spdx_tools/spdx/parser/rdf/graph_parsing_functions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ def parse_enum_value(enum_str: str, enum_class: Type[Enum], prefix: str) -> Enum
8686
raise SPDXParsingError([f"Invalid value for {enum_class}: {enum_str}"])
8787

8888

89-
def parse_spdx_id(resource: URIRef, doc_namespace: str, graph: Graph) -> Optional[str]:
90-
if not resource:
89+
def parse_spdx_id(resource: Union[URIRef, BNode], doc_namespace: str, graph: Graph) -> Optional[str]:
90+
if not resource or isinstance(resource, BNode):
9191
return None
9292
if resource.startswith(f"{doc_namespace}#"):
9393
return resource.fragment

src/spdx_tools/spdx/parser/rdf/package_parser.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-FileCopyrightText: 2023 spdx contributors
22
#
33
# SPDX-License-Identifier: Apache-2.0
4-
from typing import Optional
4+
from typing import Optional, Union
55

66
from rdflib import DOAP, RDFS, Graph, URIRef
77
from rdflib.term import BNode
@@ -34,7 +34,7 @@
3434
from spdx_tools.spdx.rdfschema.namespace import REFERENCE_NAMESPACE, SPDX_NAMESPACE
3535

3636

37-
def parse_package(package_node: URIRef, graph: Graph, doc_namespace: str) -> Package:
37+
def parse_package(package_node: Union[URIRef, BNode], graph: Graph, doc_namespace: str) -> Package:
3838
logger = Logger()
3939
spdx_id = parse_spdx_id(package_node, doc_namespace, graph)
4040
name = parse_literal(logger, graph, package_node, SPDX_NAMESPACE.name)
@@ -120,7 +120,6 @@ def parse_package(package_node: URIRef, graph: Graph, doc_namespace: str) -> Pac
120120
valid_until_date = parse_literal(
121121
logger, graph, package_node, SPDX_NAMESPACE.validUntilDate, parsing_method=datetime_from_str
122122
)
123-
124123
raise_parsing_error_if_logger_has_messages(logger, "Package")
125124
package = construct_or_raise_parsing_error(
126125
Package,

src/spdx_tools/spdx/parser/rdf/snippet_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-FileCopyrightText: 2023 spdx contributors
22
#
33
# SPDX-License-Identifier: Apache-2.0
4-
from typing import Dict, Optional, Tuple
4+
from typing import Dict, Optional, Tuple, Union
55

66
from rdflib import RDF, RDFS, Graph
77
from rdflib.exceptions import UniquenessError
@@ -27,7 +27,7 @@
2727
from spdx_tools.spdx.rdfschema.namespace import POINTER_NAMESPACE, SPDX_NAMESPACE
2828

2929

30-
def parse_snippet(snippet_node: URIRef, graph: Graph, doc_namespace: str) -> Snippet:
30+
def parse_snippet(snippet_node: Union[URIRef, BNode], graph: Graph, doc_namespace: str) -> Snippet:
3131
logger = Logger()
3232
spdx_id = parse_spdx_id(snippet_node, doc_namespace, graph)
3333
file_spdx_id_uri = get_value_from_graph(
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<rdf:RDF
3+
xmlns:spdx="http://spdx.org/rdf/terms#"
4+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
5+
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
6+
xmlns:ptr="http://www.w3.org/2009/pointers#"
7+
>
8+
<spdx:SpdxDocument rdf:about="https://some.namespace#SPDXRef-DOCUMENT">
9+
<rdfs:comment>documentComment</rdfs:comment>
10+
<spdx:name>documentName</spdx:name>
11+
<spdx:dataLicense rdf:resource="http://spdx.org/licenses/CC0-1.0"/>
12+
<spdx:creationInfo>
13+
<spdx:CreationInfo rdf:nodeID="N80af30c2c55b44afb3a7cf4124ed9aff">
14+
<spdx:licenseListVersion>3.19</spdx:licenseListVersion>
15+
<spdx:created>2022-12-01T00:00:00Z</spdx:created>
16+
</spdx:CreationInfo>
17+
</spdx:creationInfo>
18+
</spdx:SpdxDocument>
19+
<spdx:Package>
20+
<spdx:name>packageName</spdx:name>
21+
<spdx:downloadLocation>http://differentdownload.com</spdx:downloadLocation>
22+
</spdx:Package>
23+
<spdx:File>
24+
<spdx:checksum>
25+
<spdx:Checksum rdf:nodeID="Nab58c45c3b81449e9d4fbcb81940ceee">
26+
<spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha1"/>
27+
<spdx:checksumValue>71c4025dd9897b364f3ebbb42c484ff43d00791c</spdx:checksumValue>
28+
</spdx:Checksum>
29+
</spdx:checksum>
30+
<spdx:fileName>./fileName.py</spdx:fileName>
31+
</spdx:File>
32+
<spdx:Snippet>
33+
<spdx:range>
34+
<ptr:StartEndPointer rdf:nodeID="N77e7b08564a0412a9413b90ff9b3ddd9">
35+
<ptr:startPointer>
36+
<ptr:ByteOffsetPointer rdf:nodeID="N89d93c1292de424f9aa75ee1e297ede9">
37+
<ptr:offset rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">1</ptr:offset>
38+
<ptr:reference rdf:resource="https://some.namespace#SPDXRef-File"/>
39+
</ptr:ByteOffsetPointer>
40+
</ptr:startPointer>
41+
<ptr:endPointer>
42+
<ptr:ByteOffsetPointer rdf:nodeID="N7099800c04534fcc8a998b551fee34ce">
43+
<ptr:reference rdf:resource="https://some.namespace#SPDXRef-File"/>
44+
<ptr:offset rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">2</ptr:offset>
45+
</ptr:ByteOffsetPointer>
46+
</ptr:endPointer>
47+
</ptr:StartEndPointer>
48+
</spdx:range>
49+
<spdx:snippetFromFile/>
50+
</spdx:Snippet>
51+
</rdf:RDF>
52+
53+

tests/spdx/parser/rdf/test_file_parser.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import os
55
from unittest import TestCase
66

7+
import pytest
78
from license_expression import get_spdx_licensing
8-
from rdflib import RDF, Graph, URIRef
9+
from rdflib import RDF, BNode, Graph, URIRef
910

1011
from spdx_tools.spdx.model import Checksum, ChecksumAlgorithm, FileType, SpdxNoAssertion
12+
from spdx_tools.spdx.parser.error import SPDXParsingError
1113
from spdx_tools.spdx.parser.rdf.file_parser import parse_file
1214
from spdx_tools.spdx.rdfschema.namespace import SPDX_NAMESPACE
1315

@@ -35,3 +37,18 @@ def test_parse_file():
3537
assert file.license_comment == "licenseComment"
3638
assert file.notice == "fileNotice"
3739
assert file.attribution_texts == ["fileAttributionText"]
40+
41+
42+
def test_parse_invalid_file():
43+
graph = Graph().parse(os.path.join(os.path.dirname(__file__), "data/invalid_documents/file_without_spdx_ids.xml"))
44+
file_node = graph.value(predicate=RDF.type, object=SPDX_NAMESPACE.File)
45+
doc_namespace = "https://some.namespace"
46+
47+
assert isinstance(file_node, BNode)
48+
with pytest.raises(SPDXParsingError) as err:
49+
parse_file(file_node, graph, doc_namespace)
50+
51+
assert err.value.get_messages() == [
52+
"Error while constructing File: ['SetterError File: type of argument "
53+
'"spdx_id" must be str; got NoneType instead: None\']'
54+
]

tests/spdx/parser/rdf/test_package_parser.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
PackageVerificationCode,
1919
SpdxNoAssertion,
2020
)
21+
from spdx_tools.spdx.parser.error import SPDXParsingError
2122
from spdx_tools.spdx.parser.rdf.package_parser import parse_external_package_ref, parse_package
2223
from spdx_tools.spdx.rdfschema.namespace import SPDX_NAMESPACE
2324

@@ -95,3 +96,18 @@ def test_external_package_ref_parser(download_location, category, locator, type,
9596
assert external_package_ref.locator == locator
9697
assert external_package_ref.reference_type == type
9798
assert external_package_ref.comment == comment
99+
100+
101+
def test_parse_invalid_package():
102+
graph = Graph().parse(os.path.join(os.path.dirname(__file__), "data/invalid_documents/file_without_spdx_ids.xml"))
103+
package_node = graph.value(predicate=RDF.type, object=SPDX_NAMESPACE.Package)
104+
doc_namespace = "https://some.namespace"
105+
106+
assert isinstance(package_node, BNode)
107+
with pytest.raises(SPDXParsingError) as err:
108+
parse_package(package_node, graph, doc_namespace)
109+
110+
assert err.value.get_messages() == [
111+
"Error while constructing Package: ['SetterError Package: type of argument "
112+
'"spdx_id" must be str; got NoneType instead: None\']'
113+
]

tests/spdx/parser/rdf/test_snippet_parser.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,19 @@ def add_range_to_graph_helper(graph, predicate_value_class_member):
159159
graph.add((pointer_node, RDF.type, pointer_class))
160160
graph.add((start_end_pointer, predicate, pointer_node))
161161
graph.add((pointer_node, pointer_member, Literal(value)))
162+
163+
164+
def test_parse_invalid_file():
165+
graph = Graph().parse(os.path.join(os.path.dirname(__file__), "data/invalid_documents/file_without_spdx_ids.xml"))
166+
snippet_node = graph.value(predicate=RDF.type, object=SPDX_NAMESPACE.Snippet)
167+
doc_namespace = "https://some.namespace"
168+
169+
assert isinstance(snippet_node, BNode)
170+
with pytest.raises(SPDXParsingError) as err:
171+
parse_snippet(snippet_node, graph, doc_namespace)
172+
173+
assert err.value.get_messages() == [
174+
"Error while constructing Snippet: ['SetterError Snippet: type of argument "
175+
"\"spdx_id\" must be str; got NoneType instead: None', 'SetterError Snippet: "
176+
'type of argument "file_spdx_id" must be str; got NoneType instead: None\']'
177+
]

0 commit comments

Comments
 (0)