Skip to content

Commit

Permalink
Merge pull request #574 from CycloneDX/issue_571
Browse files Browse the repository at this point in the history
  • Loading branch information
nscuro authored Dec 21, 2024
2 parents 66fcb64 + 51dc9d2 commit 26bd89a
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.cyclonedx.model.metadata;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

Expand All @@ -21,6 +22,9 @@ public class ToolInformation
private List<Service> services;

public List<Component> getComponents() {
if(components==null) {
components = new ArrayList<>();
}
return components;
}

Expand All @@ -29,6 +33,9 @@ public void setComponents(final List<Component> components) {
}

public List<Service> getServices() {
if(services==null) {
services = new ArrayList<>();
}
return services;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public void setReferences(final List<Reference> references) {
this.references = references;
}

private void addReference(Reference reference) {
public void addReference(Reference reference) {
if (references == null) {
references = new ArrayList<>();
}
Expand Down Expand Up @@ -225,6 +225,13 @@ public void setAdvisories(final List<Advisory> advisories) {
this.advisories = advisories;
}

public void addAdvisory(Advisory advisory) {
if (advisories == null) {
advisories = new ArrayList<>();
}
advisories.add(advisory);
}

public Date getCreated() {
return created;
}
Expand Down Expand Up @@ -824,6 +831,13 @@ public void setResponses(final List<Response> responses) {
this.responses = responses;
}

public void addResponse(Response response) {
if (this.responses == null) {
this.responses = new ArrayList<>();
}
this.responses.add(response);
}

public String getDetail() {
return detail;
}
Expand Down Expand Up @@ -896,6 +910,13 @@ public void setVersions(final List<Version> versions) {
this.versions = versions;
}

public void addVersion(Version version) {
if (versions == null) {
versions = new ArrayList<>();
}
versions.add(version);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down Expand Up @@ -992,6 +1013,13 @@ public void setIndividuals(final List<OrganizationalContact> individuals) {
this.individuals = individuals;
}

public void addIndividual(OrganizationalContact individual) {
if (individuals == null) {
individuals = new ArrayList<>();
}
individuals.add(individual);
}

public List<OrganizationalEntity> getOrganizations() {
return organizations;
}
Expand All @@ -1000,6 +1028,13 @@ public void setOrganizations(final List<OrganizationalEntity> organizations) {
this.organizations = organizations;
}

public void addOrganization(OrganizationalEntity organization) {
if (this.organizations == null) {
this.organizations = new ArrayList<>();
}
this.organizations.add(organization);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,9 @@ public Vulnerability.Affect deserialize(JsonParser parser, DeserializationContex
if (versionNode.isArray()) {
List<Vulnerability.Version> versions = mapper.convertValue(versionNode, new TypeReference<List<Vulnerability.Version>>() {});
affect.setVersions(versions);
} else {
affect.setVersions(Collections.singletonList(
mapper.convertValue(versionNode, Vulnerability.Version.class)
));
}
else {
affect.addVersion(mapper.convertValue(versionNode, Vulnerability.Version.class));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.cyclonedx.model.metadata.ToolInformation;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

public class ToolInformationDeserializer
Expand Down Expand Up @@ -71,7 +70,7 @@ else if (componentsNode.isObject() && componentsNode.has("component")) {
toolInformation.setComponents(components);
} else if (componentNode.isObject()) {
Component component = mapper.convertValue(componentNode, Component.class);
toolInformation.setComponents(Collections.singletonList(component));
toolInformation.getComponents().add(component);
}
}
}
Expand All @@ -84,15 +83,15 @@ private void parseServices(JsonNode servicesNode, ToolInformation toolInformatio
List<Service> services = mapper.convertValue(servicesNode, new TypeReference<List<Service>>() {});
toolInformation.setServices(services);
}
// Case XML-like input where "services" contains "component"
// Case XML-like input where "services" contains "service"
else if (servicesNode.isObject() && servicesNode.has("service")) {
JsonNode serviceNode = servicesNode.get("service");
if (serviceNode.isArray()) {
List<Service> services = mapper.convertValue(servicesNode, new TypeReference<List<Service>>() {});
toolInformation.setServices(services);
} else if (serviceNode.isObject()) {
Service service = mapper.convertValue(servicesNode, Service.class);
toolInformation.setServices(Collections.singletonList(service));
toolInformation.getServices().add(service);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.fasterxml.jackson.core.JsonParser;
Expand Down Expand Up @@ -108,8 +107,7 @@ private Vulnerability parseVulnerability(JsonNode node, JsonParser jsonParser, D
new TypeReference<List<Vulnerability.Reference>>() {});
vulnerability.setReferences(references);
} else {
vulnerability.setReferences(Collections.singletonList(
mapper.convertValue(referenceNode, Vulnerability.Reference.class)));
vulnerability.addReference(mapper.convertValue(referenceNode, Vulnerability.Reference.class));
}
}
}
Expand All @@ -126,9 +124,9 @@ private Vulnerability parseVulnerability(JsonNode node, JsonParser jsonParser, D
List<Vulnerability.Rating> ratings = mapper.convertValue(ratingNode, new TypeReference<List<Vulnerability.Rating>>() {
});
vulnerability.setRatings(ratings);
} else {
vulnerability.setRatings(Collections.singletonList(
mapper.convertValue(ratingNode, Vulnerability.Rating.class)));
}
else {
vulnerability.addRating(mapper.convertValue(ratingNode, Vulnerability.Rating.class));
}
}
}
Expand All @@ -145,7 +143,7 @@ private Vulnerability parseVulnerability(JsonNode node, JsonParser jsonParser, D
});
vulnerability.setCwes(codes);
} else {
vulnerability.setCwes(Collections.singletonList(cweNode.asInt()));
vulnerability.addCwe(cweNode.asInt());
}
}
}
Expand All @@ -163,8 +161,7 @@ private Vulnerability parseVulnerability(JsonNode node, JsonParser jsonParser, D
new TypeReference<List<Vulnerability.Advisory>>() {});
vulnerability.setAdvisories(advisories);
} else {
vulnerability.setAdvisories(Collections.singletonList(
mapper.convertValue(advisoryNode, Vulnerability.Advisory.class)));
vulnerability.addAdvisory(mapper.convertValue(advisoryNode, Vulnerability.Advisory.class));
}
}
}
Expand Down Expand Up @@ -251,8 +248,9 @@ private void parseAnalysis(JsonNode analysisNode, Vulnerability vulnerability, O
analysis.setResponses(responses);
}
else if (responseNode.isTextual()) {
Vulnerability.Analysis.Response response = Vulnerability.Analysis.Response.fromString(responseNode.asText());
analysis.setResponses(Collections.singletonList(response));
Vulnerability.Analysis.Response response =
Vulnerability.Analysis.Response.fromString(responseNode.asText());
analysis.addResponse(response);
}
}
}
Expand All @@ -279,7 +277,7 @@ private void parseOrganizations(JsonNode organizationsNode, Vulnerability.Credit
credits.setOrganizations(organizations);
} else if (organizationsNode.isObject()) {
OrganizationalEntity organization = mapper.convertValue(organizationsNode.get("organization"), OrganizationalEntity.class);
credits.setOrganizations(Collections.singletonList(organization));
credits.addOrganization(organization);
}
}
}
Expand All @@ -291,7 +289,7 @@ private void parseIndividuals(JsonNode individualsNode, Vulnerability.Credits cr
credits.setIndividuals(individuals);
} else if (individualsNode.isObject()) {
OrganizationalContact individual = mapper.convertValue(individualsNode.get("individual"), OrganizationalContact.class);
credits.setIndividuals(Collections.singletonList(individual));
credits.addIndividual(individual);
}
}
}
Expand Down
27 changes: 27 additions & 0 deletions src/test/java/org/cyclonedx/BomJsonGeneratorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,24 @@
package org.cyclonedx;

import com.fasterxml.jackson.databind.JsonNode;

import java.io.FileReader;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;
import org.cyclonedx.exception.GeneratorException;
import org.cyclonedx.generators.BomGeneratorFactory;
import org.cyclonedx.generators.json.BomJsonGenerator;
import org.cyclonedx.generators.xml.BomXmlGenerator;
import org.cyclonedx.model.Bom;
import org.cyclonedx.model.Component;
import org.cyclonedx.model.Component.Type;
import org.cyclonedx.model.License;
import org.cyclonedx.model.LicenseChoice;
import org.cyclonedx.model.Metadata;
import org.cyclonedx.model.OrganizationalContact;
import org.cyclonedx.model.Service;
import org.cyclonedx.model.license.Expression;
import org.cyclonedx.model.metadata.ToolInformation;
import org.cyclonedx.parsers.JsonParser;
import org.cyclonedx.parsers.XmlParser;
import org.junit.jupiter.api.AfterEach;
Expand All @@ -46,6 +52,10 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;
import java.util.Objects;

Expand Down Expand Up @@ -550,6 +560,23 @@ public void testIssue562() throws Exception {
Version version = Version.VERSION_16;
Bom bom = createCommonJsonBom("/regression/issue562.json");

BomJsonGenerator generator = BomGeneratorFactory.createJson(version, bom);
File loadedFile = writeToFile(generator.toJsonString());

JsonParser parser = new JsonParser();
assertTrue(parser.isValid(loadedFile, version));
}

