scanoss 1.27.1__py3-none-any.whl → 1.43.1__py3-none-any.whl
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.
- protoc_gen_swagger/options/annotations_pb2.py +18 -12
- protoc_gen_swagger/options/annotations_pb2.pyi +48 -0
- protoc_gen_swagger/options/annotations_pb2_grpc.py +20 -0
- protoc_gen_swagger/options/openapiv2_pb2.py +110 -99
- protoc_gen_swagger/options/openapiv2_pb2.pyi +1317 -0
- protoc_gen_swagger/options/openapiv2_pb2_grpc.py +20 -0
- scanoss/__init__.py +1 -1
- scanoss/api/common/v2/scanoss_common_pb2.py +49 -22
- scanoss/api/common/v2/scanoss_common_pb2_grpc.py +25 -0
- scanoss/api/components/v2/scanoss_components_pb2.py +68 -43
- scanoss/api/components/v2/scanoss_components_pb2_grpc.py +83 -22
- scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py +136 -47
- scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py +650 -33
- scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py +56 -37
- scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py +64 -12
- scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2.py +74 -31
- scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2_grpc.py +252 -13
- scanoss/api/licenses/__init__.py +23 -0
- scanoss/api/licenses/v2/__init__.py +23 -0
- scanoss/api/licenses/v2/scanoss_licenses_pb2.py +84 -0
- scanoss/api/licenses/v2/scanoss_licenses_pb2_grpc.py +302 -0
- scanoss/api/scanning/v2/scanoss_scanning_pb2.py +32 -21
- scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py +49 -8
- scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py +50 -23
- scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py +151 -16
- scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py +78 -31
- scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py +282 -18
- scanoss/cli.py +1000 -186
- scanoss/components.py +80 -50
- scanoss/constants.py +7 -1
- scanoss/cryptography.py +89 -55
- scanoss/csvoutput.py +13 -7
- scanoss/cyclonedx.py +141 -9
- scanoss/data/build_date.txt +1 -1
- scanoss/data/osadl-copyleft.json +133 -0
- scanoss/delta.py +197 -0
- scanoss/export/__init__.py +23 -0
- scanoss/export/dependency_track.py +227 -0
- scanoss/file_filters.py +2 -163
- scanoss/filecount.py +37 -38
- scanoss/gitlabqualityreport.py +214 -0
- scanoss/header_filter.py +563 -0
- scanoss/inspection/policy_check/__init__.py +0 -0
- scanoss/inspection/policy_check/dependency_track/__init__.py +0 -0
- scanoss/inspection/policy_check/dependency_track/project_violation.py +479 -0
- scanoss/inspection/{policy_check.py → policy_check/policy_check.py} +65 -72
- scanoss/inspection/policy_check/scanoss/__init__.py +0 -0
- scanoss/inspection/{copyleft.py → policy_check/scanoss/copyleft.py} +89 -73
- scanoss/inspection/{undeclared_component.py → policy_check/scanoss/undeclared_component.py} +52 -46
- scanoss/inspection/summary/__init__.py +0 -0
- scanoss/inspection/summary/component_summary.py +170 -0
- scanoss/inspection/{license_summary.py → summary/license_summary.py} +62 -12
- scanoss/inspection/summary/match_summary.py +341 -0
- scanoss/inspection/utils/file_utils.py +44 -0
- scanoss/inspection/utils/license_utils.py +57 -71
- scanoss/inspection/utils/markdown_utils.py +63 -0
- scanoss/inspection/{inspect_base.py → utils/scan_result_processor.py} +53 -67
- scanoss/osadl.py +125 -0
- scanoss/scanner.py +135 -253
- scanoss/scanners/folder_hasher.py +47 -32
- scanoss/scanners/scanner_hfh.py +50 -18
- scanoss/scanoss_settings.py +33 -3
- scanoss/scanossapi.py +23 -25
- scanoss/scanossbase.py +1 -1
- scanoss/scanossgrpc.py +543 -289
- scanoss/services/dependency_track_service.py +132 -0
- scanoss/spdxlite.py +11 -4
- scanoss/threadeddependencies.py +19 -18
- scanoss/threadedscanning.py +10 -0
- scanoss/utils/scanoss_scan_results_utils.py +41 -0
- scanoss/winnowing.py +71 -19
- {scanoss-1.27.1.dist-info → scanoss-1.43.1.dist-info}/METADATA +8 -5
- scanoss-1.43.1.dist-info/RECORD +110 -0
- scanoss/inspection/component_summary.py +0 -94
- scanoss-1.27.1.dist-info/RECORD +0 -87
- {scanoss-1.27.1.dist-info → scanoss-1.43.1.dist-info}/WHEEL +0 -0
- {scanoss-1.27.1.dist-info → scanoss-1.43.1.dist-info}/entry_points.txt +0 -0
- {scanoss-1.27.1.dist-info → scanoss-1.43.1.dist-info}/licenses/LICENSE +0 -0
- {scanoss-1.27.1.dist-info → scanoss-1.43.1.dist-info}/top_level.txt +0 -0
scanoss/scanner.py
CHANGED
|
@@ -26,11 +26,11 @@ import datetime
|
|
|
26
26
|
import json
|
|
27
27
|
import os
|
|
28
28
|
import sys
|
|
29
|
+
from contextlib import nullcontext
|
|
29
30
|
from pathlib import Path
|
|
30
31
|
from typing import Any, Dict, List, Optional
|
|
31
32
|
|
|
32
33
|
import importlib_resources
|
|
33
|
-
from progress.bar import Bar
|
|
34
34
|
from progress.spinner import Spinner
|
|
35
35
|
from pypac.parser import PACFile
|
|
36
36
|
|
|
@@ -71,7 +71,6 @@ class Scanner(ScanossBase):
|
|
|
71
71
|
|
|
72
72
|
def __init__( # noqa: PLR0913, PLR0915
|
|
73
73
|
self,
|
|
74
|
-
wfp: str = None,
|
|
75
74
|
scan_output: str = None,
|
|
76
75
|
output_format: str = 'plain',
|
|
77
76
|
debug: bool = False,
|
|
@@ -83,7 +82,6 @@ class Scanner(ScanossBase):
|
|
|
83
82
|
nb_threads: int = 5,
|
|
84
83
|
post_size: int = 32,
|
|
85
84
|
timeout: int = 180,
|
|
86
|
-
no_wfp_file: bool = False,
|
|
87
85
|
all_extensions: bool = False,
|
|
88
86
|
all_folders: bool = False,
|
|
89
87
|
hidden_files_folders: bool = False,
|
|
@@ -107,6 +105,9 @@ class Scanner(ScanossBase):
|
|
|
107
105
|
skip_md5_ids=None,
|
|
108
106
|
scan_settings: 'ScanossSettings | None' = None,
|
|
109
107
|
req_headers: dict = None,
|
|
108
|
+
use_grpc: bool = False,
|
|
109
|
+
skip_headers: bool = False,
|
|
110
|
+
skip_headers_limit: int = 0,
|
|
110
111
|
):
|
|
111
112
|
"""
|
|
112
113
|
Initialise scanning class, including Winnowing, ScanossApi, ThreadedScanning
|
|
@@ -116,10 +117,8 @@ class Scanner(ScanossBase):
|
|
|
116
117
|
skip_folders = []
|
|
117
118
|
if skip_extensions is None:
|
|
118
119
|
skip_extensions = []
|
|
119
|
-
self.wfp = wfp if wfp else 'scanner_output.wfp'
|
|
120
120
|
self.scan_output = scan_output
|
|
121
121
|
self.output_format = output_format
|
|
122
|
-
self.no_wfp_file = no_wfp_file
|
|
123
122
|
self.isatty = sys.stderr.isatty()
|
|
124
123
|
self.all_extensions = all_extensions
|
|
125
124
|
self.all_folders = all_folders
|
|
@@ -135,6 +134,7 @@ class Scanner(ScanossBase):
|
|
|
135
134
|
|
|
136
135
|
self.winnowing = Winnowing(
|
|
137
136
|
debug=debug,
|
|
137
|
+
trace=trace,
|
|
138
138
|
quiet=quiet,
|
|
139
139
|
skip_snippets=self._skip_snippets,
|
|
140
140
|
all_extensions=all_extensions,
|
|
@@ -143,6 +143,8 @@ class Scanner(ScanossBase):
|
|
|
143
143
|
strip_hpsm_ids=strip_hpsm_ids,
|
|
144
144
|
strip_snippet_ids=strip_snippet_ids,
|
|
145
145
|
skip_md5_ids=skip_md5_ids,
|
|
146
|
+
skip_headers=skip_headers,
|
|
147
|
+
skip_headers_limit=skip_headers_limit,
|
|
146
148
|
)
|
|
147
149
|
self.scanoss_api = ScanossApi(
|
|
148
150
|
debug=debug,
|
|
@@ -173,6 +175,8 @@ class Scanner(ScanossBase):
|
|
|
173
175
|
pac=pac,
|
|
174
176
|
grpc_proxy=grpc_proxy,
|
|
175
177
|
req_headers=self.req_headers,
|
|
178
|
+
ignore_cert_errors=ignore_cert_errors,
|
|
179
|
+
use_grpc=use_grpc
|
|
176
180
|
)
|
|
177
181
|
self.threaded_deps = ThreadedDependencies(sc_deps, grpc_api, debug=debug, quiet=quiet, trace=trace)
|
|
178
182
|
self.nb_threads = nb_threads
|
|
@@ -360,70 +364,62 @@ class Scanner(ScanossBase):
|
|
|
360
364
|
operation_type='scanning',
|
|
361
365
|
)
|
|
362
366
|
self.print_msg(f'Searching {scan_dir} for files to fingerprint...')
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
self.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
queue_size
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
if spinner:
|
|
418
|
-
spinner.finish()
|
|
367
|
+
spinner_ctx = Spinner('Fingerprinting ') if (not self.quiet and self.isatty) else nullcontext()
|
|
368
|
+
|
|
369
|
+
with spinner_ctx as spinner:
|
|
370
|
+
scan_block = ''
|
|
371
|
+
scan_size = 0
|
|
372
|
+
queue_size = 0
|
|
373
|
+
file_count = 0 # count all files fingerprinted
|
|
374
|
+
wfp_file_count = 0 # count number of files in each queue post
|
|
375
|
+
scan_started = False
|
|
376
|
+
|
|
377
|
+
to_scan_files = file_filters.get_filtered_files_from_folder(scan_dir)
|
|
378
|
+
for to_scan_file in to_scan_files:
|
|
379
|
+
if self.threaded_scan and self.threaded_scan.stop_scanning():
|
|
380
|
+
self.print_stderr('Warning: Aborting fingerprinting as the scanning service is not available.')
|
|
381
|
+
break
|
|
382
|
+
self.print_debug(f'Fingerprinting {to_scan_file}...')
|
|
383
|
+
if spinner:
|
|
384
|
+
spinner.next()
|
|
385
|
+
abs_path = Path(scan_dir, to_scan_file).resolve()
|
|
386
|
+
wfp = self.winnowing.wfp_for_file(str(abs_path), to_scan_file)
|
|
387
|
+
if wfp is None or wfp == '':
|
|
388
|
+
self.print_debug(f'No WFP returned for {to_scan_file}. Skipping.')
|
|
389
|
+
continue
|
|
390
|
+
file_count += 1
|
|
391
|
+
if self.threaded_scan:
|
|
392
|
+
wfp_size = len(wfp.encode('utf-8'))
|
|
393
|
+
# If the WFP is bigger than the max post size and we already have something
|
|
394
|
+
# stored in the scan block, add it to the queue
|
|
395
|
+
if scan_block != '' and (wfp_size + scan_size) >= self.max_post_size:
|
|
396
|
+
self.threaded_scan.queue_add(scan_block)
|
|
397
|
+
queue_size += 1
|
|
398
|
+
scan_block = ''
|
|
399
|
+
wfp_file_count = 0
|
|
400
|
+
scan_block += wfp
|
|
401
|
+
scan_size = len(scan_block.encode('utf-8'))
|
|
402
|
+
wfp_file_count += 1
|
|
403
|
+
# If the scan request block (group of WFPs) is larger than the POST size
|
|
404
|
+
# or we have reached the file limit, add it to the queue
|
|
405
|
+
if wfp_file_count > self.post_file_count or scan_size >= self.max_post_size:
|
|
406
|
+
self.threaded_scan.queue_add(scan_block)
|
|
407
|
+
queue_size += 1
|
|
408
|
+
scan_block = ''
|
|
409
|
+
wfp_file_count = 0
|
|
410
|
+
if not scan_started and queue_size > self.nb_threads: # Start scanning if we have something to do
|
|
411
|
+
scan_started = True
|
|
412
|
+
if not self.threaded_scan.run(wait=False):
|
|
413
|
+
self.print_stderr(
|
|
414
|
+
'Warning: Some errors encountered while scanning. '
|
|
415
|
+
'Results might be incomplete.'
|
|
416
|
+
)
|
|
417
|
+
success = False
|
|
418
|
+
# End for loop
|
|
419
|
+
if self.threaded_scan and scan_block != '':
|
|
420
|
+
self.threaded_scan.queue_add(scan_block) # Make sure all files have been submitted
|
|
419
421
|
|
|
420
422
|
if file_count > 0:
|
|
421
|
-
if save_wfps_for_print: # Write a WFP file if no threading is requested
|
|
422
|
-
self.print_debug(f'Writing fingerprints to {self.wfp}')
|
|
423
|
-
with open(self.wfp, 'w') as f:
|
|
424
|
-
f.write(''.join(wfp_list))
|
|
425
|
-
else:
|
|
426
|
-
self.print_debug(f'Skipping writing WFP file {self.wfp}')
|
|
427
423
|
if self.threaded_scan:
|
|
428
424
|
success = self.__run_scan_threaded(scan_started, file_count)
|
|
429
425
|
else:
|
|
@@ -628,71 +624,62 @@ class Scanner(ScanossBase):
|
|
|
628
624
|
skip_extensions=self.skip_extensions,
|
|
629
625
|
operation_type='scanning',
|
|
630
626
|
)
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
627
|
+
spinner_ctx = Spinner('Fingerprinting ') if (not self.quiet and self.isatty) else nullcontext()
|
|
628
|
+
|
|
629
|
+
with spinner_ctx as spinner:
|
|
630
|
+
scan_block = ''
|
|
631
|
+
scan_size = 0
|
|
632
|
+
queue_size = 0
|
|
633
|
+
file_count = 0 # count all files fingerprinted
|
|
634
|
+
wfp_file_count = 0 # count number of files in each queue post
|
|
635
|
+
scan_started = False
|
|
636
|
+
|
|
637
|
+
to_scan_files = file_filters.get_filtered_files_from_files(files)
|
|
638
|
+
for file in to_scan_files:
|
|
639
|
+
if self.threaded_scan and self.threaded_scan.stop_scanning():
|
|
640
|
+
self.print_stderr('Warning: Aborting fingerprinting as the scanning service is not available.')
|
|
641
|
+
break
|
|
642
|
+
self.print_debug(f'Fingerprinting {file}...')
|
|
643
|
+
if spinner:
|
|
644
|
+
spinner.next()
|
|
645
|
+
wfp = self.winnowing.wfp_for_file(file, file)
|
|
646
|
+
if wfp is None or wfp == '':
|
|
647
|
+
self.print_debug(f'No WFP returned for {file}. Skipping.')
|
|
648
|
+
continue
|
|
649
|
+
file_count += 1
|
|
650
|
+
if self.threaded_scan:
|
|
651
|
+
wfp_size = len(wfp.encode('utf-8'))
|
|
652
|
+
# If the WFP is bigger than the max post size and we already have something
|
|
653
|
+
# stored in the scan block, add it to the queue
|
|
654
|
+
if scan_block != '' and (wfp_size + scan_size) >= self.max_post_size:
|
|
655
|
+
self.threaded_scan.queue_add(scan_block)
|
|
656
|
+
queue_size += 1
|
|
657
|
+
scan_block = ''
|
|
658
|
+
wfp_file_count = 0
|
|
659
|
+
scan_block += wfp
|
|
660
|
+
scan_size = len(scan_block.encode('utf-8'))
|
|
661
|
+
wfp_file_count += 1
|
|
662
|
+
# If the scan request block (group of WFPs) is larger than the POST size
|
|
663
|
+
# or we have reached the file limit, add it to the queue
|
|
664
|
+
if wfp_file_count > self.post_file_count or scan_size >= self.max_post_size:
|
|
665
|
+
self.threaded_scan.queue_add(scan_block)
|
|
666
|
+
queue_size += 1
|
|
667
|
+
scan_block = ''
|
|
668
|
+
wfp_file_count = 0
|
|
669
|
+
if not scan_started and queue_size > self.nb_threads: # Start scanning if we have something to do
|
|
670
|
+
scan_started = True
|
|
671
|
+
if not self.threaded_scan.run(wait=False):
|
|
672
|
+
self.print_stderr(
|
|
673
|
+
'Warning: Some errors encountered while scanning. '
|
|
674
|
+
'Results might be incomplete.'
|
|
675
|
+
)
|
|
676
|
+
success = False
|
|
642
677
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
self.print_stderr('Warning: Aborting fingerprinting as the scanning service is not available.')
|
|
647
|
-
break
|
|
648
|
-
self.print_debug(f'Fingerprinting {file}...')
|
|
649
|
-
if spinner:
|
|
650
|
-
spinner.next()
|
|
651
|
-
wfp = self.winnowing.wfp_for_file(file, file)
|
|
652
|
-
if wfp is None or wfp == '':
|
|
653
|
-
self.print_debug(f'No WFP returned for {file}. Skipping.')
|
|
654
|
-
continue
|
|
655
|
-
if save_wfps_for_print:
|
|
656
|
-
wfp_list.append(wfp)
|
|
657
|
-
file_count += 1
|
|
658
|
-
if self.threaded_scan:
|
|
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 # noqa: E501
|
|
661
|
-
if scan_block != '' and (wfp_size + scan_size) >= self.max_post_size:
|
|
662
|
-
self.threaded_scan.queue_add(scan_block)
|
|
663
|
-
queue_size += 1
|
|
664
|
-
scan_block = ''
|
|
665
|
-
wfp_file_count = 0
|
|
666
|
-
scan_block += wfp
|
|
667
|
-
scan_size = len(scan_block.encode('utf-8'))
|
|
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 # noqa: E501
|
|
670
|
-
if wfp_file_count > self.post_file_count or scan_size >= self.max_post_size:
|
|
671
|
-
self.threaded_scan.queue_add(scan_block)
|
|
672
|
-
queue_size += 1
|
|
673
|
-
scan_block = ''
|
|
674
|
-
wfp_file_count = 0
|
|
675
|
-
if not scan_started and queue_size > self.nb_threads: # Start scanning if we have something to do
|
|
676
|
-
scan_started = True
|
|
677
|
-
if not self.threaded_scan.run(wait=False):
|
|
678
|
-
self.print_stderr(
|
|
679
|
-
'Warning: Some errors encounted while scanning. Results might be incomplete.'
|
|
680
|
-
)
|
|
681
|
-
success = False
|
|
682
|
-
|
|
683
|
-
# End for loop
|
|
684
|
-
if self.threaded_scan and scan_block != '':
|
|
685
|
-
self.threaded_scan.queue_add(scan_block) # Make sure all files have been submitted
|
|
686
|
-
if spinner:
|
|
687
|
-
spinner.finish()
|
|
678
|
+
# End for loop
|
|
679
|
+
if self.threaded_scan and scan_block != '':
|
|
680
|
+
self.threaded_scan.queue_add(scan_block) # Make sure all files have been submitted
|
|
688
681
|
|
|
689
682
|
if file_count > 0:
|
|
690
|
-
if save_wfps_for_print: # Write a WFP file if no threading is requested
|
|
691
|
-
self.print_debug(f'Writing fingerprints to {self.wfp}')
|
|
692
|
-
with open(self.wfp, 'w') as f:
|
|
693
|
-
f.write(''.join(wfp_list))
|
|
694
|
-
else:
|
|
695
|
-
self.print_debug(f'Skipping writing WFP file {self.wfp}')
|
|
696
683
|
if self.threaded_scan:
|
|
697
684
|
success = self.__run_scan_threaded(scan_started, file_count)
|
|
698
685
|
else:
|
|
@@ -755,125 +742,22 @@ class Scanner(ScanossBase):
|
|
|
755
742
|
success = False
|
|
756
743
|
return success
|
|
757
744
|
|
|
758
|
-
def
|
|
759
|
-
"""
|
|
760
|
-
Scan the contents of the specified WFP file (in the current process)
|
|
761
|
-
:param file: Scan the contents of the specified WFP file (in the current process)
|
|
762
|
-
:return: True if successful, False otherwise
|
|
763
|
-
"""
|
|
764
|
-
success = True
|
|
765
|
-
wfp_file = file if file else self.wfp # If a WFP file is specified, use it, otherwise us the default
|
|
766
|
-
if not os.path.exists(wfp_file) or not os.path.isfile(wfp_file):
|
|
767
|
-
raise Exception(f'ERROR: Specified WFP file does not exist or is not a file: {wfp_file}')
|
|
768
|
-
file_count = Scanner.__count_files_in_wfp_file(wfp_file)
|
|
769
|
-
cur_files = 0
|
|
770
|
-
cur_size = 0
|
|
771
|
-
batch_files = 0
|
|
772
|
-
wfp = ''
|
|
773
|
-
max_component = {'name': '', 'hits': 0}
|
|
774
|
-
components = {}
|
|
775
|
-
self.print_debug(f'Found {file_count} files to process.')
|
|
776
|
-
raw_output = '{\n'
|
|
777
|
-
file_print = ''
|
|
778
|
-
bar = None
|
|
779
|
-
if not self.quiet and self.isatty:
|
|
780
|
-
bar = Bar('Scanning', max=file_count)
|
|
781
|
-
bar.next(0)
|
|
782
|
-
with open(wfp_file) as f:
|
|
783
|
-
for line in f:
|
|
784
|
-
if line.startswith(WFP_FILE_START):
|
|
785
|
-
if file_print:
|
|
786
|
-
wfp += file_print # Store the WFP for the current file
|
|
787
|
-
cur_size = len(wfp.encode('utf-8'))
|
|
788
|
-
file_print = line # Start storing the next file
|
|
789
|
-
cur_files += 1
|
|
790
|
-
batch_files += 1
|
|
791
|
-
else:
|
|
792
|
-
file_print += line # Store the rest of the WFP for this file
|
|
793
|
-
l_size = cur_size + len(file_print.encode('utf-8'))
|
|
794
|
-
# Hit the max post size, so sending the current batch and continue processing
|
|
795
|
-
if l_size >= self.max_post_size and wfp:
|
|
796
|
-
self.print_debug(
|
|
797
|
-
f'Sending {batch_files} ({cur_files}) of'
|
|
798
|
-
f' {file_count} ({len(wfp.encode("utf-8"))} bytes) files to the ScanOSS API.'
|
|
799
|
-
)
|
|
800
|
-
if self.debug and cur_size > self.max_post_size:
|
|
801
|
-
Scanner.print_stderr(f'Warning: Post size {cur_size} greater than limit {self.max_post_size}')
|
|
802
|
-
scan_resp = self.scanoss_api.scan(wfp, max_component['name']) # Scan current WFP and store
|
|
803
|
-
if bar:
|
|
804
|
-
bar.next(batch_files)
|
|
805
|
-
if scan_resp is not None:
|
|
806
|
-
for key, value in scan_resp.items():
|
|
807
|
-
raw_output += ' "%s":%s,' % (key, json.dumps(value, indent=2))
|
|
808
|
-
for v in value:
|
|
809
|
-
if hasattr(v, 'get'):
|
|
810
|
-
if v.get('id') != 'none':
|
|
811
|
-
vcv = '%s:%s:%s' % (v.get('vendor'), v.get('component'), v.get('version'))
|
|
812
|
-
components[vcv] = components[vcv] + 1 if vcv in components else 1
|
|
813
|
-
if max_component['hits'] < components[vcv]:
|
|
814
|
-
max_component['name'] = v.get('component')
|
|
815
|
-
max_component['hits'] = components[vcv]
|
|
816
|
-
else:
|
|
817
|
-
Scanner.print_stderr(f'Warning: Unknown value: {v}')
|
|
818
|
-
else:
|
|
819
|
-
success = False
|
|
820
|
-
batch_files = 0
|
|
821
|
-
wfp = ''
|
|
822
|
-
if file_print:
|
|
823
|
-
wfp += file_print # Store the WFP for the current file
|
|
824
|
-
if wfp:
|
|
825
|
-
self.print_debug(
|
|
826
|
-
f'Sending {batch_files} ({cur_files}) of'
|
|
827
|
-
f' {file_count} ({len(wfp.encode("utf-8"))} bytes) files to the ScanOSS API.'
|
|
828
|
-
)
|
|
829
|
-
scan_resp = self.scanoss_api.scan(wfp, max_component['name']) # Scan current WFP and store
|
|
830
|
-
if bar:
|
|
831
|
-
bar.next(batch_files)
|
|
832
|
-
first = True
|
|
833
|
-
if scan_resp is not None:
|
|
834
|
-
for key, value in scan_resp.items():
|
|
835
|
-
if first:
|
|
836
|
-
raw_output += ' "%s":%s' % (key, json.dumps(value, indent=2))
|
|
837
|
-
first = False
|
|
838
|
-
else:
|
|
839
|
-
raw_output += ',\n "%s":%s' % (key, json.dumps(value, indent=2))
|
|
840
|
-
else:
|
|
841
|
-
success = False
|
|
842
|
-
raw_output += '\n}'
|
|
843
|
-
if bar:
|
|
844
|
-
bar.finish()
|
|
845
|
-
if self.output_format == 'plain':
|
|
846
|
-
self.__log_result(raw_output)
|
|
847
|
-
elif self.output_format == 'cyclonedx':
|
|
848
|
-
cdx = CycloneDx(self.debug, self.scan_output)
|
|
849
|
-
cdx.produce_from_str(raw_output)
|
|
850
|
-
elif self.output_format == 'spdxlite':
|
|
851
|
-
spdxlite = SpdxLite(self.debug, self.scan_output)
|
|
852
|
-
success = spdxlite.produce_from_str(raw_output)
|
|
853
|
-
elif self.output_format == 'csv':
|
|
854
|
-
csvo = CsvOutput(self.debug, self.scan_output)
|
|
855
|
-
csvo.produce_from_str(raw_output)
|
|
856
|
-
else:
|
|
857
|
-
self.print_stderr(f'ERROR: Unknown output format: {self.output_format}')
|
|
858
|
-
success = False
|
|
859
|
-
|
|
860
|
-
return success
|
|
861
|
-
|
|
862
|
-
def scan_wfp_with_options(self, wfp: str, deps_file: str, file_map: dict = None) -> bool:
|
|
745
|
+
def scan_wfp_with_options(self, wfp_file: str, deps_file: str, file_map: dict = None) -> bool:
|
|
863
746
|
"""
|
|
864
747
|
Scan the given WFP file for whatever scaning options that have been configured
|
|
865
|
-
:param
|
|
748
|
+
:param wfp_file: WFP file to scan
|
|
866
749
|
:param deps_file: pre-parsed dependency file to decorate
|
|
867
750
|
:param file_map: mapping of obfuscated files back into originals
|
|
868
751
|
:return: True if successful, False otherwise
|
|
869
752
|
"""
|
|
870
753
|
success = True
|
|
871
|
-
|
|
754
|
+
if not wfp_file:
|
|
755
|
+
raise Exception('ERROR: Please specify a WFP file to scan')
|
|
872
756
|
if not os.path.exists(wfp_file) or not os.path.isfile(wfp_file):
|
|
873
757
|
raise Exception(f'ERROR: Specified WFP file does not exist or is not a file: {wfp_file}')
|
|
874
758
|
|
|
875
759
|
if not self.is_file_or_snippet_scan() and not self.is_dependency_scan():
|
|
876
|
-
raise Exception(f'ERROR: No scan options defined to scan WFP: {
|
|
760
|
+
raise Exception(f'ERROR: No scan options defined to scan WFP: {wfp_file}')
|
|
877
761
|
|
|
878
762
|
if self.scan_output:
|
|
879
763
|
self.print_msg(f'Writing results to {self.scan_output}...')
|
|
@@ -888,14 +772,15 @@ class Scanner(ScanossBase):
|
|
|
888
772
|
success = False
|
|
889
773
|
return success
|
|
890
774
|
|
|
891
|
-
def scan_wfp_file_threaded(self,
|
|
775
|
+
def scan_wfp_file_threaded(self, wfp_file: str) -> bool: # noqa: PLR0912
|
|
892
776
|
"""
|
|
893
777
|
Scan the contents of the specified WFP file (threaded)
|
|
894
|
-
:param
|
|
778
|
+
:param wfp_file: WFP file to scan
|
|
895
779
|
return: True if successful, False otherwise
|
|
896
780
|
"""
|
|
897
781
|
success = True
|
|
898
|
-
|
|
782
|
+
if not wfp_file:
|
|
783
|
+
raise Exception('ERROR: Please specify a WFP file to scan')
|
|
899
784
|
if not os.path.exists(wfp_file) or not os.path.isfile(wfp_file):
|
|
900
785
|
raise Exception(f'ERROR: Specified WFP file does not exist or is not a file: {wfp_file}')
|
|
901
786
|
cur_size = 0
|
|
@@ -1049,19 +934,16 @@ class Scanner(ScanossBase):
|
|
|
1049
934
|
)
|
|
1050
935
|
wfps = ''
|
|
1051
936
|
self.print_msg(f'Searching {scan_dir} for files to fingerprint...')
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
wfps += self.winnowing.wfp_for_file(str(abs_path), file)
|
|
1063
|
-
if spinner:
|
|
1064
|
-
spinner.finish()
|
|
937
|
+
spinner_ctx = Spinner('Fingerprinting ') if (not self.quiet and self.isatty) else nullcontext()
|
|
938
|
+
|
|
939
|
+
with spinner_ctx as spinner:
|
|
940
|
+
to_fingerprint_files = file_filters.get_filtered_files_from_folder(scan_dir)
|
|
941
|
+
for file in to_fingerprint_files:
|
|
942
|
+
if spinner:
|
|
943
|
+
spinner.next()
|
|
944
|
+
abs_path = Path(scan_dir, file).resolve()
|
|
945
|
+
self.print_debug(f'Fingerprinting {file}...')
|
|
946
|
+
wfps += self.winnowing.wfp_for_file(str(abs_path), file)
|
|
1065
947
|
if wfps:
|
|
1066
948
|
if wfp_file:
|
|
1067
949
|
self.print_stderr(f'Writing fingerprints to {wfp_file}')
|