Skip to content

Commit

Permalink
fix: XML serialize normalizedString and token properly (#646)
Browse files Browse the repository at this point in the history
fixes #638

---------

Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
  • Loading branch information
jkowalleck authored Jul 8, 2024
1 parent ce6991b commit b40f739
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 1 deletion.
9 changes: 9 additions & 0 deletions cyclonedx/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def flow(self, flow: DataFlow) -> None:

@property
@serializable.xml_name('.')
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def classification(self) -> str:
"""
Data classification tags data according to its type, sensitivity, and value if altered, stolen, or destroyed.
Expand Down Expand Up @@ -182,6 +183,7 @@ def __init__(
@property
@serializable.xml_attribute()
@serializable.xml_name('content-type')
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def content_type(self) -> str:
"""
Specifies the content type of the text. Defaults to text/plain if not specified.
Expand Down Expand Up @@ -468,6 +470,7 @@ def alg(self, alg: HashAlgorithm) -> None:

@property
@serializable.xml_name('.')
@serializable.xml_string(serializable.XmlStringSerializationType.TOKEN)
def content(self) -> str:
"""
Hash value content.
Expand Down Expand Up @@ -889,6 +892,7 @@ def name(self, name: str) -> None:

@property
@serializable.xml_name('.')
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def value(self) -> Optional[str]:
"""
Value of this Property.
Expand Down Expand Up @@ -1128,6 +1132,7 @@ def __init__(

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def vendor(self) -> Optional[str]:
"""
The name of the vendor who created the tool.
Expand All @@ -1143,6 +1148,7 @@ def vendor(self, vendor: Optional[str]) -> None:

@property
@serializable.xml_sequence(2)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def name(self) -> Optional[str]:
"""
The name of the tool.
Expand All @@ -1158,6 +1164,7 @@ def name(self, name: Optional[str]) -> None:

@property
@serializable.xml_sequence(3)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def version(self) -> Optional[str]:
"""
The version of the tool.
Expand Down Expand Up @@ -1268,6 +1275,7 @@ def timestamp(self, timestamp: Optional[datetime]) -> None:
self._timestamp = timestamp

@property
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def name(self) -> Optional[str]:
"""
The name of the individual who performed the action.
Expand All @@ -1282,6 +1290,7 @@ def name(self, name: Optional[str]) -> None:
self._name = name

@property
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def email(self) -> Optional[str]:
"""
The email address of the individual who performed the action.
Expand Down
10 changes: 10 additions & 0 deletions cyclonedx/model/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ def __init__(

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def uid(self) -> Optional[str]:
"""
A unique identifier of the commit. This may be version control specific. For example, Subversion uses revision
Expand Down Expand Up @@ -155,6 +156,7 @@ def committer(self, committer: Optional[IdentifiableAction]) -> None:

@property
@serializable.xml_sequence(5)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def message(self) -> Optional[str]:
"""
The text description of the contents of the commit.
Expand Down Expand Up @@ -1151,6 +1153,7 @@ def type(self, type: ComponentType) -> None:
self._type = type

@property
@serializable.xml_string(serializable.XmlStringSerializationType.TOKEN)
def mime_type(self) -> Optional[str]:
"""
Get any declared mime-type for this Component.
Expand Down Expand Up @@ -1256,6 +1259,7 @@ def authors(self, authors: Iterable[OrganizationalContact]) -> None:
@serializable.view(SchemaVersion1Dot5)
@serializable.view(SchemaVersion1Dot6) # todo: this is deprecated in v1.6?
@serializable.xml_sequence(4)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def author(self) -> Optional[str]:
"""
The person(s) or organization(s) that authored the component.
Expand All @@ -1271,6 +1275,7 @@ def author(self, author: Optional[str]) -> None:

@property
@serializable.xml_sequence(5)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def publisher(self) -> Optional[str]:
"""
The person(s) or organization(s) that published the component
Expand All @@ -1286,6 +1291,7 @@ def publisher(self, publisher: Optional[str]) -> None:

@property
@serializable.xml_sequence(6)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def group(self) -> Optional[str]:
"""
The grouping name or identifier. This will often be a shortened, single name of the company or project that
Expand All @@ -1305,6 +1311,7 @@ def group(self, group: Optional[str]) -> None:

@property
@serializable.xml_sequence(7)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def name(self) -> str:
"""
The name of the component.
Expand All @@ -1328,6 +1335,7 @@ def name(self, name: str) -> None:
@serializable.include_none(SchemaVersion1Dot2, '')
@serializable.include_none(SchemaVersion1Dot3, '')
@serializable.xml_sequence(8)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def version(self) -> Optional[str]:
"""
The component version. The version should ideally comply with semantic versioning but is not enforced.
Expand All @@ -1348,6 +1356,7 @@ def version(self, version: Optional[str]) -> None:

@property
@serializable.xml_sequence(9)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def description(self) -> Optional[str]:
"""
Get the description of this Component.
Expand Down Expand Up @@ -1419,6 +1428,7 @@ def licenses(self, licenses: Iterable[License]) -> None:

@property
@serializable.xml_sequence(13)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def copyright(self) -> Optional[str]:
"""
An optional copyright notice informing users of the underlying claims to copyright ownership in a published
Expand Down
4 changes: 4 additions & 0 deletions cyclonedx/model/contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ def __init__(

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def name(self) -> Optional[str]:
"""
Get the name of the contact.
Expand All @@ -228,6 +229,7 @@ def name(self, name: Optional[str]) -> None:

@property
@serializable.xml_sequence(2)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def email(self) -> Optional[str]:
"""
Get the email of the contact.
Expand All @@ -243,6 +245,7 @@ def email(self, email: Optional[str]) -> None:

@property
@serializable.xml_sequence(3)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def phone(self) -> Optional[str]:
"""
Get the phone of the contact.
Expand Down Expand Up @@ -305,6 +308,7 @@ def __init__(

@property
@serializable.xml_sequence(10)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def name(self) -> Optional[str]:
"""
Get the name of the organization.
Expand Down
4 changes: 4 additions & 0 deletions cyclonedx/model/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def __init__(
self.url = url

@property
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def name(self) -> Optional[str]:
"""
The name of the source. For example "National Vulnerability Database", "NVD", and "Apache".
Expand Down Expand Up @@ -151,6 +152,7 @@ def type(self, type: IssueClassification) -> None:

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def id(self) -> Optional[str]:
"""
The identifier of the issue assigned by the source of the issue.
Expand All @@ -166,6 +168,7 @@ def id(self, id: Optional[str]) -> None:

@property
@serializable.xml_sequence(2)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def name(self) -> Optional[str]:
"""
The name of the issue.
Expand All @@ -181,6 +184,7 @@ def name(self, name: Optional[str]) -> None:

@property
@serializable.xml_sequence(3)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def description(self) -> Optional[str]:
"""
A description of the issue.
Expand Down
2 changes: 2 additions & 0 deletions cyclonedx/model/license.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def id(self, id: Optional[str]) -> None:

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def name(self) -> Optional[str]:
"""
If SPDX does not define the license used, this field may be used to provide the license name.
Expand Down Expand Up @@ -257,6 +258,7 @@ def __init__(

@property
@serializable.xml_name('.')
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
@serializable.json_name('expression')
def value(self) -> str:
"""
Expand Down
3 changes: 3 additions & 0 deletions cyclonedx/model/release_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def __init__(

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def type(self) -> str:
"""
The software versioning type.
Expand Down Expand Up @@ -148,6 +149,7 @@ def timestamp(self, timestamp: Optional[datetime]) -> None:

@property
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'alias')
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
@serializable.xml_sequence(7)
def aliases(self) -> 'SortedSet[str]':
"""
Expand All @@ -165,6 +167,7 @@ def aliases(self, aliases: Iterable[str]) -> None:

@property
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'tag')
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
@serializable.xml_sequence(8)
def tags(self) -> 'SortedSet[str]':
"""
Expand Down
4 changes: 4 additions & 0 deletions cyclonedx/model/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def provider(self, provider: Optional[OrganizationalEntity]) -> None:

@property
@serializable.xml_sequence(2)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def group(self) -> Optional[str]:
"""
The grouping name, namespace, or identifier. This will often be a shortened, single name of the company or
Expand All @@ -135,6 +136,7 @@ def group(self, group: Optional[str]) -> None:

@property
@serializable.xml_sequence(3)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def name(self) -> str:
"""
The name of the service. This will often be a shortened, single name of the service.
Expand All @@ -150,6 +152,7 @@ def name(self, name: str) -> None:

@property
@serializable.xml_sequence(4)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def version(self) -> Optional[str]:
"""
The service version.
Expand All @@ -165,6 +168,7 @@ def version(self, version: Optional[str]) -> None:

@property
@serializable.xml_sequence(5)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def description(self) -> Optional[str]:
"""
Specifies a description for the service.
Expand Down
6 changes: 6 additions & 0 deletions cyclonedx/model/vulnerability.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def __init__(

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def version(self) -> Optional[str]:
"""
A single version of a component or service.
Expand Down Expand Up @@ -354,6 +355,7 @@ def __init__(

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def title(self) -> Optional[str]:
"""
The title of this advisory.
Expand Down Expand Up @@ -422,6 +424,7 @@ def __init__(

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def name(self) -> Optional[str]:
"""
Name of this Source.
Expand Down Expand Up @@ -493,6 +496,7 @@ def __init__(

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def id(self) -> Optional[str]:
"""
The identifier that uniquely identifies the vulnerability in the associated Source. For example: CVE-2021-39182.
Expand Down Expand Up @@ -803,6 +807,7 @@ def method(self, score_source: Optional[VulnerabilityScoreSource]) -> None:

@property
@serializable.xml_sequence(5)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def vector(self) -> Optional[str]:
"""
The textual representation of the metric values used to score the vulnerability - also known as the vector.
Expand Down Expand Up @@ -994,6 +999,7 @@ def bom_ref(self) -> BomRef:

@property
@serializable.xml_sequence(1)
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def id(self) -> Optional[str]:
"""
The identifier that uniquely identifies the vulnerability. For example: CVE-2021-39182.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ keywords = [
[tool.poetry.dependencies]
python = "^3.8"
packageurl-python = ">=0.11, <2"
py-serializable = ">=1.0.3, <2"
py-serializable = "^1.1.0"
sortedcontainers = "^2.4.0"
license-expression = "^30"
jsonschema = { version = "^4.18", extras=['format'], optional=true }
Expand Down

0 comments on commit b40f739

Please sign in to comment.