1- from  guarddog .analyzer .metadata .detector  import  Detector 
21from  abc  import  abstractmethod 
3- from  typing  import  Optional 
4- import  os 
5- from  functools  import  reduce 
2+ import  hashlib 
63import  logging 
4+ import  os 
5+ from  typing  import  Optional 
6+ 
7+ from  guarddog .analyzer .metadata .detector  import  Detector 
78
89log  =  logging .getLogger ("guarddog" )
910
@@ -28,22 +29,41 @@ def detect(
2829        name : Optional [str ] =  None ,
2930        version : Optional [str ] =  None ,
3031    ) ->  tuple [bool , str ]:
32+         def  format_file (file : str , kind : str ) ->  str :
33+             return  f"{ file } { kind }  
34+ 
35+         def  sha256 (file : str ) ->  str :
36+             with  open (file , "rb" ) as  f :
37+                 hasher  =  hashlib .sha256 ()
38+                 while  (chunk  :=  f .read (4096 )):
39+                     hasher .update (chunk )
40+                 return  hasher .hexdigest ()
3141
3242        log .debug (
3343            f"Running bundled binary heuristic on package { name } { version }  
3444        )
3545        if  not  path :
3646            raise  ValueError ("path is needed to run heuristic "  +  self .get_name ())
3747
38-         bin_files  =  [] 
48+         bin_files  =  {} 
3949        for  root , _ , files  in  os .walk (path ):
4050            for  f  in  files :
41-                 kind  =  self .is_binary (os .path .join (root , f ))
51+                 path  =  os .path .join (root , f )
52+                 kind  =  self .is_binary (path )
4253                if  kind :
43-                     bin_files .append (f"{ f } { kind }  )
44-         if  bin_files :
45-             return  True , "Binary file/s detected in package: "  +  reduce (lambda  x , y : f"{ x } { y }  , bin_files )
46-         return  False , "" 
54+                     digest  =  sha256 (path )
55+                     if  digest  not  in bin_files :
56+                         bin_files [digest ] =  [format_file (f , kind )]
57+                     else :
58+                         bin_files [digest ].append (format_file (f , kind ))
59+ 
60+         if  not  bin_files :
61+             return  False , "" 
62+ 
63+         output_lines  =  '\n ' .join (
64+             f"{ digest } { ', ' .join (files )}   for  digest , files  in  bin_files .items ()
65+         )
66+         return  True , f"Binary file/s detected in package:\n { output_lines }  
4767
4868    def  is_binary (self , path : str ) ->  Optional [str ]:
4969        max_head  =  len (max (self .magic_bytes .values ()))
0 commit comments