diff --git a/cli/gitcommands.go b/cli/gitcommands.go index 6fb8b80c3..bf515b4e0 100644 --- a/cli/gitcommands.go +++ b/cli/gitcommands.go @@ -99,7 +99,6 @@ func GitAuditCmd(c *components.Context) error { gitAuditCmd.SetUploadCdxResults(uploadResults).SetRtResultRepository(c.GetStringFlagValue(flags.UploadRtRepoPath)) // Run the command with progress bar if needed, Reporting error if Xsc service is enabled err = reportErrorIfExists(xrayVersion, xscVersion, serverDetails, gitAuditCmd.GetProjectKey(), progressbar.ExecWithProgress(gitAuditCmd)) - log.Info("####### jf git audit Scan Finished #######") return err } diff --git a/cli/scancommands.go b/cli/scancommands.go index 62f476b48..cf565a609 100644 --- a/cli/scancommands.go +++ b/cli/scancommands.go @@ -481,7 +481,6 @@ func AuditCmd(c *components.Context) error { auditCmd.SetThreads(threads) // Reporting error if Xsc service is enabled err = reportErrorIfExists(xrayVersion, xscVersion, serverDetails, auditCmd.GetProjectKey(), progressbar.ExecWithProgress(auditCmd)) - log.Info("####### jf audit Scan Finished #######") return err } diff --git a/commands/audit/audit.go b/commands/audit/audit.go index 683c8cca3..96efc80e9 100644 --- a/commands/audit/audit.go +++ b/commands/audit/audit.go @@ -242,7 +242,7 @@ func (auditCmd *AuditCommand) Run() (err error) { return errors.Join(err, auditResults.GetErrors()) } } - + log.Info("####### jf audit Scan Finished #######") return OutputResultsAndCmdError(auditResults, auditCmd.getResultWriter(auditResults), auditCmd.Fail) } diff --git a/commands/git/audit/gitaudit.go b/commands/git/audit/gitaudit.go index 060a9e496..d5692ae37 100644 --- a/commands/git/audit/gitaudit.go +++ b/commands/git/audit/gitaudit.go @@ -62,6 +62,7 @@ func (gaCmd *GitAuditCommand) Run() (err error) { return errors.Join(err, auditResults.GetErrors()) } } + log.Info("####### jf git audit Scan Finished #######") return sourceAudit.OutputResultsAndCmdError(auditResults, gaCmd.getResultWriter(auditResults), gaCmd.failBuild) } diff --git a/utils/results/common.go b/utils/results/common.go index 6e049b3ca..5cd34e72d 100644 --- a/utils/results/common.go +++ b/utils/results/common.go @@ -33,6 +33,9 @@ const ( DirectDependencyPathLength = 2 nodeModules = "node_modules" + // MaxUniqueAppearances defines the maximum number of times a dependency can appear in a dependency tree. + MaxUniqueAppearances = 10 + // #LC-LC LocationIdTemplate = "%s#L%dC%d-L%dC%d" // Applicability properties for cdx @@ -1024,10 +1027,11 @@ func BomToFullTree(sbom *cyclonedx.BOM, convertToXrayCompId bool) (fullDependenc // No dependencies or components in the SBOM, return an empty slice return } + dependencyAppearances := map[string]int8{} for _, rootEntry := range cdxutils.GetRootDependenciesEntries(sbom, false) { // Create a new GraphNode with ref as the ID, when populating the tree we need to use the ref as the ID currentTree := &xrayUtils.GraphNode{Id: rootEntry.Ref} - populateDepsNodeDataFromBom(currentTree, sbom.Dependencies) + populateDepsNodeDataFromBom(currentTree, sbom.Dependencies, dependencyAppearances) fullDependencyTrees = append(fullDependencyTrees, currentTree) } // Translate refs to Purl/Xray IDs @@ -1037,9 +1041,13 @@ func BomToFullTree(sbom *cyclonedx.BOM, convertToXrayCompId bool) (fullDependenc return } -func populateDepsNodeDataFromBom(node *xrayUtils.GraphNode, dependencies *[]cyclonedx.Dependency) { - if node == nil || node.NodeHasLoop() { - // If the node is nil or has a loop, return +func populateDepsNodeDataFromBom(node *xrayUtils.GraphNode, dependencies *[]cyclonedx.Dependency, dependencyAppearances map[string]int8) { + if node == nil { + return + } + dependencyAppearances[node.Id]++ + if dependencyAppearances[node.Id] >= MaxUniqueAppearances || node.NodeHasLoop() { + // If the node has a loop or appeared too many times, stop the recursion return } for _, dep := range cdxutils.GetDirectDependencies(dependencies, node.Id) { @@ -1047,7 +1055,7 @@ func populateDepsNodeDataFromBom(node *xrayUtils.GraphNode, dependencies *[]cycl // Add the dependency to the current node node.Nodes = append(node.Nodes, depNode) // Recursively populate the node data - populateDepsNodeDataFromBom(depNode, dependencies) + populateDepsNodeDataFromBom(depNode, dependencies, dependencyAppearances) } }