@Test
public void testIssue571() throws Exception {
Version version = Version.VERSION_16;
Bom bom = createCommonJsonBom("/regression/issue571.json");

Component component = new Component();
component.setName("test");
component.setVersion("v2");
component.setType(Type.APPLICATION);
bom.getMetadata().getToolChoice().getComponents().add(component);

BomJsonGenerator generator = BomGeneratorFactory.createJson(version, bom);
File loadedFile = writeToFile(generator.toJsonString());
Expand Down
19 changes: 19 additions & 0 deletions src/test/java/org/cyclonedx/BomXmlGeneratorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.cyclonedx.model.Attribute;
import org.cyclonedx.model.Bom;
import org.cyclonedx.model.Component;
import org.cyclonedx.model.Component.Type;
import org.cyclonedx.model.ExtensibleType;
import org.cyclonedx.model.ExternalReference;
import org.cyclonedx.model.License;
Expand Down Expand Up @@ -730,6 +731,24 @@ public void testIssue562() throws Exception {
assertTrue(parser.isValid(loadedFile, version));
}

@Test
public void testIssue571() throws Exception {
Version version = Version.VERSION_16;
Bom bom = createCommonBomXml("/regression/issue571.xml");

Component component = new Component();
component.setName("test");
component.setVersion("v2");
component.setType(Type.APPLICATION);
bom.getMetadata().getToolChoice().getComponents().add(component);

BomJsonGenerator generator = BomGeneratorFactory.createJson(version, bom);
File loadedFile = writeToFile(generator.toJsonString());

JsonParser parser = new JsonParser();
assertTrue(parser.isValid(loadedFile, version));
}

@Test
public void testIssue492() throws Exception {
Version version = Version.VERSION_15;
Expand Down
21 changes: 21 additions & 0 deletions src/test/resources/regression/issue571.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"bomFormat":"CycloneDX",
"specVersion":"1.6",
"serialNumber":"urn:uuid:0c81ff2e-d64e-4897-bfa4-2f0f7d8ab767",
"version" : 1,
"metadata" : {
"timestamp":"2024-12-09T21:56:45Z",
"tools" : {
"components" : [ {
"type":"application",
"name":"TOOL 1",
"version":"v1"
} ]
},
"authors" : [ {
"name":"Author 1"
}, {
"name":"Author 2"
} ]
}
}
22 changes: 22 additions & 0 deletions src/test/resources/regression/issue571.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.6" serialNumber="urn:uuid:0c81ff2e-d64e-4897-bfa4-2f0f7d8ab767" version="1">
<metadata>
<timestamp>2024-12-09T21:56:45Z</timestamp>
<tools>
<components>
<component type="application">
<name>TOOL 1</name>
<version>v1</version>
</component>
</components>
</tools>
<authors>
<author>
<name>Author 1</name>
</author>
<author>
<name>Author 2</name>
</author>
</authors>
</metadata>
</bom>

0 comments on commit 26bd89a

Please sign in to comment.