Skip to content

Commit

Permalink
Correcting bomlink generation for XML and JSON. Added unit tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
stevespringett committed Nov 19, 2022
1 parent 248c886 commit a893ba6
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/main/java/org/cyclonedx/util/BomUtils.java
Expand Up @@ -27,6 +27,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
Expand Down Expand Up @@ -95,6 +96,7 @@ private static Hash.Algorithm toAlgorithm(MessageDigest digest) {
throw new IllegalArgumentException("Unable to find algorithm matching '"+digest.getAlgorithm()+"'. Known algorithms: "+ Arrays.stream(Hash.Algorithm.values()).map(Hash.Algorithm::getSpec).sorted().collect(Collectors.joining()));
}

@Deprecated
public static boolean validateUrlString(String url) {
try {
new URL(url).toURI();
Expand All @@ -103,4 +105,13 @@ public static boolean validateUrlString(String url) {
return false;
}
}

public static boolean validateUriString(String uri) {
try {
new URI(uri);
return true;
} catch (URISyntaxException e) {
return false;
}
}
}
Expand Up @@ -46,7 +46,7 @@ public ExternalReferenceSerializer(final Class<ExternalReference> t) {
public void serialize(
final ExternalReference extRef, final JsonGenerator gen, final SerializerProvider provider) throws IOException
{
final BiPredicate<Type, String> validateExternalReference = (type, url) -> (type != null && url != null && BomUtils.validateUrlString(url));
final BiPredicate<Type, String> validateExternalReference = (type, url) -> (type != null && url != null && BomUtils.validateUriString(url));
if (gen instanceof ToXmlGenerator) {
final ToXmlGenerator toXmlGenerator = (ToXmlGenerator) gen;
final XMLStreamWriter staxWriter = toXmlGenerator.getStaxWriter();
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/org/cyclonedx/BomJsonGeneratorTest.java
Expand Up @@ -164,6 +164,19 @@ public void schema14MultipleDependenciesJsonTest() throws Exception {
assertTrue(jsonParser.isValid(file, CycloneDxSchema.Version.VERSION_14));
}

@Test
public void schema14JBomLinkGenerationTest() throws Exception {
Bom bom = createCommonBom("/bom-1.4-bomlink.xml");
BomJsonGenerator generator = BomGeneratorFactory.createJson(Version.VERSION_14, bom);
File file = writeToFile(generator.toJsonString());
JsonParser parser = new JsonParser();
assertTrue(parser.isValid(file, CycloneDxSchema.Version.VERSION_14));
Bom bom2 = parser.parse(file);
assertNotNull(bom2.getComponents().get(0).getExternalReferences());
assertEquals("bom", bom2.getComponents().get(0).getExternalReferences().get(0).getType().getTypeName());
assertEquals("urn:cdx:f08a6ccd-4dce-4759-bd84-c626675d60a7/1", bom2.getComponents().get(0).getExternalReferences().get(0).getUrl());
}

private File writeToFile(String jsonString) throws Exception {
try (FileWriter writer = new FileWriter(tempFile.getAbsolutePath())) {
writer.write(jsonString);
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/org/cyclonedx/BomXmlGeneratorTest.java
Expand Up @@ -308,6 +308,19 @@ public void schema13EmptyComponentsXmlTest() throws Exception {
assertTrue(parser.isValid(file, CycloneDxSchema.Version.VERSION_13));
}

@Test
public void schema14JBomLinkGenerationTest() throws Exception {
Bom bom = createCommonBom("/bom-1.4-bomlink.xml");
BomXmlGenerator generator = BomGeneratorFactory.createXml(Version.VERSION_14, bom);
File file = writeToFile(generator.toXmlString());
XmlParser parser = new XmlParser();
assertTrue(parser.isValid(file, CycloneDxSchema.Version.VERSION_14));
Bom bom2 = parser.parse(file);
assertNotNull(bom2.getComponents().get(0).getExternalReferences());
assertEquals("bom", bom2.getComponents().get(0).getExternalReferences().get(0).getType().getTypeName());
assertEquals("urn:cdx:f08a6ccd-4dce-4759-bd84-c626675d60a7/1", bom2.getComponents().get(0).getExternalReferences().get(0).getUrl());
}

private File writeToFile(String xmlString) throws Exception {
try (FileWriter writer = new FileWriter(tempFile.getAbsolutePath())) {
writer.write(xmlString);
Expand Down
11 changes: 11 additions & 0 deletions src/test/java/org/cyclonedx/parsers/JsonParserTest.java
Expand Up @@ -312,6 +312,17 @@ public void testParsedObjects13Bom() throws Exception {
assertEquals("pkg:npm/acme/common@2.2.0", d22.getRef());
}

@Test
public void testValidBomLink() throws Exception {
final File file = new File(this.getClass().getResource("/bom-1.4-bomlink.json").getFile());
final JsonParser parser = new JsonParser();
Bom bom = parser.parse(file);
assertTrue(parser.isValid(file, CycloneDxSchema.Version.VERSION_14));
ExternalReference ref = bom.getComponents().get(0).getExternalReferences().get(0);
assertEquals("bom", ref.getType().getTypeName());
assertEquals("urn:cdx:f08a6ccd-4dce-4759-bd84-c626675d60a7/1", ref.getUrl());
}

@Test
public void testParsedObjects14Bom() throws Exception {
final byte[] bomBytes = IOUtils.toByteArray(this.getClass().getResourceAsStream("/bom-1.4.json"));
Expand Down
11 changes: 11 additions & 0 deletions src/test/java/org/cyclonedx/parsers/XmlParserTest.java
Expand Up @@ -92,6 +92,17 @@ public void testValid12Bom() throws Exception {
assertTrue(valid);
}

@Test
public void testValidBomLink() throws Exception {
final File file = new File(this.getClass().getResource("/bom-1.4-bomlink.xml").getFile());
final XmlParser parser = new XmlParser();
Bom bom = parser.parse(file);
assertTrue(parser.isValid(file, CycloneDxSchema.Version.VERSION_14));
ExternalReference ref = bom.getComponents().get(0).getExternalReferences().get(0);
assertEquals("bom", ref.getType().getTypeName());
assertEquals("urn:cdx:f08a6ccd-4dce-4759-bd84-c626675d60a7/1", ref.getUrl());
}

@Test
public void testValid12BomWithPedigree() throws Exception {
final File file = new File(this.getClass().getResource("/bom-1.2-pedigree.xml").getFile());
Expand Down
28 changes: 28 additions & 0 deletions src/test/resources/bom-1.4-bomlink.json
@@ -0,0 +1,28 @@
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"components": [
{
"type": "library",
"publisher": "Acme Inc",
"group": "org.example",
"name": "mylibrary",
"version": "1.0.0",
"externalReferences": [
{
"type": "bom",
"url": "urn:cdx:f08a6ccd-4dce-4759-bd84-c626675d60a7/1",
"comment": "An external SBOM that describes what this component includes",
"hashes": [
{
"alg": "SHA-256",
"content": "708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313"
}
]
}
]
}
]
}
19 changes: 19 additions & 0 deletions src/test/resources/bom-1.4-bomlink.xml
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<bom serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1" xmlns="http://cyclonedx.org/schema/bom/1.4">
<components>
<component type="library">
<group>org.example</group>
<name>mylibrary</name>
<version>1.0.0</version>
<externalReferences>
<reference type="bom">
<url>urn:cdx:f08a6ccd-4dce-4759-bd84-c626675d60a7/1</url>
<comment>An external SBOM that describes what this component includes</comment>
<hashes>
<hash alg="SHA-256">f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b</hash>
</hashes>
</reference>
</externalReferences>
</component>
</components>
</bom>

0 comments on commit a893ba6

Please sign in to comment.