@@ -18,7 +18,7 @@ class Messages:
1818 def map_severity_to_sarif (severity : str ) -> str :
1919 """
2020 Map Socket severity levels to SARIF levels (GitHub code scanning).
21-
21+
2222 'low' -> 'note'
2323 'medium' or 'middle' -> 'warning'
2424 'high' or 'critical' -> 'error'
@@ -37,31 +37,35 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str)
3737 """
3838 Finds the line number and snippet of code for the given package/version in a manifest file.
3939 Returns a 2-tuple: (line_number, snippet_or_message).
40+
41+ Supports:
42+ 1) JSON-based manifest files (package-lock.json, Pipfile.lock, composer.lock)
43+ - Locates a dictionary entry with the matching package & version
44+ - Does a rough line-based search to find the actual line in the raw text
45+ 2) Text-based (requirements.txt, package.json, yarn.lock, etc.)
46+ - Uses compiled regex patterns to detect a match line by line
4047 """
48+ # Extract just the file name to detect manifest type
4149 file_type = Path (manifest_file ).name
42- logging .debug ("Processing manifest file: %s" , manifest_file )
43-
50+ logging .debug ("Processing file: %s" , manifest_file )
51+
4452 # ----------------------------------------------------
4553 # 1) JSON-based manifest files
4654 # ----------------------------------------------------
4755 if file_type in ["package-lock.json" , "Pipfile.lock" , "composer.lock" ]:
4856 try :
4957 with open (manifest_file , "r" , encoding = "utf-8" ) as f :
5058 raw_text = f .read ()
51- logging .debug ("Raw text length: %d" , len (raw_text ))
52- try :
53- data = json .loads (raw_text )
54- except json .JSONDecodeError :
55- data = {}
56- logging .debug ("JSON decode failed for %s" , manifest_file )
57-
59+ logging .debug ("Read %d characters from %s" , len (raw_text ), manifest_file )
60+ data = json .loads (raw_text )
5861 packages_dict = (
5962 data .get ("packages" )
6063 or data .get ("default" )
6164 or data .get ("dependencies" )
6265 or {}
6366 )
64- logging .debug ("Packages dict keys: %s" , list (packages_dict .keys ()))
67+ logging .debug ("Found package keys: %s" , list (packages_dict .keys ()))
68+
6569 found_key = None
6670 found_info = None
6771 for key , value in packages_dict .items ():
@@ -75,17 +79,18 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str)
7579 needle_key = f'"{ found_key } ":'
7680 needle_version = f'"version": "{ packageversion } "'
7781 lines = raw_text .splitlines ()
78- logging .debug ("Total lines: %d" , len (lines ))
82+ logging .debug ("Total lines in %s : %d" , manifest_file , len (lines ))
7983 for i , line in enumerate (lines , start = 1 ):
8084 if (needle_key in line ) or (needle_version in line ):
81- logging .debug ("Found match at line %d: %s" , i , line .strip ())
85+ logging .debug ("Match found at line %d in %s : %s" , i , manifest_file , line .strip ())
8286 return i , line .strip ()
8387 return 1 , f'"{ found_key } ": { found_info } '
8488 else :
8589 return 1 , f"{ packagename } { packageversion } (not found in { manifest_file } )"
86- except (FileNotFoundError , json .JSONDecodeError ):
90+ except (FileNotFoundError , json .JSONDecodeError ) as e :
91+ logging .error ("Error reading JSON from %s: %s" , manifest_file , e )
8792 return 1 , f"Error reading { manifest_file } "
88-
93+
8994 # ----------------------------------------------------
9095 # 2) Text-based / line-based manifests
9196 # ----------------------------------------------------
@@ -123,7 +128,7 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str)
123128 for line_number , line_content in enumerate (lines , start = 1 ):
124129 line_main = line_content .split (";" , 1 )[0 ].strip ()
125130 if re .search (searchstring , line_main , re .IGNORECASE ):
126- logging .debug ("Match found in %s at line %d: %s" , manifest_file , line_number , line_content .strip ())
131+ logging .debug ("Match found at line %d in %s : %s" , line_number , manifest_file , line_content .strip ())
127132 return line_number , line_content .strip ()
128133 except FileNotFoundError :
129134 return 1 , f"{ manifest_file } not found"
@@ -167,7 +172,7 @@ def create_security_comment_sarif(diff) -> dict:
167172 """
168173 Create SARIF-compliant output from the diff report, including dynamic URL generation
169174 based on manifest type and improved <br/> formatting for GitHub SARIF display.
170-
175+
171176 This function now:
172177 - Accepts multiple manifest files from alert.introduced_by or alert.manifests.
173178 - Generates one SARIF location per manifest file.
@@ -216,12 +221,12 @@ def create_security_comment_sarif(diff) -> dict:
216221 logging .debug ("Alert %s manifest_files before fallback: %s" , rule_id , manifest_files )
217222 if not manifest_files :
218223 manifest_files = ["requirements.txt" ]
219- logging .debug ("Alert %s: Falling back to manifest_files : %s" , rule_id , manifest_files )
224+ logging .debug ("Alert %s falling back to: %s" , rule_id , manifest_files )
220225
221- logging .debug ("Alert %s: Using manifest_file for URL: %s" , rule_id , manifest_files [0 ])
226+ logging .debug ("Alert %s using manifest_file for URL: %s" , rule_id , manifest_files [0 ])
222227 socket_url = Messages .get_manifest_type_url (manifest_files [0 ], pkg_name , pkg_version )
223228 short_desc = (f"{ alert .props .get ('note' , '' )} <br/><br/>Suggested Action:<br/>{ alert .suggestion } "
224- f"<br/><a href=\" { socket_url } \" >{ socket_url } </a>" )
229+ f"<br/><a href=\" { socket_url } \" >{ socket_url } </a>" )
225230 full_desc = "{} - {}" .format (alert .title , alert .description .replace ('\r \n ' , '<br/>' ))
226231
227232 if rule_id not in rules_map :
@@ -241,7 +246,7 @@ def create_security_comment_sarif(diff) -> dict:
241246 for mf in manifest_files :
242247 line_number , line_content = Messages .find_line_in_file (pkg_name , pkg_version , mf )
243248 if line_number < 1 :
244- line_number = 1
249+ line_number = 1 # Ensure SARIF compliance.
245250 logging .debug ("Alert %s: Manifest %s, line %d: %s" , rule_id , mf , line_number , line_content )
246251 locations .append ({
247252 "physicalLocation" : {
@@ -264,7 +269,7 @@ def create_security_comment_sarif(diff) -> dict:
264269 sarif_data ["runs" ][0 ]["results" ] = results_list
265270
266271 return sarif_data
267-
272+
268273 @staticmethod
269274 def create_security_comment_json (diff : Diff ) -> dict :
270275 scan_failed = False
0 commit comments