Skip to content

Commit

Permalink
Handle empty component and service names
Browse files Browse the repository at this point in the history
`component.name` and `service.name` are required as per CycloneDX specification, but the schema doesn't sufficiently enforce this requirement (CycloneDX/specification#461).

Because DT trims names from the BOM during model conversion, empty or blank names end up becoming `null`. Since the respective database columns have a `NOT NULL` constraint on them, inserting or updating such components will always fail.

Usually we would not want to try to "repair" data, but the name being empty appears to be so common that there's no other sensible way for us to deal with it.

With this change, empty names will end up being saved as `-` instead, to signal the absence of a proper value.

Fixes DependencyTrack#2821

Signed-off-by: nscuro <[email protected]>
  • Loading branch information
nscuro committed Sep 13, 2024
1 parent a15803f commit 146b9e1
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import java.util.function.Consumer;
import java.util.function.Function;

import static java.util.Objects.requireNonNullElse;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trim;
import static org.apache.commons.lang3.StringUtils.trimToNull;
Expand Down Expand Up @@ -167,7 +168,7 @@ public static Component convertComponent(final org.cyclonedx.model.Component cdx
component.setSupplier(convert(cdxComponent.getSupplier()));
component.setClassifier(convertClassifier(cdxComponent.getType()).orElse(Classifier.LIBRARY));
component.setGroup(trimToNull(cdxComponent.getGroup()));
component.setName(trimToNull(cdxComponent.getName()));
component.setName(requireNonNullElse(trimToNull(cdxComponent.getName()), "-"));
component.setVersion(trimToNull(cdxComponent.getVersion()));
component.setDescription(trimToNull(cdxComponent.getDescription()));
component.setCopyright(trimToNull(cdxComponent.getCopyright()));
Expand Down Expand Up @@ -325,7 +326,7 @@ public static ServiceComponent convertService(final org.cyclonedx.model.Service
final var service = new ServiceComponent();
service.setBomRef(useOrGenerateRandomBomRef(cdxService.getBomRef()));
service.setGroup(trimToNull(cdxService.getGroup()));
service.setName(trimToNull(cdxService.getName()));
service.setName(requireNonNullElse(trimToNull(cdxService.getName()), "-"));
service.setVersion(trimToNull(cdxService.getVersion()));
service.setDescription(trimToNull(cdxService.getDescription()));
service.setAuthenticated(cdxService.getAuthenticated());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,45 @@ public void informWithLicenseResolutionByIdOrNameTest() {
});
}

@Test
public void informWithEmptyComponentAndServiceNameTest() {
final var project = new Project();
project.setName("acme-license-app");
qm.persist(project);

final byte[] bomBytes = """
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b80",
"version": 1,
"components": [
{
"type": "library",
"name": ""
}
],
"services": [
{
"name": ""
}
]
}
""".getBytes(StandardCharsets.UTF_8);

final var bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), bomBytes);
new BomUploadProcessingTask().inform(bomUploadEvent);
awaitBomProcessedNotification(bomUploadEvent);

qm.getPersistenceManager().evictAll();
assertThat(qm.getAllComponents(project)).satisfiesExactly(component -> {
assertThat(component.getName()).isEqualTo("-");
});
assertThat(qm.getAllServiceComponents(project)).satisfiesExactly(service -> {
assertThat(service.getName()).isEqualTo("-");
});
}

@Test // https://github.com/DependencyTrack/dependency-track/issues/1905
public void informIssue1905Test() throws Exception {
final var project = qm.createProject("Acme Example", null, "1.0", null, null, null, true, false);
Expand Down Expand Up @@ -1331,7 +1370,6 @@ public void informIssue3981Test() {

@Test
public void informIssue3936Test() throws Exception{

final Project project = qm.createProject("Acme Example", null, "1.0", null, null, null, true, false);
List<String> boms = new ArrayList<>(Arrays.asList("/unit/bom-issue3936-authors.json", "/unit/bom-issue3936-author.json", "/unit/bom-issue3936-both.json"));
for(String bom : boms){
Expand Down

0 comments on commit 146b9e1

Please sign in to comment.