@@ -41,11 +41,10 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str)
41
41
Supports:
42
42
1) JSON-based manifest files (package-lock.json, Pipfile.lock, composer.lock)
43
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
44
+ - Does a rough line-based search (by matching the key) in the raw text
45
45
2) Text-based (requirements.txt, package.json, yarn.lock, etc.)
46
46
- Uses compiled regex patterns to detect a match line by line
47
47
"""
48
- # Extract just the file name to detect manifest type
49
48
file_type = Path (manifest_file ).name
50
49
logging .debug ("Processing file for line lookup: %s" , manifest_file )
51
50
@@ -68,20 +67,21 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str)
68
67
found_key = None
69
68
found_info = None
70
69
for key , value in packages_dict .items ():
70
+ # For NPM package-lock, keys might look like "node_modules/axios"
71
71
if key .endswith (packagename ) and "version" in value :
72
72
if value ["version" ] == packageversion :
73
73
found_key = key
74
74
found_info = value
75
75
break
76
76
77
77
if found_key and found_info :
78
+ # Only use the found key to locate the line
78
79
needle_key = f'"{ found_key } ":'
79
- needle_version = f'"version": "{ packageversion } "'
80
80
lines = raw_text .splitlines ()
81
81
logging .debug ("Total lines in %s: %d" , manifest_file , len (lines ))
82
82
for i , line in enumerate (lines , start = 1 ):
83
- if ( needle_key in line ) or ( needle_version in line ) :
84
- logging .debug ("Found match at line %d in %s: %s" , i , manifest_file , line .strip ())
83
+ if needle_key in line :
84
+ logging .debug ("Match found at line %d in %s: %s" , i , manifest_file , line .strip ())
85
85
return i , line .strip ()
86
86
return 1 , f'"{ found_key } ": { found_info } '
87
87
else :
@@ -94,7 +94,6 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str)
94
94
# 2) Text-based / line-based manifests
95
95
# ----------------------------------------------------
96
96
search_patterns = {
97
- # Updated pattern for package.json to allow optional '^' or '~'
98
97
"package.json" : rf'"{ packagename } ":\s*"[\^~]?{ re .escape (packageversion )} "' ,
99
98
"yarn.lock" : rf'{ packagename } @{ packageversion } ' ,
100
99
"pnpm-lock.yaml" : rf'"{ re .escape (packagename )} "\s*:\s*\{{[^}}]*"version":\s*"{ re .escape (packageversion )} "' ,
@@ -226,10 +225,9 @@ def create_security_comment_sarif(diff) -> dict:
226
225
227
226
if not manifest_files :
228
227
logging .error ("Alert %s: No manifest file found; cannot determine file location." , rule_id )
229
- continue # Skip this alert if no manifest is provided
228
+ continue
230
229
231
230
logging .debug ("Alert %s - using manifest_files for processing: %s" , rule_id , manifest_files )
232
-
233
231
# Use the first manifest for URL generation.
234
232
logging .debug ("Alert %s - Using file for URL generation: %s" , rule_id , manifest_files [0 ])
235
233
socket_url = Messages .get_manifest_type_url (manifest_files [0 ], pkg_name , pkg_version )
@@ -255,7 +253,7 @@ def create_security_comment_sarif(diff) -> dict:
255
253
logging .debug ("Alert %s - Processing manifest file: %s" , rule_id , mf )
256
254
line_number , line_content = Messages .find_line_in_file (pkg_name , pkg_version , mf )
257
255
if line_number < 1 :
258
- line_number = 1 # Ensure SARIF compliance.
256
+ line_number = 1
259
257
logging .debug ("Alert %s: Manifest %s, line %d: %s" , rule_id , mf , line_number , line_content )
260
258
locations .append ({
261
259
"physicalLocation" : {
0 commit comments