Skip to content

Commit 0b35329

Browse files
committed
CR fixes: refactor diff.go, remove LogCollector wrapper, use helpers
- Rename filterExistingFindings to excludeExistingFindingsInTargets - Extract countJasFindings and extractAllJasResultKeys helpers - Move getSastFingerprint to sarifutils.GetSastDiffFingerprint - Use WrapTaskWithLoggerPropagation helper in audit.go - Remove LogCollector wrapper - use BufferedLogger directly from client-go
1 parent 1ca4a0a commit 0b35329

5 files changed

Lines changed: 92 additions & 123 deletions

File tree

commands/audit/audit.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,9 @@ func (auditCmd *AuditCommand) CommandName() string {
292292
// Returns an audit Results object containing all the scan results.
293293
// If the current server is entitled for JAS, the advanced security results will be included in the scan results.
294294
func RunAudit(auditParams *AuditParams) (cmdResults *results.SecurityCommandResults) {
295-
// Set up isolated logging if a log collector is provided
295+
// Set up isolated logging if a BufferedLogger is provided for parallel log capture
296296
if collector := auditParams.GetLogCollector(); collector != nil {
297-
log.SetLoggerForGoroutine(collector.Logger())
297+
log.SetLoggerForGoroutine(collector)
298298
defer log.ClearLoggerForGoroutine()
299299
}
300300
// Prepare the command for the scan.
@@ -628,16 +628,9 @@ func addJasScansToRunner(auditParallelRunner *utils.SecurityParallelRunner, audi
628628
return
629629
}
630630
auditParallelRunner.JasWg.Add(1)
631-
// Capture current logger (may be a BufferedLogger for isolated parallel logging).
632-
// Worker goroutines need this propagated so their logs are captured in the same buffer.
633-
currentLogger := log.GetLogger()
634631
jasTask := createJasScansTask(auditParallelRunner, scanResults, serverDetails, auditParams, jasScanner)
635-
wrappedJasTask := func(threadId int) error {
636-
// Propagate parent's logger to this worker goroutine for isolated log capture
637-
log.SetLoggerForGoroutine(currentLogger)
638-
defer log.ClearLoggerForGoroutine()
639-
return jasTask(threadId)
640-
}
632+
// Wrap task to propagate parent's logger for isolated parallel logging
633+
wrappedJasTask := utils.WrapTaskWithLoggerPropagation(jasTask)
641634
if _, jasErr := auditParallelRunner.Runner.AddTaskWithError(wrappedJasTask, func(taskErr error) {
642635
scanResults.AddGeneralError(fmt.Errorf("failed while adding JAS scan tasks: %s", taskErr.Error()), auditParams.AllowPartialResults())
643636
}); jasErr != nil {

commands/audit/auditbasicparams.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
66
"github.com/jfrog/jfrog-cli-security/utils"
77
ioUtils "github.com/jfrog/jfrog-client-go/utils/io"
8+
"github.com/jfrog/jfrog-client-go/utils/log"
89
xscservices "github.com/jfrog/jfrog-client-go/xsc/services"
910
)
1011

@@ -82,7 +83,7 @@ type AuditBasicParams struct {
8283
xscVersion string
8384
configProfile *xscservices.ConfigProfile
8485
solutionFilePath string
85-
logCollector *LogCollector
86+
logCollector *log.BufferedLogger
8687
useIncludedBuilds bool
8788
}
8889

@@ -345,12 +346,12 @@ func (abp *AuditBasicParams) SetSolutionFilePath(solutionFilePath string) *Audit
345346
return abp
346347
}
347348

348-
func (abp *AuditBasicParams) SetLogCollector(collector *LogCollector) *AuditBasicParams {
349+
func (abp *AuditBasicParams) SetLogCollector(collector *log.BufferedLogger) *AuditBasicParams {
349350
abp.logCollector = collector
350351
return abp
351352
}
352353

353-
func (abp *AuditBasicParams) GetLogCollector() *LogCollector {
354+
func (abp *AuditBasicParams) GetLogCollector() *log.BufferedLogger {
354355
return abp.logCollector
355356
}
356357

commands/audit/logcollector.go

Lines changed: 0 additions & 41 deletions
This file was deleted.

utils/formats/sarifutils/sarifutils.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,21 @@ func GetResultFingerprint(result *sarif.Result) string {
904904
return ""
905905
}
906906

907+
// SastDiffFingerprintKey is the fingerprint key used by Analyzer Manager for SAST diff matching.
908+
// This differs from jasutils.SastFingerprintKey ("significant_full_path") which is used for general SAST operations.
909+
const SastDiffFingerprintKey = "precise_sink_and_sink_function"
910+
911+
// GetSastDiffFingerprint extracts the SAST fingerprint used specifically for diff matching.
912+
// Uses "precise_sink_and_sink_function" key (generated by Analyzer Manager for diff purposes).
913+
func GetSastDiffFingerprint(result *sarif.Result) string {
914+
if result != nil && result.Fingerprints != nil {
915+
if value, ok := result.Fingerprints[SastDiffFingerprintKey]; ok {
916+
return value
917+
}
918+
}
919+
return ""
920+
}
921+
907922
func GetResultsByRuleId(ruleId string, runs ...*sarif.Run) (results []*sarif.Result) {
908923
for _, run := range runs {
909924
for _, result := range run.Results {

utils/results/diff.go

Lines changed: 69 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func CompareJasResults(targetResults, sourceResults *SecurityCommandResults) *Se
7575
}
7676
}
7777

78-
diffJasResults := filterExistingFindings(allTargetJasResults, sourceTarget.JasResults)
78+
diffJasResults := excludeExistingFindingsInTargets(sourceTarget.JasResults, allTargetJasResults...)
7979

8080
diffTarget := &TargetResults{
8181
ScanTarget: sourceTarget.ScanTarget,
@@ -88,49 +88,20 @@ func CompareJasResults(targetResults, sourceResults *SecurityCommandResults) *Se
8888
return diffResults
8989
}
9090

91-
// filterExistingFindings removes findings from source that already exist in target.
92-
func filterExistingFindings(allTargetJasResults []*JasScansResults, sourceJasResults *JasScansResults) *JasScansResults {
91+
// excludeExistingFindingsInTargets removes findings from source that already exist in any of the target results.
92+
// Returns a new JasScansResults containing only findings that are NEW in source (not present in targets).
93+
func excludeExistingFindingsInTargets(sourceJasResults *JasScansResults, targetJasResultsToExclude ...*JasScansResults) *JasScansResults {
9394
if sourceJasResults == nil {
9495
return nil
9596
}
9697

97-
if len(allTargetJasResults) == 0 {
98+
if len(targetJasResultsToExclude) == 0 {
9899
return sourceJasResults
99100
}
100101

101-
targetKeys := make(map[string]bool)
102+
targetKeys := extractAllJasResultKeys(targetJasResultsToExclude...)
102103

103-
for _, targetJasResults := range allTargetJasResults {
104-
if targetJasResults == nil {
105-
continue
106-
}
107-
108-
for _, targetRun := range targetJasResults.GetVulnerabilitiesResults(jasutils.Secrets) {
109-
extractLocationsOnly(targetRun, targetKeys)
110-
}
111-
for _, targetRun := range targetJasResults.GetViolationsResults(jasutils.Secrets) {
112-
extractLocationsOnly(targetRun, targetKeys)
113-
}
114-
for _, targetRun := range targetJasResults.GetVulnerabilitiesResults(jasutils.IaC) {
115-
extractLocationsOnly(targetRun, targetKeys)
116-
}
117-
for _, targetRun := range targetJasResults.GetViolationsResults(jasutils.IaC) {
118-
extractLocationsOnly(targetRun, targetKeys)
119-
}
120-
for _, targetRun := range targetJasResults.GetVulnerabilitiesResults(jasutils.Sast) {
121-
extractFingerprints(targetRun, targetKeys)
122-
}
123-
for _, targetRun := range targetJasResults.GetViolationsResults(jasutils.Sast) {
124-
extractFingerprints(targetRun, targetKeys)
125-
}
126-
}
127-
128-
sourceSecrets := countSarifResults(sourceJasResults.JasVulnerabilities.SecretsScanResults) +
129-
countSarifResults(sourceJasResults.JasViolations.SecretsScanResults)
130-
sourceIac := countSarifResults(sourceJasResults.JasVulnerabilities.IacScanResults) +
131-
countSarifResults(sourceJasResults.JasViolations.IacScanResults)
132-
sourceSast := countSarifResults(sourceJasResults.JasVulnerabilities.SastScanResults) +
133-
countSarifResults(sourceJasResults.JasViolations.SastScanResults)
104+
sourceSecrets, sourceIac, sourceSast := countJasFindings(sourceJasResults)
134105

135106
log.Debug("[DIFF] Source findings before diff - Secrets:", sourceSecrets, "| IaC:", sourceIac, "| SAST:", sourceSast)
136107

@@ -150,19 +121,28 @@ func filterExistingFindings(allTargetJasResults []*JasScansResults, sourceJasRes
150121
filteredJasResults.JasViolations.SastScanResults = filterNewSarifFindings(
151122
sourceJasResults.JasViolations.SastScanResults, targetKeys)
152123

153-
diffSecrets := countSarifResults(filteredJasResults.JasVulnerabilities.SecretsScanResults) +
154-
countSarifResults(filteredJasResults.JasViolations.SecretsScanResults)
155-
diffIac := countSarifResults(filteredJasResults.JasVulnerabilities.IacScanResults) +
156-
countSarifResults(filteredJasResults.JasViolations.IacScanResults)
157-
diffSast := countSarifResults(filteredJasResults.JasVulnerabilities.SastScanResults) +
158-
countSarifResults(filteredJasResults.JasViolations.SastScanResults)
124+
diffSecrets, diffIac, diffSast := countJasFindings(filteredJasResults)
159125

160126
log.Info("[DIFF] New findings after diff - Secrets:", diffSecrets, "| IaC:", diffIac, "| SAST:", diffSast)
161127
log.Info("[DIFF] Filtered out - Secrets:", sourceSecrets-diffSecrets, "| IaC:", sourceIac-diffIac, "| SAST:", sourceSast-diffSast)
162128

163129
return filteredJasResults
164130
}
165131

132+
// countJasFindings returns the count of (secrets, iac, sast) findings in the JAS results.
133+
func countJasFindings(jasResults *JasScansResults) (secrets, iac, sast int) {
134+
if jasResults == nil {
135+
return
136+
}
137+
secrets = countSarifResults(jasResults.JasVulnerabilities.SecretsScanResults) +
138+
countSarifResults(jasResults.JasViolations.SecretsScanResults)
139+
iac = countSarifResults(jasResults.JasVulnerabilities.IacScanResults) +
140+
countSarifResults(jasResults.JasViolations.IacScanResults)
141+
sast = countSarifResults(jasResults.JasVulnerabilities.SastScanResults) +
142+
countSarifResults(jasResults.JasViolations.SastScanResults)
143+
return
144+
}
145+
166146
func countSarifResults(runs []*sarif.Run) int {
167147
count := 0
168148
for _, run := range runs {
@@ -173,41 +153,62 @@ func countSarifResults(runs []*sarif.Run) int {
173153
return count
174154
}
175155

176-
func extractFingerprints(run *sarif.Run, targetKeys map[string]bool) {
177-
for _, result := range run.Results {
178-
if sarifutils.IsFingerprintsExists(result) {
179-
key := getSastFingerprint(result)
180-
if key != "" {
181-
targetKeys[key] = true
182-
}
183-
} else {
184-
for _, location := range result.Locations {
185-
key := sarifutils.GetRelativeLocationFileName(location, run.Invocations) + sarifutils.GetLocationSnippetText(location)
186-
targetKeys[key] = true
187-
}
156+
// extractAllJasResultKeys extracts unique identifiers from all JAS results for diff comparison.
157+
// For Secrets/IaC: uses file path + snippet as key (location-based matching).
158+
// For SAST: uses fingerprint when available, falls back to location-based matching.
159+
func extractAllJasResultKeys(jasResults ...*JasScansResults) map[string]bool {
160+
targetKeys := make(map[string]bool)
161+
for _, jasResult := range jasResults {
162+
if jasResult == nil {
163+
continue
188164
}
165+
// Secrets and IaC use location-based matching
166+
extractLocationsOnly(targetKeys,
167+
jasResult.GetVulnerabilitiesResults(jasutils.Secrets)...)
168+
extractLocationsOnly(targetKeys,
169+
jasResult.GetViolationsResults(jasutils.Secrets)...)
170+
extractLocationsOnly(targetKeys,
171+
jasResult.GetVulnerabilitiesResults(jasutils.IaC)...)
172+
extractLocationsOnly(targetKeys,
173+
jasResult.GetViolationsResults(jasutils.IaC)...)
174+
// SAST uses fingerprint-based matching when available
175+
extractFingerprints(targetKeys,
176+
jasResult.GetVulnerabilitiesResults(jasutils.Sast)...)
177+
extractFingerprints(targetKeys,
178+
jasResult.GetViolationsResults(jasutils.Sast)...)
189179
}
180+
return targetKeys
190181
}
191182

192-
func extractLocationsOnly(run *sarif.Run, targetKeys map[string]bool) {
193-
for _, result := range run.Results {
194-
for _, location := range result.Locations {
195-
key := sarifutils.GetRelativeLocationFileName(location, run.Invocations) + sarifutils.GetLocationSnippetText(location)
196-
targetKeys[key] = true
183+
// extractFingerprints extracts SAST fingerprints (or falls back to locations) for diff matching.
184+
func extractFingerprints(targetKeys map[string]bool, runs ...*sarif.Run) {
185+
for _, run := range runs {
186+
for _, result := range run.Results {
187+
if sarifutils.IsFingerprintsExists(result) {
188+
key := sarifutils.GetSastDiffFingerprint(result)
189+
if key != "" {
190+
targetKeys[key] = true
191+
}
192+
} else {
193+
for _, location := range result.Locations {
194+
key := sarifutils.GetRelativeLocationFileName(location, run.Invocations) + sarifutils.GetLocationSnippetText(location)
195+
targetKeys[key] = true
196+
}
197+
}
197198
}
198199
}
199200
}
200201

201-
// getSastFingerprint extracts the SAST fingerprint used for diff matching.
202-
// Note: Uses "precise_sink_and_sink_function" key (from Analyzer Manager for diff purposes),
203-
// which differs from jasutils.SastFingerprintKey ("significant_full_path") used elsewhere.
204-
func getSastFingerprint(result *sarif.Result) string {
205-
if result.Fingerprints != nil {
206-
if value, ok := result.Fingerprints["precise_sink_and_sink_function"]; ok {
207-
return value
202+
// extractLocationsOnly extracts location-based keys (file path + snippet) for diff matching.
203+
func extractLocationsOnly(targetKeys map[string]bool, runs ...*sarif.Run) {
204+
for _, run := range runs {
205+
for _, result := range run.Results {
206+
for _, location := range result.Locations {
207+
key := sarifutils.GetRelativeLocationFileName(location, run.Invocations) + sarifutils.GetLocationSnippetText(location)
208+
targetKeys[key] = true
209+
}
208210
}
209211
}
210-
return ""
211212
}
212213

213214
// filterNewSarifFindings removes findings from sourceRuns that already exist in targetKeys.
@@ -221,7 +222,7 @@ func filterNewSarifFindings(sourceRuns []*sarif.Run, targetKeys map[string]bool)
221222

222223
for _, result := range run.Results {
223224
if sarifutils.IsFingerprintsExists(result) {
224-
if !targetKeys[getSastFingerprint(result)] {
225+
if !targetKeys[sarifutils.GetSastDiffFingerprint(result)] {
225226
filteredResults = append(filteredResults, result)
226227
}
227228
} else {

0 commit comments

Comments
 (0)