Skip to content

Allow serializing of patch resolves items for xml #312

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 27 additions & 22 deletions cyclonedx/output/xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,27 +428,7 @@ def _add_release_notes_element(release_notes: ReleaseNotes, parent_element: Elem
for tag in release_notes.tags:
ElementTree.SubElement(release_notes_tags_e, 'tag').text = tag
if release_notes.resolves:
release_notes_resolves_e = ElementTree.SubElement(release_notes_e, 'resolves')
for issue in release_notes.resolves:
issue_e = ElementTree.SubElement(
release_notes_resolves_e, 'issue', {'type': issue.type.value}
)
if issue.id:
ElementTree.SubElement(issue_e, 'id').text = issue.id
if issue.name:
ElementTree.SubElement(issue_e, 'name').text = issue.name
if issue.description:
ElementTree.SubElement(issue_e, 'description').text = issue.description
if issue.source:
issue_source_e = ElementTree.SubElement(issue_e, 'source')
if issue.source.name:
ElementTree.SubElement(issue_source_e, 'name').text = issue.source.name
if issue.source.url:
ElementTree.SubElement(issue_source_e, 'url').text = str(issue.source.url)
if issue.references:
issue_references_e = ElementTree.SubElement(issue_e, 'references')
for reference in issue.references:
ElementTree.SubElement(issue_references_e, 'url').text = str(reference)
Xml._add_resolves_element(release_notes.resolves, release_notes_e)
if release_notes.notes:
release_notes_notes_e = ElementTree.SubElement(release_notes_e, 'notes')
for note in release_notes.notes:
Expand All @@ -473,9 +453,34 @@ def add_patch_element(patch: Patch) -> ElementTree.Element:
diff_element.append(Xml._add_attached_text(attached_text=patch.diff.text))
if patch.diff.url:
ElementTree.SubElement(diff_element, 'url').text = str(patch.diff.url)

if patch.resolves:
Xml._add_resolves_element(patch.resolves, patch_element)
return patch_element

@staticmethod
def _add_resolves_element(resolves: "SortedSet[IssueType]", parent_element: ElementTree.Element) -> None:
resolves_e = ElementTree.SubElement(parent_element, 'resolves')
for issue in resolves:
issue_e = ElementTree.SubElement(
resolves_e, 'issue', {'type': issue.type.value}
)
if issue.id:
ElementTree.SubElement(issue_e, 'id').text = issue.id
if issue.name:
ElementTree.SubElement(issue_e, 'name').text = issue.name
if issue.description:
ElementTree.SubElement(issue_e, 'description').text = issue.description
if issue.source:
issue_source_e = ElementTree.SubElement(issue_e, 'source')
if issue.source.name:
ElementTree.SubElement(issue_source_e, 'name').text = issue.source.name
if issue.source.url:
ElementTree.SubElement(issue_source_e, 'url').text = str(issue.source.url)
if issue.references:
issue_references_e = ElementTree.SubElement(issue_e, 'references')
for reference in issue.references:
ElementTree.SubElement(issue_references_e, 'url').text = str(reference)

@staticmethod
def _add_properties_element(properties: "SortedSet[Property]", parent_element: ElementTree.Element) -> None:
properties_e = ElementTree.SubElement(parent_element, 'properties')
Expand Down
18 changes: 18 additions & 0 deletions tests/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ def get_bom_with_component_setuptools_complete() -> Bom:
return Bom(components=[get_component_setuptools_complete()])


def get_bom_with_component_setuptools_complete_resolves() -> Bom:
return Bom(components=[get_component_setuptools_complete_resolves()])


def get_bom_with_component_setuptools_with_vulnerability() -> Bom:
bom = Bom()
component = get_component_setuptools_simple()
Expand Down Expand Up @@ -375,6 +379,12 @@ def get_component_setuptools_complete(include_pedigree: bool = True) -> Componen
return component


def get_component_setuptools_complete_resolves() -> Component:
component = get_component_setuptools_complete(False)
component.pedigree = get_pedigree_2()
return component


def get_component_setuptools_simple(
bom_ref: Optional[str] = 'pkg:pypi/[email protected]?extension=tar.gz') -> Component:
return Component(
Expand Down Expand Up @@ -495,6 +505,14 @@ def get_pedigree_1() -> Pedigree:
)


def get_pedigree_2() -> Pedigree:
pedigree = get_pedigree_1()
pedigree.patches.add(
Patch(type_=PatchClassification.BACKPORT, resolves=[get_issue_1()])
)
return pedigree


def get_properties_1() -> List[Property]:
return [
Property(name='key1', value='val1'),
Expand Down
268 changes: 268 additions & 0 deletions tests/fixtures/xml/1.4/bom_setuptools_complete_resolves.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.4" version="1" serialNumber="urn:uuid:f9b53ef1-ce03-4a66-9594-f6efe0d26d15">
<metadata>
<timestamp>2022-10-20T15:55:25.045777+00:00</timestamp>
<tools>
<tool>
<vendor>CycloneDX</vendor>
<name>cyclonedx-python-lib</name>
<version>3.1.0</version>
<externalReferences>
<reference type="build-system">
<url>https://github.com/CycloneDX/cyclonedx-python-lib/actions</url>
</reference>
<reference type="distribution">
<url>https://pypi.org/project/cyclonedx-python-lib/</url>
</reference>
<reference type="documentation">
<url>https://cyclonedx.github.io/cyclonedx-python-lib/</url>
</reference>
<reference type="issue-tracker">
<url>https://github.com/CycloneDX/cyclonedx-python-lib/issues</url>
</reference>
<reference type="license">
<url>https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/LICENSE</url>
</reference>
<reference type="release-notes">
<url>https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CHANGELOG.md</url>
</reference>
<reference type="vcs">
<url>https://github.com/CycloneDX/cyclonedx-python-lib</url>
</reference>
<reference type="website">
<url>https://cyclonedx.org</url>
</reference>
</externalReferences>
</tool>
</tools>
</metadata>
<components>
<component type="library" bom-ref="cd3e9c95-9d41-49e7-9924-8cf0465ae789">
<supplier>
<name>CycloneDX</name>
<url>https://cyclonedx.org</url>
<contact>
<name>A N Other</name>
<email>[email protected]</email>
<phone>+44 (0)1234 567890</phone>
</contact>
<contact>
<name>Paul Horton</name>
<email>[email protected]</email>
</contact>
</supplier>
<author>Test Author</author>
<publisher>CycloneDX</publisher>
<name>setuptools</name>
<version>50.3.2</version>
<description>This component is awesome</description>
<scope>required</scope>
<licenses>
<expression>MIT License</expression>
</licenses>
<copyright>Apache 2.0 baby!</copyright>
<cpe>cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*</cpe>
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
<swid tagId="swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1" name="Test Application" version="3.4.5">
<text content-type="text/xml" encoding="base64">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==</text>
</swid>
<pedigree>
<ancestors>
<component type="library" bom-ref="ccc8d7ee-4b9c-4750-aee0-a72585152291">
<author>Test Author</author>
<name>setuptools</name>
<version>50.3.2</version>
<licenses>
<expression>MIT License</expression>
</licenses>
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
</component>
<component type="library" bom-ref="8a3893b3-9923-4adb-a1d3-47456636ba0a">
<author>Test Author</author>
<name>setuptools</name>
<licenses>
<expression>MIT License</expression>
</licenses>
<purl>pkg:pypi/setuptools?extension=tar.gz</purl>
</component>
</ancestors>
<descendants>
<component type="library" bom-ref="28b2d8ce-def0-446f-a221-58dee0b44acc">
<author>Test Author</author>
<name>setuptools</name>
<licenses>
<expression>MIT License</expression>
</licenses>
<purl>pkg:pypi/setuptools?extension=tar.gz</purl>
</component>
<component type="library" bom-ref="555ca729-93c6-48f3-956e-bdaa4a2f0bfa">
<name>toml</name>
<version>0.10.2</version>
<hashes>
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
</hashes>
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
<externalReferences>
<reference type="distribution">
<url>https://cyclonedx.org</url>
<comment>No comment</comment>
<hashes>
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
</hashes>
</reference>
</externalReferences>
</component>
</descendants>
<variants>
<component type="library" bom-ref="ded1d73e-1fca-4302-b520-f1bc53979958">
<author>Test Author</author>
<name>setuptools</name>
<version>50.3.2</version>
<licenses>
<expression>MIT License</expression>
</licenses>
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
</component>
<component type="library" bom-ref="e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66">
<name>toml</name>
<version>0.10.2</version>
<hashes>
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
</hashes>
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
<externalReferences>
<reference type="distribution">
<url>https://cyclonedx.org</url>
<comment>No comment</comment>
<hashes>
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
</hashes>
</reference>
</externalReferences>
</component>
</variants>
<commits>
<commit>
<uid>a-random-uid</uid>
<message>A commit message</message>
</commit>
</commits>
<patches>
<patch type="backport" />
<patch type="backport">
<resolves>
<issue type="security">
<id>CVE-2021-44228</id>
<name>Apache Log3Shell</name>
<description>Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...</description>
<source>
<name>NVD</name>
<url>https://nvd.nist.gov/vuln/detail/CVE-2021-44228</url>
</source>
<references>
<url>https://central.sonatype.org/news/20211213_log4shell_help</url>
<url>https://logging.apache.org/log4j/2.x/security.html</url>
</references>
</issue>
</resolves>
</patch>
</patches>
<notes>Some notes here please</notes>
</pedigree>
<externalReferences>
<reference type="distribution">
<url>https://cyclonedx.org</url>
<comment>No comment</comment>
<hashes>
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
</hashes>
</reference>
</externalReferences>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
<components>
<component type="library" bom-ref="pkg:pypi/[email protected]?extension=tar.gz">
<author>Test Author</author>
<name>setuptools</name>
<version>50.3.2</version>
<licenses>
<expression>MIT License</expression>
</licenses>
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
</component>
<component type="library" bom-ref="pkg:pypi/[email protected]?extension=tar.gz">
<name>toml</name>
<version>0.10.2</version>
<hashes>
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
</hashes>
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
<externalReferences>
<reference type="distribution">
<url>https://cyclonedx.org</url>
<comment>No comment</comment>
<hashes>
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
</hashes>
</reference>
</externalReferences>
</component>
</components>
<evidence>
<copyright>
<text>Commercial</text>
<text>Commercial 2</text>
</copyright>
</evidence>
<releaseNotes>
<type>major</type>
<title>Release Notes Title</title>
<featuredImage>https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png</featuredImage>
<socialImage>https://cyclonedx.org/cyclonedx-icon.png</socialImage>
<description>This release is a test release</description>
<timestamp>2021-12-31T10:00:00+00:00</timestamp>
<aliases>
<alias>First Test Release</alias>
</aliases>
<tags>
<tag>alpha</tag>
<tag>test</tag>
</tags>
<resolves>
<issue type="security">
<id>CVE-2021-44228</id>
<name>Apache Log3Shell</name>
<description>Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...</description>
<source>
<name>NVD</name>
<url>https://nvd.nist.gov/vuln/detail/CVE-2021-44228</url>
</source>
<references>
<url>https://central.sonatype.org/news/20211213_log4shell_help</url>
<url>https://logging.apache.org/log4j/2.x/security.html</url>
</references>
</issue>
</resolves>
<notes>
<note>
<locale>en-GB</locale>
<text content-type="text/plain; charset=UTF-8" encoding="base64">U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==</text>
</note>
<note>
<locale>en-US</locale>
<text content-type="text/plain; charset=UTF-8" encoding="base64">U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==</text>
</note>
</notes>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</releaseNotes>
</component>
</components>
<dependencies>
<dependency ref="cd3e9c95-9d41-49e7-9924-8cf0465ae789" />
</dependencies>
</bom>
Loading