Skip to content
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

Correcting bomlink generation for XML and JSON. Added unit tests. #238

Merged
merged 2 commits into from
Nov 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Maven Usage
<dependency>
<groupId>org.cyclonedx</groupId>
<artifactId>cyclonedx-core-java</artifactId>
<version>7.2.1</version>
<version>7.2.2</version>
</dependency>
```

Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/cyclonedx/util/BomUtils.java
Original file line number Diff line number Diff line change
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;
}
}
}
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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>