Skip to content

Commit

Permalink
Fix: Detect and avoid infinite recursion during second upload of SBOM…
Browse files Browse the repository at this point in the history
… with nested duplicate

See DependencyTrack#1905 for details

Signed-off-by: syalioune <[email protected]>
  • Loading branch information
syalioune committed May 15, 2023
1 parent 752b0f7 commit 674e85c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.github.packageurl.PackageURL;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.cyclonedx.model.Bom;
import org.cyclonedx.model.Dependency;
import org.cyclonedx.model.Hash;
Expand Down Expand Up @@ -96,7 +97,8 @@ public static List<Component> convertComponents(final QueryManager qm, final Bom

@SuppressWarnings("deprecation")
public static Component convert(final QueryManager qm, final org.cyclonedx.model.Component cycloneDxComponent, final Project project) {
Component component = qm.matchSingleIdentity(project, new ComponentIdentity(cycloneDxComponent));
ComponentIdentity parentIdentity = new ComponentIdentity(cycloneDxComponent);
Component component = qm.matchSingleIdentity(project, parentIdentity);
if (component == null) {
component = new Component();
component.setProject(project);
Expand Down Expand Up @@ -187,7 +189,8 @@ public static Component convert(final QueryManager qm, final org.cyclonedx.model
final Collection<Component> components = new ArrayList<>();
for (int i = 0; i < cycloneDxComponent.getComponents().size(); i++) {
final org.cyclonedx.model.Component cycloneDxChildComponent = cycloneDxComponent.getComponents().get(i);
if (cycloneDxChildComponent != null) {
ComponentIdentity childIdentity = new ComponentIdentity(cycloneDxChildComponent);
if (cycloneDxChildComponent != null && !EqualsBuilder.reflectionEquals(parentIdentity, childIdentity)) {
components.add(convert(qm, cycloneDxChildComponent, project));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

Expand Down Expand Up @@ -209,4 +210,27 @@ public void informWithInvalidCycloneDxBomTest() throws Exception {
assertThat(project.getLastBomImport()).isNull();
}

@Test
public void informTestWithInvalidCycloneDxBomRecursiveDuplicateTest() throws Exception {
// Test case for issue #1905 : https://github.com/DependencyTrack/dependency-track/issues/1905
Project project = qm.createProject("Acme Example", null, "1.0", null, null, null, true, false);

final byte[] bomBytes = Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("bom-2.json").toURI()));

new BomUploadProcessingTask().inform(new BomUploadEvent(project.getUuid(), bomBytes));
assertConditionWithTimeout(() -> qm.getAllComponents(project).size() == 1, Duration.ofSeconds(5));
assertConditionWithTimeout(() -> NOTIFICATIONS.size() >= 3, Duration.ofSeconds(5));
List<Component> components = qm.getAllComponents(project);
final Component component = components.get(0);
assertThat(component.getName()).isEqualTo("Pillow");
assertThat(component.getVersion()).isEqualTo("9.3.0");
assertThat(component.getCpe()).isEqualTo("cpe:2.3:a:alex_clark_\\(pil_fork_author\\):python-Pillow:9.3.0:*:*:*:*:*:*:*");
assertThat(component.getPurl().canonicalize()).isEqualTo("pkg:pypi/[email protected]");
assertThat(NOTIFICATIONS).satisfiesExactly(
n -> assertThat(n.getGroup()).isEqualTo(NotificationGroup.PROJECT_CREATED.name()),
n -> assertThat(n.getGroup()).isEqualTo(NotificationGroup.BOM_CONSUMED.name()),
n -> assertThat(n.getGroup()).isEqualTo(NotificationGroup.BOM_PROCESSED.name())
);
}

}
35 changes: 35 additions & 0 deletions src/test/resources/bom-2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"version": 1,
"metadata": {
"timestamp": "2023-01-01T11:01:51Z",
"tools": [
{
"vendor": "changeme",
"name": "changeme",
"version": "0.62.3"
}
]
},
"components": [
{
"bom-ref": "pkg:pypi/[email protected]",
"type": "library",
"name": "Pillow",
"version": "9.3.0",
"cpe": "cpe:2.3:a:alex_clark_\\(pil_fork_author\\):python-Pillow:9.3.0:*:*:*:*:*:*:*",
"purl": "pkg:pypi/[email protected]",
"components": [
{
"bom-ref": "pkg:pypi/[email protected]?package-id=212c649613e17901",
"type": "library",
"name": "Pillow",
"version": "9.3.0",
"cpe": "cpe:2.3:a:alex_clark_\\(pil_fork_author\\):python-Pillow:9.3.0:*:*:*:*:*:*:*",
"purl": "pkg:pypi/[email protected]"
}
]
}
]
}

0 comments on commit 674e85c

Please sign in to comment.