Skip to content

Commit 96644b5

Browse files
committed
fix(scanoss): Exclude identified snippets from SnippetFindings
Modifies generateSummary() to filter out snippets that are already identified. Only unidentified snippets should be included in the SnippetFindings results. Signed-off-by: Agustin Isasmendi <[email protected]>
1 parent dbf8667 commit 96644b5

File tree

3 files changed

+171
-23
lines changed

3 files changed

+171
-23
lines changed

plugins/scanners/scanoss/src/main/kotlin/ScanOssResultParser.kt

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import com.scanoss.dto.LicenseDetails
2323
import com.scanoss.dto.ScanFileDetails
2424
import com.scanoss.dto.ScanFileResult
2525
import com.scanoss.dto.enums.MatchType
26+
import com.scanoss.dto.enums.StatusType
2627

2728
import java.lang.invoke.MethodHandles
2829
import java.time.Instant
@@ -62,22 +63,28 @@ internal fun generateSummary(startTime: Instant, endTime: Instant, results: List
6263

6364
MatchType.snippet -> {
6465
val localFile = requireNotNull(result.filePath)
65-
val localLines = requireNotNull(details.lines)
66-
val sourceLocations = convertLines(localFile, localLines)
67-
val snippets = getSnippets(details)
68-
69-
// The number of snippets should match the number of source locations.
70-
if (sourceLocations.size != snippets.size) {
71-
logger.warn {
72-
"Unexpected mismatch in '$localFile': " +
73-
"${sourceLocations.size} source locations vs ${snippets.size} snippets. " +
74-
"This indicates a potential issue with line range conversion."
66+
if (details.status == StatusType.pending) {
67+
val localLines = requireNotNull(details.lines)
68+
val sourceLocations = convertLines(localFile, localLines)
69+
val snippets = getSnippets(details)
70+
71+
// The number of snippets should match the number of source locations.
72+
if (sourceLocations.size != snippets.size) {
73+
logger.warn {
74+
"Unexpected mismatch in '$localFile': " +
75+
"${sourceLocations.size} source locations vs ${snippets.size} snippets. " +
76+
"This indicates a potential issue with line range conversion."
77+
}
7578
}
76-
}
7779

78-
// Associate each source location with its corresponding snippet.
79-
sourceLocations.zip(snippets).forEach { (location, snippet) ->
80-
snippetFindings += SnippetFinding(location, setOf(snippet))
80+
// Associate each source location with its corresponding snippet.
81+
sourceLocations.zip(snippets).forEach { (location, snippet) ->
82+
snippetFindings += SnippetFinding(location, setOf(snippet))
83+
}
84+
} else {
85+
logger.warn { "File '$localFile' is identified, not including on snippet findings" }
86+
licenseFindings += getLicenseFindings(details)
87+
copyrightFindings += getCopyrightFindings(details)
8188
}
8289
}
8390

@@ -118,9 +125,7 @@ private fun getLicenseFindings(details: ScanFileDetails): List<LicenseFinding> {
118125
LicenseFinding(
119126
license = validatedLicense,
120127
location = TextLocation(
121-
path = path,
122-
startLine = TextLocation.UNKNOWN_LINE,
123-
endLine = TextLocation.UNKNOWN_LINE
128+
path = path, startLine = TextLocation.UNKNOWN_LINE, endLine = TextLocation.UNKNOWN_LINE
124129
),
125130
score = score
126131
)
@@ -137,9 +142,7 @@ private fun getCopyrightFindings(details: ScanFileDetails): List<CopyrightFindin
137142
CopyrightFinding(
138143
statement = copyright.name,
139144
location = TextLocation(
140-
path = path,
141-
startLine = TextLocation.UNKNOWN_LINE,
142-
endLine = TextLocation.UNKNOWN_LINE
145+
path = path, startLine = TextLocation.UNKNOWN_LINE, endLine = TextLocation.UNKNOWN_LINE
143146
)
144147
)
145148
}
@@ -217,8 +220,6 @@ fun getUniqueLicenseExpression(licensesDetails: List<LicenseDetails>): SpdxExpre
217220
return SpdxLicenseIdExpression(SpdxConstants.NOASSERTION)
218221
}
219222

220-
return licensesDetails
221-
.map { license -> SpdxExpression.parse(license.name) }
222-
.reduce { acc, expr -> acc and expr }
223+
return licensesDetails.map { license -> SpdxExpression.parse(license.name) }.reduce { acc, expr -> acc and expr }
223224
.simplify()
224225
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
{
2+
"main.c": [
3+
{
4+
"id": "snippet",
5+
"lines": "14-22",
6+
"oss_lines": "34-42",
7+
"matched": "19%",
8+
"file_hash": "4597ef1de00849bb96d42e78f2cfc3a7",
9+
"source_hash": "f5aef06745de4d711838ea21198f2fc1",
10+
"quality": [
11+
{
12+
"score": "4/5",
13+
"source": "best_practices"
14+
}
15+
],
16+
"cryptography": [],
17+
"purl": [
18+
"pkg:sourceforge/check"
19+
],
20+
"vendor": "check",
21+
"component": "check",
22+
"version": "0.8.1",
23+
"latest": "0.8.1",
24+
"url": "https://sourceforge.net/projects/check",
25+
"status": "identified",
26+
"release_date": "2002-03-02",
27+
"file": "src/check_error.c",
28+
"url_hash": "d81953e1dca4c498140c44f5d6fa92d6",
29+
"licenses": [
30+
{
31+
"name": "LGPL-2.1-or-later",
32+
"patent_hints": "yes",
33+
"copyleft": "yes",
34+
"checklist_url": "https://www.osadl.org/fileadmin/checklists/unreflicenses/LGPL-2.1-or-later.txt",
35+
"incompatible_with": "Apache-1.0, Apache-1.1, Apache-2.0, BSD-4-Clause, BSD-4-Clause-UC, BSD-4.3TAHOE, ECL-2.0, FTL, IJG, LicenseRef-scancode-bsla-no-advert, Minpack, OpenSSL, PHP-3.01, Python-2.0, zlib-acknowledgement, XFree86-1.1",
36+
"osadl_updated": "2025-02-10T14:26:00+0000",
37+
"source": "scancode",
38+
"url": "https://spdx.org/licenses/LGPL-2.1-or-later.html"
39+
},
40+
{
41+
"name": "LGPL-2.1-or-later",
42+
"patent_hints": "yes",
43+
"copyleft": "yes",
44+
"checklist_url": "https://www.osadl.org/fileadmin/checklists/unreflicenses/LGPL-2.1-or-later.txt",
45+
"incompatible_with": "Apache-1.0, Apache-1.1, Apache-2.0, BSD-4-Clause, BSD-4-Clause-UC, BSD-4.3TAHOE, ECL-2.0, FTL, IJG, LicenseRef-scancode-bsla-no-advert, Minpack, OpenSSL, PHP-3.01, Python-2.0, zlib-acknowledgement, XFree86-1.1",
46+
"osadl_updated": "2025-02-10T14:26:00+0000",
47+
"source": "file_header",
48+
"url": "https://spdx.org/licenses/LGPL-2.1-or-later.html"
49+
}
50+
],
51+
"url_stats": {},
52+
"dependencies": [],
53+
"copyrights": [
54+
{
55+
"name": "Copyright (C) 2001; 2002 Arien Malec",
56+
"source": "file_header"
57+
},
58+
{
59+
"name": "Copyright (c) 2001; 2002 Arien Malec",
60+
"source": "scancode"
61+
}
62+
],
63+
"vulnerabilities": [],
64+
"server": {
65+
"version": "5.4.10",
66+
"kb_version": {
67+
"monthly": "25.04",
68+
"daily": "25.05.07"
69+
},
70+
"hostname": "d2",
71+
"flags": "16384",
72+
"elapsed": "0.107563s"
73+
}
74+
}
75+
],
76+
"hung_task.c": [
77+
{
78+
"component": "proton_bluecross",
79+
"file": "kernel/hung_task.c",
80+
"file_hash": "581734935cfbe570d280a1265aaa2a6b",
81+
"file_url": "https://api.scanoss.com/file_contents/581734935cfbe570d280a1265aaa2a6b",
82+
"id": "snippet",
83+
"latest": "17",
84+
"licenses": [
85+
{
86+
"checklist_url": "https://www.osadl.org/fileadmin/checklists/unreflicenses/GPL-2.0-only.txt",
87+
"copyleft": "yes",
88+
"incompatible_with": "Apache-1.0, Apache-1.1, Apache-2.0, BSD-4-Clause, BSD-4-Clause-UC, BSD-4.3TAHOE, ECL-2.0, FTL, IJG, LicenseRef-scancode-bsla-no-advert, Minpack, OpenSSL, PHP-3.01, Python-2.0, zlib-acknowledgement, XFree86-1.1",
89+
"name": "GPL-2.0-only",
90+
"osadl_updated": "2025-02-10T14:26:00+0000",
91+
"patent_hints": "yes",
92+
"source": "scancode",
93+
"url": "https://spdx.org/licenses/GPL-2.0-only.html"
94+
},
95+
{
96+
"name": "GPL-2.0-only WITH Linux-syscall-note",
97+
"source": "scancode",
98+
"url": "https://spdx.org/licenses/GPL-2.0-only WITH Linux-syscall-note.html"
99+
},
100+
{
101+
"checklist_url": "https://www.osadl.org/fileadmin/checklists/unreflicenses/GPL-2.0-only.txt",
102+
"copyleft": "yes",
103+
"incompatible_with": "Apache-1.0, Apache-1.1, Apache-2.0, BSD-4-Clause, BSD-4-Clause-UC, BSD-4.3TAHOE, ECL-2.0, FTL, IJG, LicenseRef-scancode-bsla-no-advert, Minpack, OpenSSL, PHP-3.01, Python-2.0, zlib-acknowledgement, XFree86-1.1",
104+
"name": "GPL-2.0-only",
105+
"osadl_updated": "2025-02-10T14:26:00+0000",
106+
"patent_hints": "yes",
107+
"source": "scancode",
108+
"url": "https://spdx.org/licenses/GPL-2.0-only.html"
109+
}
110+
],
111+
"lines": "12-150",
112+
"matched": "35%",
113+
"oss_lines": "10-148",
114+
"purl": [
115+
"pkg:github/kdrag0n/proton_bluecross"
116+
],
117+
"release_date": "2019-02-21",
118+
"server": {
119+
"kb_version": {
120+
"daily": "25.03.27",
121+
"monthly": "25.03"
122+
},
123+
"version": "5.4.10"
124+
},
125+
"source_hash": "45dd1e50621a8a32f88fbe0251a470ab",
126+
"status": "pending",
127+
"url": "https://github.com/kdrag0n/proton_bluecross",
128+
"url_hash": "a9c1c67f0930dc42dbd40c29e565bcdd",
129+
"vendor": "kdrag0n",
130+
"version": "15"
131+
}
132+
]
133+
}

plugins/scanners/scanoss/src/test/kotlin/ScanOssResultParserTest.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,5 +208,19 @@ class ScanOssResultParserTest : WordSpec({
208208
TextLocation("kernel/hung_task.c", 86, 107)
209209
}
210210
}
211+
212+
"should exclude identified snippets from snippet findings" {
213+
// The scanoss-identified-snippet.json contains two snippets, but one is identified.
214+
// Only unidentified snippets should be included in the SnippetFindings.
215+
val results = File("src/test/assets/scanoss-identified-snippet.json").readText().let {
216+
JsonUtils.toScanFileResultsFromObject(JsonUtils.toJsonObject(it))
217+
}
218+
219+
val time = Instant.now()
220+
val summary = generateSummary(time, time, results)
221+
222+
// Should have only one finding because the identified snippet is excluded
223+
summary.snippetFindings should haveSize(1)
224+
}
211225
}
212226
})

0 commit comments

Comments
 (0)