Skip to content

Comments

fix(linter): harden traverseSchema (cycle-safe traversal, unambiguous paths)#833

Open
Mehrn0ush wants to merge 1 commit intoCycloneDX:2.0-dev-threatmodelingfrom
Mehrn0ush:fix/linter-harden-traverseschema-path-and-cycle-detection
Open

fix(linter): harden traverseSchema (cycle-safe traversal, unambiguous paths)#833
Mehrn0ush wants to merge 1 commit intoCycloneDX:2.0-dev-threatmodelingfrom
Mehrn0ush:fix/linter-harden-traverseschema-path-and-cycle-detection

Conversation

@Mehrn0ush
Copy link
Contributor

What

Hardens traverseSchema in tools/src/main/js/linter/index.js:

  • Stack-based cycle detection (WeakSet of nodes on the current recursion path) to prevent infinite recursion on circular in-memory schema graphs.
  • Unambiguous path emission via safePathJoin:
    • dot notation for simple identifiers
    • bracket notation for non-identifier keys (e.g. $["a.b"])
  • Optional depth guard (maxDepth, default Infinity) with an onDepthLimit hook.
  • Optional onCycle / onDangerousKey callbacks and DANGEROUS_PATH_KEYS export (defense-in-depth for any future path consumers).

Why

  • Prevents potential linter crashes (Maximum call stack size exceeded) when schemas are circular in-memory (programmatic construction, loader back-references, alias graphs).
  • Avoids ambiguous dot-path diagnostics when schema keys contain . or other non-identifier characters.

Compatibility / Behavior

  • Existing call sites in this repo are unchanged (all current checks call traverseSchema(schema, visitor)); additional parameters are optional.
  • Default behavior preserved: maxDepth defaults to Infinity (no truncation unless explicitly configured).
  • Cycle detection is stack-based and only skips true cycles (re-entry on the current recursion stack).
  • Path formatting changes only for keys that are not simple identifiers.

Security notes

  • Object.entries returns only own enumerable properties; traverseSchema does not traverse inherited properties and does not mutate objects.
  • In this repo, issue.path is used for reporting/CLI output only; no path-based setters are used. DANGEROUS_PATH_KEYS / onDangerousKey are provided as defense-in-depth for any future consumers.

Testing

  • cd tools/src/test/js && npm install && npm test
  • node --check tools/src/main/js/linter/index.js
  • node tools/src/main/js/linter/cli.js -i enum-value-formatting schema/2.0/cyclonedx-2.0.schema.json

Closes #832

… paths)

Signed-off-by: Mehrn0ush <mehrnoush.vaseghi@gmail.com>
@Mehrn0ush Mehrn0ush requested a review from a team as a code owner February 21, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant