scanoss 1.27.0__tar.gz → 1.28.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {scanoss-1.27.0/src/scanoss.egg-info → scanoss-1.28.0}/PKG-INFO +1 -1
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/__init__.py +1 -1
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/cyclonedx.py +96 -11
- scanoss-1.28.0/src/scanoss/data/build_date.txt +1 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanner.py +23 -23
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanners/container_scanner.py +4 -2
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanners/scanner_hfh.py +15 -4
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanossgrpc.py +1 -1
- {scanoss-1.27.0 → scanoss-1.28.0/src/scanoss.egg-info}/PKG-INFO +1 -1
- scanoss-1.27.0/src/scanoss/data/build_date.txt +0 -1
- {scanoss-1.27.0 → scanoss-1.28.0}/LICENSE +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/PACKAGE.md +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/README.md +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/pyproject.toml +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/setup.cfg +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/protoc_gen_swagger/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/protoc_gen_swagger/options/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/protoc_gen_swagger/options/annotations_pb2.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/protoc_gen_swagger/options/annotations_pb2_grpc.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/protoc_gen_swagger/options/openapiv2_pb2.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/common/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/common/v2/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/common/v2/scanoss_common_pb2.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/components/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/components/v2/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/components/v2/scanoss_components_pb2.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/components/v2/scanoss_components_pb2_grpc.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/dependencies/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/dependencies/v2/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/geoprovenance/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/geoprovenance/v2/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2_grpc.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/scanning/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/scanning/v2/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/scanning/v2/scanoss_scanning_pb2.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/semgrep/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/semgrep/v2/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/vulnerabilities/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/vulnerabilities/v2/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/cli.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/components.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/constants.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/cryptography.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/csvoutput.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/data/scanoss-settings-schema.json +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/data/spdx-exceptions.json +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/data/spdx-licenses.json +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/file_filters.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/filecount.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/inspection/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/inspection/component_summary.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/inspection/copyleft.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/inspection/inspect_base.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/inspection/license_summary.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/inspection/policy_check.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/inspection/undeclared_component.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/inspection/utils/license_utils.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/results.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scancodedeps.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanners/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanners/folder_hasher.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanners/scanner_config.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanoss_settings.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanossapi.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanossbase.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scanpostprocessor.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/scantype.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/spdxlite.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/threadeddependencies.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/threadedscanning.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/utils/__init__.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/utils/abstract_presenter.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/utils/crc64.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/utils/file.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/utils/simhash.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/winnowing.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss.egg-info/SOURCES.txt +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss.egg-info/dependency_links.txt +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss.egg-info/entry_points.txt +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss.egg-info/requires.txt +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss.egg-info/top_level.txt +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/tests/test_csv_output.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/tests/test_file_filters.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/tests/test_policy_inspect.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/tests/test_scan_post_processor.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/tests/test_spdxlite.py +0 -0
- {scanoss-1.27.0 → scanoss-1.28.0}/tests/test_winnowing.py +0 -0
|
@@ -22,14 +22,13 @@ SPDX-License-Identifier: MIT
|
|
|
22
22
|
THE SOFTWARE.
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
+
import datetime
|
|
25
26
|
import json
|
|
26
27
|
import os.path
|
|
27
28
|
import sys
|
|
28
29
|
import uuid
|
|
29
|
-
import datetime
|
|
30
30
|
|
|
31
31
|
from . import __version__
|
|
32
|
-
|
|
33
32
|
from .scanossbase import ScanossBase
|
|
34
33
|
from .spdxlite import SpdxLite
|
|
35
34
|
|
|
@@ -49,7 +48,7 @@ class CycloneDx(ScanossBase):
|
|
|
49
48
|
self.debug = debug
|
|
50
49
|
self._spdx = SpdxLite(debug=debug)
|
|
51
50
|
|
|
52
|
-
def parse(self, data: json):
|
|
51
|
+
def parse(self, data: json): # noqa: PLR0912, PLR0915
|
|
53
52
|
"""
|
|
54
53
|
Parse the given input (raw/plain) JSON string and return CycloneDX summary
|
|
55
54
|
:param data: json - JSON object
|
|
@@ -58,7 +57,7 @@ class CycloneDx(ScanossBase):
|
|
|
58
57
|
if not data:
|
|
59
58
|
self.print_stderr('ERROR: No JSON data provided to parse.')
|
|
60
59
|
return None, None
|
|
61
|
-
self.print_debug(
|
|
60
|
+
self.print_debug('Processing raw results into CycloneDX format...')
|
|
62
61
|
cdx = {}
|
|
63
62
|
vdx = {}
|
|
64
63
|
for f in data:
|
|
@@ -171,17 +170,22 @@ class CycloneDx(ScanossBase):
|
|
|
171
170
|
success = self.produce_from_str(f.read(), output_file)
|
|
172
171
|
return success
|
|
173
172
|
|
|
174
|
-
def produce_from_json(self, data: json, output_file: str = None) -> bool:
|
|
173
|
+
def produce_from_json(self, data: json, output_file: str = None) -> tuple[bool, json]: # noqa: PLR0912
|
|
175
174
|
"""
|
|
176
|
-
Produce the CycloneDX output from the input data
|
|
177
|
-
|
|
178
|
-
:
|
|
179
|
-
|
|
175
|
+
Produce the CycloneDX output from the raw scan results input data
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
data (json): JSON object
|
|
179
|
+
output_file (str, optional): Output file (optional). Defaults to None.
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
bool: True if successful, False otherwise
|
|
183
|
+
json: The CycloneDX output
|
|
180
184
|
"""
|
|
181
185
|
cdx, vdx = self.parse(data)
|
|
182
186
|
if not cdx:
|
|
183
187
|
self.print_stderr('ERROR: No CycloneDX data returned for the JSON string provided.')
|
|
184
|
-
return False
|
|
188
|
+
return False, None
|
|
185
189
|
self._spdx.load_license_data() # Load SPDX license name data for later reference
|
|
186
190
|
#
|
|
187
191
|
# Using CDX version 1.4: https://cyclonedx.org/docs/1.4/json/
|
|
@@ -264,7 +268,7 @@ class CycloneDx(ScanossBase):
|
|
|
264
268
|
if output_file:
|
|
265
269
|
file.close()
|
|
266
270
|
|
|
267
|
-
return True
|
|
271
|
+
return True, data
|
|
268
272
|
|
|
269
273
|
def produce_from_str(self, json_str: str, output_file: str = None) -> bool:
|
|
270
274
|
"""
|
|
@@ -283,6 +287,87 @@ class CycloneDx(ScanossBase):
|
|
|
283
287
|
return False
|
|
284
288
|
return self.produce_from_json(data, output_file)
|
|
285
289
|
|
|
290
|
+
def _normalize_vulnerability_id(self, vuln: dict) -> tuple[str, str]:
|
|
291
|
+
"""
|
|
292
|
+
Normalize vulnerability ID and CVE from different possible field names.
|
|
293
|
+
Returns tuple of (vuln_id, vuln_cve).
|
|
294
|
+
"""
|
|
295
|
+
vuln_id = vuln.get('ID', '') or vuln.get('id', '')
|
|
296
|
+
vuln_cve = vuln.get('CVE', '') or vuln.get('cve', '')
|
|
297
|
+
|
|
298
|
+
# Skip CPE entries, use CVE if available
|
|
299
|
+
if vuln_id.upper().startswith('CPE:') and vuln_cve:
|
|
300
|
+
vuln_id = vuln_cve
|
|
301
|
+
|
|
302
|
+
return vuln_id, vuln_cve
|
|
303
|
+
|
|
304
|
+
def _create_vulnerability_entry(self, vuln_id: str, vuln: dict, vuln_cve: str, purl: str) -> dict:
|
|
305
|
+
"""
|
|
306
|
+
Create a new vulnerability entry for CycloneDX format.
|
|
307
|
+
"""
|
|
308
|
+
vuln_source = vuln.get('source', '').lower()
|
|
309
|
+
return {
|
|
310
|
+
'id': vuln_id,
|
|
311
|
+
'source': {
|
|
312
|
+
'name': 'NVD' if vuln_source == 'nvd' else 'GitHub Advisories',
|
|
313
|
+
'url': f'https://nvd.nist.gov/vuln/detail/{vuln_cve}'
|
|
314
|
+
if vuln_source == 'nvd'
|
|
315
|
+
else f'https://github.com/advisories/{vuln_id}'
|
|
316
|
+
},
|
|
317
|
+
'ratings': [{'severity': self._sev_lookup(vuln.get('severity', 'unknown').lower())}],
|
|
318
|
+
'affects': [{'ref': purl}]
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
def append_vulnerabilities(self, cdx_dict: dict, vulnerabilities_data: dict, purl: str) -> dict:
|
|
322
|
+
"""
|
|
323
|
+
Append vulnerabilities to an existing CycloneDX dictionary
|
|
324
|
+
|
|
325
|
+
Args:
|
|
326
|
+
cdx_dict (dict): The existing CycloneDX dictionary
|
|
327
|
+
vulnerabilities_data (dict): The vulnerabilities data from get_vulnerabilities_json
|
|
328
|
+
purl (str): The PURL of the component these vulnerabilities affect
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
dict: The updated CycloneDX dictionary with vulnerabilities appended
|
|
332
|
+
"""
|
|
333
|
+
if not cdx_dict or not vulnerabilities_data:
|
|
334
|
+
return cdx_dict
|
|
335
|
+
|
|
336
|
+
if 'vulnerabilities' not in cdx_dict:
|
|
337
|
+
cdx_dict['vulnerabilities'] = []
|
|
338
|
+
|
|
339
|
+
# Extract vulnerabilities from the response
|
|
340
|
+
vulns_list = vulnerabilities_data.get('purls', [])
|
|
341
|
+
if not vulns_list:
|
|
342
|
+
return cdx_dict
|
|
343
|
+
|
|
344
|
+
vuln_items = vulns_list[0].get('vulnerabilities', [])
|
|
345
|
+
|
|
346
|
+
for vuln in vuln_items:
|
|
347
|
+
vuln_id, vuln_cve = self._normalize_vulnerability_id(vuln)
|
|
348
|
+
|
|
349
|
+
# Skip empty IDs or CPE-only entries
|
|
350
|
+
if not vuln_id or vuln_id.upper().startswith('CPE:'):
|
|
351
|
+
continue
|
|
352
|
+
|
|
353
|
+
# Check if vulnerability already exists
|
|
354
|
+
existing_vuln = next(
|
|
355
|
+
(v for v in cdx_dict['vulnerabilities'] if v.get('id') == vuln_id),
|
|
356
|
+
None
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
if existing_vuln:
|
|
360
|
+
# Add this PURL to the affects list if not already present
|
|
361
|
+
if not any(ref.get('ref') == purl for ref in existing_vuln.get('affects', [])):
|
|
362
|
+
existing_vuln['affects'].append({'ref': purl})
|
|
363
|
+
else:
|
|
364
|
+
# Create new vulnerability entry
|
|
365
|
+
cdx_dict['vulnerabilities'].append(
|
|
366
|
+
self._create_vulnerability_entry(vuln_id, vuln, vuln_cve, purl)
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
return cdx_dict
|
|
370
|
+
|
|
286
371
|
@staticmethod
|
|
287
372
|
def _sev_lookup(value: str):
|
|
288
373
|
"""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
date: 20250710142446, utime: 1752157486
|
|
@@ -22,40 +22,40 @@ SPDX-License-Identifier: MIT
|
|
|
22
22
|
THE SOFTWARE.
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
+
import datetime
|
|
25
26
|
import json
|
|
26
27
|
import os
|
|
27
|
-
from pathlib import Path
|
|
28
28
|
import sys
|
|
29
|
-
import
|
|
29
|
+
from pathlib import Path
|
|
30
30
|
from typing import Any, Dict, List, Optional
|
|
31
|
-
import importlib_resources
|
|
32
31
|
|
|
32
|
+
import importlib_resources
|
|
33
33
|
from progress.bar import Bar
|
|
34
34
|
from progress.spinner import Spinner
|
|
35
35
|
from pypac.parser import PACFile
|
|
36
36
|
|
|
37
37
|
from scanoss.file_filters import FileFilters
|
|
38
38
|
|
|
39
|
-
from .
|
|
40
|
-
from .cyclonedx import CycloneDx
|
|
41
|
-
from .spdxlite import SpdxLite
|
|
39
|
+
from . import __version__
|
|
42
40
|
from .csvoutput import CsvOutput
|
|
43
|
-
from .
|
|
41
|
+
from .cyclonedx import CycloneDx
|
|
44
42
|
from .scancodedeps import ScancodeDeps
|
|
45
|
-
from .threadeddependencies import ThreadedDependencies, SCOPE
|
|
46
|
-
from .scanossgrpc import ScanossGrpc
|
|
47
|
-
from .scantype import ScanType
|
|
48
|
-
from .scanossbase import ScanossBase
|
|
49
43
|
from .scanoss_settings import ScanossSettings
|
|
44
|
+
from .scanossapi import ScanossApi
|
|
45
|
+
from .scanossbase import ScanossBase
|
|
46
|
+
from .scanossgrpc import ScanossGrpc
|
|
50
47
|
from .scanpostprocessor import ScanPostProcessor
|
|
51
|
-
from . import
|
|
48
|
+
from .scantype import ScanType
|
|
49
|
+
from .spdxlite import SpdxLite
|
|
50
|
+
from .threadeddependencies import SCOPE, ThreadedDependencies
|
|
51
|
+
from .threadedscanning import ThreadedScanning
|
|
52
52
|
|
|
53
53
|
FAST_WINNOWING = False
|
|
54
54
|
try:
|
|
55
55
|
from scanoss_winnowing.winnowing import Winnowing
|
|
56
56
|
|
|
57
57
|
FAST_WINNOWING = True
|
|
58
|
-
except ModuleNotFoundError
|
|
58
|
+
except (ModuleNotFoundError, ImportError):
|
|
59
59
|
FAST_WINNOWING = False
|
|
60
60
|
from .winnowing import Winnowing
|
|
61
61
|
|
|
@@ -284,7 +284,7 @@ class Scanner(ScanossBase):
|
|
|
284
284
|
return True
|
|
285
285
|
return False
|
|
286
286
|
|
|
287
|
-
def scan_folder_with_options(
|
|
287
|
+
def scan_folder_with_options( # noqa: PLR0913
|
|
288
288
|
self,
|
|
289
289
|
scan_dir: str,
|
|
290
290
|
deps_file: str = None,
|
|
@@ -332,7 +332,7 @@ class Scanner(ScanossBase):
|
|
|
332
332
|
success = False
|
|
333
333
|
return success
|
|
334
334
|
|
|
335
|
-
def scan_folder(self, scan_dir: str) -> bool:
|
|
335
|
+
def scan_folder(self, scan_dir: str) -> bool: # noqa: PLR0912, PLR0915
|
|
336
336
|
"""
|
|
337
337
|
Scan the specified folder producing fingerprints, send to the SCANOSS API and return results
|
|
338
338
|
|
|
@@ -400,7 +400,7 @@ class Scanner(ScanossBase):
|
|
|
400
400
|
scan_block += wfp
|
|
401
401
|
scan_size = len(scan_block.encode('utf-8'))
|
|
402
402
|
wfp_file_count += 1
|
|
403
|
-
# If the scan request block (group of WFPs) or larger than the POST size or we have reached the file limit, add it to the queue
|
|
403
|
+
# If the scan request block (group of WFPs) or larger than the POST size or we have reached the file limit, add it to the queue # noqa: E501
|
|
404
404
|
if wfp_file_count > self.post_file_count or scan_size >= self.max_post_size:
|
|
405
405
|
self.threaded_scan.queue_add(scan_block)
|
|
406
406
|
queue_size += 1
|
|
@@ -484,7 +484,7 @@ class Scanner(ScanossBase):
|
|
|
484
484
|
self.__log_result(json.dumps(results, indent=2, sort_keys=True))
|
|
485
485
|
elif self.output_format == 'cyclonedx':
|
|
486
486
|
cdx = CycloneDx(self.debug, self.scan_output)
|
|
487
|
-
success = cdx.produce_from_json(results)
|
|
487
|
+
success, _ = cdx.produce_from_json(results)
|
|
488
488
|
elif self.output_format == 'spdxlite':
|
|
489
489
|
spdxlite = SpdxLite(self.debug, self.scan_output)
|
|
490
490
|
success = spdxlite.produce_from_json(results)
|
|
@@ -509,7 +509,7 @@ class Scanner(ScanossBase):
|
|
|
509
509
|
for response in scan_responses:
|
|
510
510
|
if response is not None:
|
|
511
511
|
if file_map:
|
|
512
|
-
response = self._deobfuscate_filenames(response, file_map)
|
|
512
|
+
response = self._deobfuscate_filenames(response, file_map) # noqa: PLW2901
|
|
513
513
|
results.update(response)
|
|
514
514
|
|
|
515
515
|
dep_files = dep_responses.get('files', None) if dep_responses else None
|
|
@@ -532,7 +532,7 @@ class Scanner(ScanossBase):
|
|
|
532
532
|
deobfuscated[key] = value
|
|
533
533
|
return deobfuscated
|
|
534
534
|
|
|
535
|
-
def scan_file_with_options(
|
|
535
|
+
def scan_file_with_options( # noqa: PLR0913
|
|
536
536
|
self,
|
|
537
537
|
file: str,
|
|
538
538
|
deps_file: str = None,
|
|
@@ -603,7 +603,7 @@ class Scanner(ScanossBase):
|
|
|
603
603
|
success = False
|
|
604
604
|
return success
|
|
605
605
|
|
|
606
|
-
def scan_files(self, files: []) -> bool:
|
|
606
|
+
def scan_files(self, files: []) -> bool: # noqa: PLR0912, PLR0915
|
|
607
607
|
"""
|
|
608
608
|
Scan the specified list of files, producing fingerprints, send to the SCANOSS API and return results
|
|
609
609
|
Please note that by providing an explicit list you bypass any exclusions that may be defined on the scanner
|
|
@@ -657,7 +657,7 @@ class Scanner(ScanossBase):
|
|
|
657
657
|
file_count += 1
|
|
658
658
|
if self.threaded_scan:
|
|
659
659
|
wfp_size = len(wfp.encode('utf-8'))
|
|
660
|
-
# If the WFP is bigger than the max post size and we already have something stored in the scan block, add it to the queue
|
|
660
|
+
# If the WFP is bigger than the max post size and we already have something stored in the scan block, add it to the queue # noqa: E501
|
|
661
661
|
if scan_block != '' and (wfp_size + scan_size) >= self.max_post_size:
|
|
662
662
|
self.threaded_scan.queue_add(scan_block)
|
|
663
663
|
queue_size += 1
|
|
@@ -666,7 +666,7 @@ class Scanner(ScanossBase):
|
|
|
666
666
|
scan_block += wfp
|
|
667
667
|
scan_size = len(scan_block.encode('utf-8'))
|
|
668
668
|
wfp_file_count += 1
|
|
669
|
-
# If the scan request block (group of WFPs) or larger than the POST size or we have reached the file limit, add it to the queue
|
|
669
|
+
# If the scan request block (group of WFPs) or larger than the POST size or we have reached the file limit, add it to the queue # noqa: E501
|
|
670
670
|
if wfp_file_count > self.post_file_count or scan_size >= self.max_post_size:
|
|
671
671
|
self.threaded_scan.queue_add(scan_block)
|
|
672
672
|
queue_size += 1
|
|
@@ -755,7 +755,7 @@ class Scanner(ScanossBase):
|
|
|
755
755
|
success = False
|
|
756
756
|
return success
|
|
757
757
|
|
|
758
|
-
def scan_wfp_file(self, file: str = None) -> bool:
|
|
758
|
+
def scan_wfp_file(self, file: str = None) -> bool: # noqa: PLR0912, PLR0915
|
|
759
759
|
"""
|
|
760
760
|
Scan the contents of the specified WFP file (in the current process)
|
|
761
761
|
:param file: Scan the contents of the specified WFP file (in the current process)
|
|
@@ -436,10 +436,12 @@ class ContainerScannerPresenter(AbstractPresenter):
|
|
|
436
436
|
scan_results = {}
|
|
437
437
|
for f in self.scanner.decorated_scan_results['files']:
|
|
438
438
|
scan_results[f['file']] = [f]
|
|
439
|
-
|
|
439
|
+
success, cdx_output = cdx.produce_from_json(scan_results)
|
|
440
|
+
if not success:
|
|
440
441
|
error_msg = 'Failed to produce CycloneDX output'
|
|
441
442
|
self.base.print_stderr(error_msg)
|
|
442
|
-
|
|
443
|
+
return None
|
|
444
|
+
return json.dumps(cdx_output, indent=2)
|
|
443
445
|
|
|
444
446
|
def _format_spdxlite_output(self) -> str:
|
|
445
447
|
"""
|
|
@@ -162,7 +162,7 @@ class ScannerHFHPresenter(AbstractPresenter):
|
|
|
162
162
|
else str(self.scanner.scan_results)
|
|
163
163
|
)
|
|
164
164
|
|
|
165
|
-
def _format_cyclonedx_output(self) -> str:
|
|
165
|
+
def _format_cyclonedx_output(self) -> str: # noqa: PLR0911
|
|
166
166
|
if not self.scanner.scan_results:
|
|
167
167
|
return ''
|
|
168
168
|
try:
|
|
@@ -193,17 +193,28 @@ class ScannerHFHPresenter(AbstractPresenter):
|
|
|
193
193
|
}
|
|
194
194
|
]
|
|
195
195
|
}
|
|
196
|
+
|
|
197
|
+
get_vulnerabilities_json_request = {
|
|
198
|
+
'purls': [{'purl': purl, 'requirement': best_match_version['version']}],
|
|
199
|
+
}
|
|
196
200
|
|
|
197
201
|
decorated_scan_results = self.scanner.client.get_dependencies(get_dependencies_json_request)
|
|
202
|
+
vulnerabilities = self.scanner.client.get_vulnerabilities_json(get_vulnerabilities_json_request)
|
|
198
203
|
|
|
199
|
-
cdx = CycloneDx(self.base.debug
|
|
204
|
+
cdx = CycloneDx(self.base.debug)
|
|
200
205
|
scan_results = {}
|
|
201
206
|
for f in decorated_scan_results['files']:
|
|
202
207
|
scan_results[f['file']] = [f]
|
|
203
|
-
|
|
208
|
+
success, cdx_output = cdx.produce_from_json(scan_results)
|
|
209
|
+
if not success:
|
|
204
210
|
error_msg = 'ERROR: Failed to produce CycloneDX output'
|
|
205
211
|
self.base.print_stderr(error_msg)
|
|
206
|
-
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
if vulnerabilities:
|
|
215
|
+
cdx_output = cdx.append_vulnerabilities(cdx_output, vulnerabilities, purl)
|
|
216
|
+
|
|
217
|
+
return json.dumps(cdx_output, indent=2)
|
|
207
218
|
except Exception as e:
|
|
208
219
|
self.base.print_stderr(f'ERROR: Failed to get license information: {e}')
|
|
209
220
|
return None
|
|
@@ -326,7 +326,7 @@ class ScanossGrpc(ScanossBase):
|
|
|
326
326
|
request = ParseDict(purls, PurlRequest()) # Parse the JSON/Dict into the purl request object
|
|
327
327
|
metadata = self.metadata[:]
|
|
328
328
|
metadata.append(('x-request-id', request_id)) # Set a Request ID
|
|
329
|
-
self.print_debug(f'Sending
|
|
329
|
+
self.print_debug(f'Sending vulnerability data for decoration (rqId: {request_id})...')
|
|
330
330
|
resp = self.vuln_stub.GetVulnerabilities(request, metadata=metadata, timeout=self.timeout)
|
|
331
331
|
except Exception as e:
|
|
332
332
|
self.print_stderr(
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
date: 20250708100043, utime: 1751968843
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/components/v2/scanoss_components_pb2_grpc.py
RENAMED
|
File without changes
|
{scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py
RENAMED
|
File without changes
|
{scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py
RENAMED
|
File without changes
|
{scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2.py
RENAMED
|
File without changes
|
{scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scanoss-1.27.0 → scanoss-1.28.0}/src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|