Deeps-2005/java-ssl-scanner
0
1import subprocess
2import tempfile
3import os
4import re # Import re for parsing patch logs
5
6def patch_java_code(code: str) -> dict:
7 """
8 Runs AutoPatcher.java against the provided Java code using AST patching
9 and returns a dict with both the patched code and patch logs.
10 """
11 java_file_path = None
12 try:
13 # Robust line ending normalization:
14 # Split by any combination of CR/LF and then join back with only LF.
15 normalized_code = '\n'.join(code.splitlines())
16
17 with tempfile.NamedTemporaryFile(delete=False, suffix=".java", mode="w", encoding="utf-8") as temp_file:
18 temp_file.write(normalized_code) # Write the normalized code
19 java_file_path = temp_file.name
20
21 base_path = os.path.abspath(os.path.dirname(__file__))
22 javaparser_jar = os.path.join(base_path, "..", "java_analyzer", "javaparser-core-3.26.4.jar")
23 patcher_classpath = os.path.join(base_path, "..", "java_analyzer")
24
25 result = subprocess.run(
26 [
27 "java",
28 "-cp",
29 f"{patcher_classpath}{os.pathsep}{javaparser_jar}",
30 "AutoPatcher",
31 java_file_path
32 ],
33 stdout=subprocess.PIPE,
34 stderr=subprocess.PIPE, # Capture stderr for patch logs
35 text=True,
36 check=True
37 )
38
39 # The AutoPatcher's stdout contains the patched code.
40 # Its stderr contains the patch logs, delimited by "--- PATCH LOG START ---" and "--- PATCH LOG END ---".
41
42 patched_code = result.stdout.strip()
43 raw_patch_logs = result.stderr.strip()
44
45 parsed_patch_logs = []
46 log_start_match = re.search(r"--- PATCH LOG START ---\n", raw_patch_logs)
47 log_end_match = re.search(r"\n--- PATCH LOG END ---", raw_patch_logs)
48
49 if log_start_match and log_end_match:
50 log_content = raw_patch_logs[log_start_match.end():log_end_match.start()].strip()
51 for log_line in log_content.splitlines():
52 log_match = re.match(r"Line (\d+): (.*)", log_line)
53 if log_match:
54 line_num = int(log_match.group(1))
55 message = log_match.group(2)
56 parsed_patch_logs.append({"line": line_num, "message": message})
57
58 return {
59 "patched_code": patched_code,
60 "patch_logs": parsed_patch_logs
61 }
62 except subprocess.CalledProcessError as e:
63 return {
64 "patched_code": "",
65 "patch_logs": [],
66 "error": f"AutoPatcher execution failed. Stderr: {e.stderr.strip()}"
67 }
68 except FileNotFoundError as e:
69 return {
70 "patched_code": "",
71 "patch_logs": [],
72 "error": f"Java or AutoPatcher dependencies not found. Ensure JDK is installed and JARs are in 'java_analyzer' directory. Error: {str(e)}"
73 }
74 except Exception as e:
75 return {
76 "patched_code": "",
77 "patch_logs": [],
78 "error": f"An unexpected error occurred in Python patcher script: {str(e)}"
79 }
80 finally:
81 if java_file_path and os.path.exists(java_file_path):
82 os.remove(java_file_path)
83
84 