@@ -88,6 +88,32 @@ def zip_extract_member_new(self, member, targetpath, pwd):
88
88
return targetpath
89
89
90
90
91
+
92
+ def safe_extract_rar (file_path , dest_dir ):
93
+ import rarfile
94
+ import posixpath
95
+ with rarfile .RarFile (file_path ) as rf :
96
+ os .makedirs (dest_dir , exist_ok = True )
97
+ base_path = os .path .abspath (dest_dir )
98
+ for file_info in rf .infolist ():
99
+ orig_filename = file_info .filename
100
+ filename = posixpath .normpath (orig_filename ).lstrip ('/' )
101
+ # 路径遍历防护
102
+ if '..' in filename or filename .startswith ('../' ):
103
+ raise Exception (f"Attempted Path Traversal in { orig_filename } " )
104
+ # 符号链接防护
105
+ if hasattr (file_info , 'is_symlink' ) and file_info .is_symlink ():
106
+ raise Exception (f"Attempted Symlink in { orig_filename } " )
107
+ # 构造完整目标路径
108
+ target_path = os .path .join (base_path , filename )
109
+ final_path = os .path .normpath (target_path )
110
+ # 最终路径校验
111
+ if not final_path .startswith (base_path ):
112
+ raise Exception (f"Attempted Path Traversal in { orig_filename } " )
113
+ rf .extractall (dest_dir )
114
+
115
+
116
+
91
117
def extract_archive (file_path , dest_dir ):
92
118
import zipfile
93
119
import tarfile
@@ -132,14 +158,11 @@ def extract_archive(file_path, dest_dir):
132
158
# 此外,Windows上还需要安装winrar软件,配置其Path环境变量,如"C:\Program Files\WinRAR"才可以
133
159
elif file_extension == ".rar" :
134
160
try :
135
- import rarfile
136
-
137
- with rarfile .RarFile (file_path ) as rf :
138
- rf .extractall (path = dest_dir )
139
- logger .info ("Successfully extracted rar archive to {}" .format (dest_dir ))
161
+ import rarfile # 用来检查rarfile是否安装,不要删除
162
+ safe_extract_rar (file_path , dest_dir )
140
163
except :
141
164
logger .info ("Rar format requires additional dependencies to install" )
142
- return "\n \n 解压失败 ! 需要安装pip install rarfile来解压rar文件。建议:使用zip压缩格式。"
165
+ return "<br/><br/>解压失败 ! 需要安装pip install rarfile来解压rar文件。建议:使用zip压缩格式。"
143
166
144
167
# 第三方库,需要预先pip install py7zr
145
168
elif file_extension == ".7z" :
@@ -151,7 +174,7 @@ def extract_archive(file_path, dest_dir):
151
174
logger .info ("Successfully extracted 7z archive to {}" .format (dest_dir ))
152
175
except :
153
176
logger .info ("7z format requires additional dependencies to install" )
154
- return "\n \n 解压失败 ! 需要安装pip install py7zr来解压7z文件"
177
+ return "<br/><br/>解压失败 ! 需要安装pip install py7zr来解压7z文件"
155
178
else :
156
179
return ""
157
180
return ""
0 commit comments