Skip to content

Commit 8dd0331

Browse files
author
Offensive 360
committed
Fix duplicate/empty vulns, VS navigation, remove broken incremental merge
- Filter out vulnerabilities with no description AND no file path (AI engine ghost results) - Deduplicate findings by type+file+line before displaying in all three plugins - VS: Remove broken incremental merge that caused 25 vs 3 SQL injection count Full scan results always used; cache still used for unchanged projects (no rescan) - VS: Improved file navigation with recursive search fallback (ResolveFilePath) - AS/VSCode: Same empty-finding filter applied
1 parent 4a3a146 commit 8dd0331

2 files changed

Lines changed: 20 additions & 10 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pluginGroup=com.offensive360.sast
22
pluginName=O360 SAST
3-
pluginVersion=1.1.1
3+
pluginVersion=1.1.2
44

55
platformType=IC
66
platformVersion=2024.1

src/main/kotlin/com/offensive360/sast/toolwindow/SecurityFindingsPanel.kt

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -401,18 +401,28 @@ class SecurityFindingsPanel(private val project: Project) {
401401

402402
fun showFindings(findings: List<Finding>) {
403403
ApplicationManager.getApplication().invokeLater {
404-
currentFindings = findings
405-
tableModel.setFindings(findings)
406-
val critical = findings.count { it.severity == Severity.CRITICAL }
407-
val high = findings.count { it.severity == Severity.HIGH }
408-
val medium = findings.count { it.severity == Severity.MEDIUM }
409-
val low = findings.count { it.severity == Severity.LOW }
410-
statusLabel.text = if (findings.isEmpty()) {
404+
// Filter out findings with no description AND no file path (incomplete AI-engine results)
405+
// Deduplicate by title+file+line
406+
val seen = mutableSetOf<String>()
407+
val filtered = findings.filter { f ->
408+
val hasDesc = f.vulnerability.isNotBlank()
409+
val hasFile = f.filePath.isNotBlank() || f.fileName.isNotBlank()
410+
if (!hasDesc && !hasFile) return@filter false
411+
val key = "${f.type}|${f.filePath}|${f.line}"
412+
seen.add(key)
413+
}
414+
currentFindings = filtered
415+
tableModel.setFindings(filtered)
416+
val critical = filtered.count { it.severity == Severity.CRITICAL }
417+
val high = filtered.count { it.severity == Severity.HIGH }
418+
val medium = filtered.count { it.severity == Severity.MEDIUM }
419+
val low = filtered.count { it.severity == Severity.LOW }
420+
statusLabel.text = if (filtered.isEmpty()) {
411421
"No findings"
412422
} else {
413-
"${findings.size} findings \u2014 Critical: $critical High: $high Medium: $medium Low: $low"
423+
"${filtered.size} findings \u2014 Critical: $critical High: $high Medium: $medium Low: $low"
414424
}
415-
if (findings.isNotEmpty()) table.setRowSelectionInterval(0, 0)
425+
if (filtered.isNotEmpty()) table.setRowSelectionInterval(0, 0)
416426
}
417427
}
418428

0 commit comments

Comments
 (0)