@@ -78,19 +78,25 @@ def analyze(self, analysis: Analysis) -> list[AnalysisResult]:
7878 def results (self ) -> AnalysisResults :
7979 return AnalysisResults (pickled = self .pickled , results = self .previous_results )
8080
81- def shorten_code (self , ast_node ) -> tuple [str , bool ]:
81+ def shorten_code (self , ast_node ) -> str :
82+ """Return a short, human-readable form of an AST node for use in
83+ analysis messages. Pure formatter — does not touch dedup state.
84+ """
8285 code = unparse (ast_node ).strip ()
8386 if len (code ) > 32 :
8487 cutoff = code .find ("(" )
85- if code [cutoff ] == "(" :
86- shortened_code = f"{ code [: code .find ('(' )].strip ()} (...)"
87- else :
88- shortened_code = code
89- else :
90- shortened_code = code
91- was_already_reported = shortened_code in self .reported_shortened_code
92- self .reported_shortened_code .add (shortened_code )
93- return shortened_code , was_already_reported
88+ if cutoff >= 0 :
89+ return f"{ code [:cutoff ].strip ()} (...)"
90+ return code
91+
92+ def mark_reported (self , shortened : str ) -> bool :
93+ """Mark a shortened code fragment as reported. Returns True if
94+ this was the first mark, False if a prior call already marked it.
95+ """
96+ if shortened in self .reported_shortened_code :
97+ return False
98+ self .reported_shortened_code .add (shortened )
99+ return True
94100
95101
96102class Analyzer (metaclass = AnalyzerMeta ):
@@ -255,8 +261,8 @@ def analyze(self, context: AnalysisContext) -> Iterator[AnalysisResult]:
255261class NonStandardImports (Analysis ):
256262 def analyze (self , context : AnalysisContext ) -> Iterator [AnalysisResult ]:
257263 for node in context .pickled .non_standard_imports ():
258- shortened , already_reported = context .shorten_code (node )
259- if not already_reported :
264+ shortened = context .shorten_code (node )
265+ if context . mark_reported ( shortened ) :
260266 yield AnalysisResult (
261267 Severity .LIKELY_UNSAFE ,
262268 f"`{ shortened } ` imports a Python module that is not a part of "
@@ -324,7 +330,7 @@ class UnsafeImportsML(Analysis):
324330
325331 def analyze (self , context : AnalysisContext ) -> Iterator [AnalysisResult ]:
326332 for node in context .pickled .properties .imports :
327- shortened , _ = context .shorten_code (node )
333+ shortened = context .shorten_code (node )
328334 all_modules = [
329335 node .module .rsplit ("." , i )[0 ] for i in range (0 , node .module .count ("." ) + 1 )
330336 ]
@@ -377,7 +383,7 @@ class BadCalls(Analysis):
377383
378384 def analyze (self , context : AnalysisContext ) -> Iterator [AnalysisResult ]:
379385 for node in context .pickled .properties .calls :
380- shortened , _already_reported = context .shorten_code (node )
386+ shortened = context .shorten_code (node )
381387 if any (shortened .startswith (f"{ c } (" ) for c in self .BAD_CALLS ):
382388 yield AnalysisResult (
383389 Severity .OVERTLY_MALICIOUS ,
@@ -397,7 +403,7 @@ def analyze(self, context: AnalysisContext) -> Iterator[AnalysisResult]:
397403 # if the call is to a constructor of an object imported from the Python
398404 # standard library, it's probably okay
399405 continue
400- shortened , already_reported = context .shorten_code (node )
406+ shortened = context .shorten_code (node )
401407 if (
402408 shortened .startswith ("eval(" )
403409 or shortened .startswith ("exec(" )
@@ -413,7 +419,7 @@ def analyze(self, context: AnalysisContext) -> Iterator[AnalysisResult]:
413419 "OvertlyBadEval" ,
414420 trigger = shortened ,
415421 )
416- elif not already_reported :
422+ elif context . mark_reported ( shortened ) :
417423 yield AnalysisResult (
418424 Severity .LIKELY_UNSAFE ,
419425 f"Call to `{ shortened } ` can execute arbitrary code and is inherently unsafe" ,
@@ -429,7 +435,7 @@ def analyze(self, context: AnalysisContext) -> Iterator[AnalysisResult]:
429435 n .name in SAFE_BUILTINS for n in node .names
430436 ):
431437 continue
432- shortened , _ = context .shorten_code (node )
438+ shortened = context .shorten_code (node )
433439 yield AnalysisResult (
434440 Severity .LIKELY_OVERTLY_MALICIOUS ,
435441 f"`{ shortened } ` is suspicious and indicative of an overtly malicious pickle file" ,
@@ -447,7 +453,7 @@ def analyze(self, context: AnalysisContext) -> Iterator[AnalysisResult]:
447453 # Malformed pickle or resource exhaustion - dedicated analyses will report this
448454 return
449455 for varname , asmt in unused .items ():
450- shortened , _ = context .shorten_code (asmt .value )
456+ shortened = context .shorten_code (asmt .value )
451457 yield AnalysisResult (
452458 Severity .SUSPICIOUS ,
453459 f"Variable `{ varname } ` is assigned value `{ shortened } ` but unused afterward; "
0 commit comments