Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Bug: Dependency Trees overflows the call stack on cyclic SBOM dependency graphs

未关闭
#5,746 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@faystmax 已经在做这个了。

开始于 2026年10月3日。

  • #5748 来自 @faystmax —— 未关闭

评估

难度
4/5
预计耗时
3-5 天
新手友好度
68/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
领域
frontend

调研方向

Start with spring-boot-admin-server-ui/src/main/frontend/views/instances/sbomdependencytrees/sbomUtils.ts, especially getChildren() and retrieveChildren(), then inspect tree.spec.ts for the existing normalization and rendering tests. Reproduce the minimal cyclic input and add coverage for cycles, self-references, acyclic chains, and shared dependencies. Done means finite cycle-marked output, preserved repeated shared nodes, and working filtering and rerendering without a stack overflow.

由索引模型根据 Issue 内容生成。

描述

Spring Boot Admin Server information

  • Version: 4.1.3
  • Spring Boot version: 4.1.1

Client information

  • Spring Boot versions: 3.5.10
  • SBOM format: CycloneDX JSON

Description

The SBOM Dependency Trees normalizer recursively expands dependency references without tracking ancestors. When the input graph contains a reachable cycle, expansion never terminates normally and throws RangeError: Maximum call stack size exceeded.

This was reproduced in isolation against the executable normalization logic from 4.1.3 and master inspected on 2026-10-03. A self-reference also reproduces the failure. A full SBA browser integration test was not run for this report.

Regardless of how a producer generated a cyclic graph, the viewer should handle it without exhausting the JavaScript call stack. Removing BOM/POM components from the input should not be necessary to prevent the viewer from failing.

Minimal input

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "version": 1,
  "metadata": {
    "component": { "type": "application", "bom-ref": "app", "name": "demo-app", "version": "1.0.0" }
  },
  "components": [
    { "type": "library", "bom-ref": "a", "name": "library-a", "version": "1.0.0" },
    { "type": "library", "bom-ref": "b", "name": "library-b", "version": "1.0.0" }
  ],
  "dependencies": [
    { "ref": "app", "dependsOn": ["a"] },
    { "ref": "a", "dependsOn": ["b"] },
    { "ref": "b", "dependsOn": ["a"] }
  ]
}

Reproduction and actual behavior

Pass this document's dependencies to normalizeData() in sbomUtils.ts. It throws Maximum call stack size exceeded while expanding app -> a -> b -> a -> ....

For UI reproduction, serve the document through the monitored application's SBOM endpoint, or mock instance.fetchSbom() in tree.spec.ts, and open Dependency Trees. Normalization fails before a finite tree can be passed to the D3 renderer.

Expected behavior

Render a finite representation of the reachable graph. For example, show a terminal node/reference marked as a cycle when a dependency points back to an ancestor:

app
└── a
    └── b
        └── a [cycle; not expanded again]

An explicit controlled diagnostic would also be preferable to a stack overflow, but retaining the rest of the graph would make the view more useful.

Cause and proposed fix

getChildren() and retrieveChildren() in 4.1.3 call each other without an ancestor/recursion-path guard.

  • Index dependency records by their exact ref.
  • Track references on the current traversal path, including the root.
  • If the next reference is already on that path, create a terminal cycle/reference node rather than expanding it again.
  • Use full references for identity; normalized labels can collide.
  • Do not use a global visited set to suppress all repeated nodes. A shared dependency in two independent branches is not a cycle and should remain visible under both parents.
  • Keep the resulting object structure acyclic for D3, and preserve the original SBOM graph.
  • Consider an explicit stack or controlled expansion limits for very deep graphs / large numbers of repeated paths; cycle detection alone does not bound all work.

Regression cases should include a two-node cycle, self-reference, an edge back to the application root, an ordinary acyclic chain, and a diamond (app -> a,b, a -> c, b -> c) where c is shown in both branches. Filtering and rerendering should still work with cycle markers.

Related reports

There is a separate root-selection defect where dependencies[0] is treated as the root. Correcting it can make previously hidden cycles reachable. [#5745]

#5157 fixes an alert displayed during SBOM loading; it does not add cycle detection to dependency traversal.

I would be happy to contribute a PR targeting master, covering both root selection and cycle-safe traversal if preferred.

主要语言
Java
星标
12.9k
派生
3.2k
平均合并
13 小时 56 分钟
30 天内合并 PR
84

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

codecentric/spring-boot-admin 的其他 Issue

查看 codecentric/spring-boot-admin 的全部 Issue

相似的 Issue

更多 Java Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。