11
11
12
12
from macaron .database .db_custom_types import DBJsonDict
13
13
from macaron .database .table_definitions import CheckFacts
14
- from macaron .errors import ConfigurationError , HeuristicAnalyzerValueError
14
+ from macaron .errors import ConfigurationError , HeuristicAnalyzerValueError , SourceCodeError
15
15
from macaron .json_tools import JsonType , json_extract
16
16
from macaron .malware_analyzer .pypi_heuristics .base_analyzer import BaseHeuristicAnalyzer
17
17
from macaron .malware_analyzer .pypi_heuristics .heuristics import HeuristicResult , Heuristics
@@ -282,27 +282,45 @@ def _should_skip(
282
282
return True
283
283
return False
284
284
285
- def analyze_source (self , pypi_package_json : PyPIPackageJsonAsset ) -> tuple [HeuristicResult , dict [str , JsonType ]]:
285
+ def analyze_source (
286
+ self , pypi_package_json : PyPIPackageJsonAsset , results : dict [Heuristics , HeuristicResult ]
287
+ ) -> tuple [HeuristicResult , dict [str , JsonType ]]:
286
288
"""Analyze the source code of the package with a textual scan, looking for malicious code patterns.
287
289
288
290
Parameters
289
291
----------
290
292
pypi_package_json: PyPIPackageJsonAsset
291
293
The PyPI package JSON asset object.
294
+ results: dict[Heuristics, HeuristicResult]
295
+ Containing all heuristics' results (excluding this one), where the key is the heuristic and the value is the result
296
+ associated with that heuristic.
292
297
293
298
Returns
294
299
-------
295
300
tuple[HeuristicResult, dict[str, JsonType]]
296
301
Containing the analysis results and relevant patterns identified.
302
+
303
+ Raises
304
+ ------
305
+ HeuristicAnalyzerValueError
306
+ If the analyzer fails due to malformed package information.
307
+ ConfigurationError
308
+ If the configuration of the analyzer encountered a problem.
297
309
"""
298
310
logger .debug ("Instantiating %s" , PyPISourcecodeAnalyzer .__name__ )
299
- try :
300
- sourcecode_analyzer = PyPISourcecodeAnalyzer ()
301
- return sourcecode_analyzer .analyze (pypi_package_json )
302
- except (ConfigurationError , HeuristicAnalyzerValueError ) as source_code_error :
303
- logger .debug ("Unable to perform source code analysis: %s" , source_code_error )
311
+ analyzer = PyPISourcecodeAnalyzer ()
312
+
313
+ if analyzer .depends_on and self ._should_skip (results , analyzer .depends_on ):
304
314
return HeuristicResult .SKIP , {}
305
315
316
+ try :
317
+ with pypi_package_json .sourcecode ():
318
+ return analyzer .analyze (pypi_package_json )
319
+ except SourceCodeError as error :
320
+ error_msg = f"Unable to perform analysis, source code not available: { error } "
321
+ logger .debug (error_msg )
322
+ raise HeuristicAnalyzerValueError (error_msg ) from error
323
+
306
324
def run_heuristics (
307
325
self , pypi_package_json : PyPIPackageJsonAsset
308
326
) -> tuple [dict [Heuristics , HeuristicResult ], dict [str , JsonType ]]:
@@ -428,9 +446,15 @@ def run_check(self, ctx: AnalyzeContext) -> CheckResultData:
428
446
confidence = Confidence .HIGH
429
447
result_type = CheckResultType .PASSED
430
448
431
- # experimental analyze sourcecode feature
432
- if ctx .dynamic_data ["analyze_source" ] and pypi_package_json .download_sourcecode ():
433
- sourcecode_result , sourcecode_detail_info = self .analyze_source (pypi_package_json )
449
+ # experimental sourcecode analysis feature
450
+ if ctx .dynamic_data ["analyze_source" ]:
451
+ try :
452
+ sourcecode_result , sourcecode_detail_info = self .analyze_source (
453
+ pypi_package_json , heuristic_results
454
+ )
455
+ except (HeuristicAnalyzerValueError , ConfigurationError ):
456
+ return CheckResultData (result_tables = [], result_type = CheckResultType .UNKNOWN )
457
+
434
458
heuristic_results [Heuristics .SUSPICIOUS_PATTERNS ] = sourcecode_result
435
459
heuristics_detail_info .update (sourcecode_detail_info )
436
460
@@ -440,8 +464,6 @@ def run_check(self, ctx: AnalyzeContext) -> CheckResultData:
440
464
confidence = Confidence .LOW
441
465
result_type = CheckResultType .FAILED
442
466
443
- pypi_package_json .cleanup_sourcecode ()
444
-
445
467
result_tables .append (
446
468
MaliciousMetadataFacts (
447
469
result = heuristic_results ,
0 commit comments