Skip to content

Commit ca58440

Browse files
committed
fix #3 skips file scan and notfy to console about Corrupted file
fix scan button not visible moved up add some redsign
1 parent a715fce commit ca58440

File tree

2 files changed

+129
-86
lines changed

2 files changed

+129
-86
lines changed

GUI.py

Lines changed: 98 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from picklescan.src.picklescan.scanner import scanned_files
1010
from picklescan.src.picklescan.scanner import infected_files
1111
import util.icons as ic
12+
from zipfile import BadZipFile
1213
COLOR_DARK_GREEN = '#78BA04'
1314
COLOR_DARK_BLUE = '#4974a5'
1415
COLOR_RED_ORANGE = '#C13515'
@@ -48,25 +49,40 @@ def do_clipboard_operation(event, window, element):
4849
except:
4950
# print('Nothing selected')
5051
window['-status_info-'].update(value='Nothing selected')
52+
5153
def main():
52-
ver = '0.1.0'
54+
ver = '0.1.1'
5355
sg.theme('Dark Gray 15')
5456
app_title = f"Disty's Stable Diffusion Pickle Scanner GUI - Ver {ver}"
5557
isError = 0
5658
file_ext = {
57-
("Pytorch Files", "*.ckpt"),
58-
("Pytorch Files", "*.pth"),
59-
("Pytorch Files", "*.pt"),
60-
("Pytorch Files", "*.bin"),
61-
("Pickle Files", "*.pkl"),
62-
("Pickle Files", "*.pickle"),
63-
("Pickle Files", "*.joblib"),
64-
("Pickle Files", "*.dat"),
65-
("Pickle Files", "*.data"),
66-
("Pickle Files", "*.npy"),
67-
("Pickle Files", "*.npy"),
68-
("Zip Files", "*.npz"),
69-
("Zip Files", "*.zip"),
59+
60+
("All", "*.ckpt"),
61+
("All", "*.pth"),
62+
("All", "*.pt"),
63+
("All", "*.bin"),
64+
("All", "*.pkl"),
65+
("All", "*.pickle"),
66+
("All", "*.joblib"),
67+
("All", "*.dat"),
68+
("All", "*.data"),
69+
("All", "*.npy"),
70+
("All", "*.npy"),
71+
("All", "*.npz"),
72+
("All", "*.zip"),
73+
# ("Pytorch Files", "*.ckpt"),
74+
# ("Pytorch Files", "*.pth"),
75+
# ("Pytorch Files", "*.pt"),
76+
# ("Pytorch Files", "*.bin"),
77+
# ("Pickle Files", "*.pkl"),
78+
# ("Pickle Files", "*.pickle"),
79+
# ("Pickle Files", "*.joblib"),
80+
# ("Pickle Files", "*.dat"),
81+
# ("Pickle Files", "*.data"),
82+
# ("Pickle Files", "*.npy"),
83+
# ("Pickle Files", "*.npy"),
84+
# ("Zip Files", "*.npz"),
85+
# ("Zip Files", "*.zip"),
7086
}
7187

7288
#region layout
@@ -83,7 +99,8 @@ def browse_layout(type_,visible_,disabled=False):
8399
layout = sg.Frame('',[
84100
[
85101
sg.Input(key=f'-input_files_{type_}-',enable_events=True,expand_x=True,expand_y=True,font='Ariel 11',background_color=COLOR_DARK_GRAY,right_click_menu=right_click_menu),
86-
browse_type
102+
browse_type,
103+
87104
],
88105
],expand_x=True,k=f'-frame_{type_}-',visible=visible_,relief=sg.RELIEF_SOLID,border_width=1,background_color=COLOR_GRAY_9900)
89106
return layout
@@ -118,44 +135,52 @@ def browse_layout(type_,visible_,disabled=False):
118135
],
119136
]
120137

121-
bottom_column = [
122-
[
123-
sg.Frame('',[
124-
[
125-
sg.Frame(' Status',[
126-
[
127-
sg.Text('',key='-status_info-', expand_x=True)
128-
],
129-
],expand_x=True,expand_y=False,relief=sg.RELIEF_SOLID,border_width=0,visible=True,element_justification='c',background_color=COLOR_GRAY_9900,title_color=COLOR_DARK_BLUE)
130-
],
131-
[
132-
sg.Button('Scan',k='-scan_button-',disabled=False,expand_x=True),
133-
],
134-
],expand_x=True,border_width=0,relief=sg.RELIEF_FLAT,element_justification='c')
135-
],
136-
]
137138

138139
console_column = [
139140
[
140141
sg.Frame('',[
142+
[
143+
sg.Button('SCAN',k='-scan_button-',disabled=False,button_color=("white",COLOR_DARK_BLUE),font='Ariel 12 ',expand_x=True,size=(10,2)),
144+
],
145+
141146
[
142147
sg.Text(SCANNED_FILES_DEF,k='-scanned_files_text-',expand_x=True,expand_y=True,font='Ariel 12',justification='left',size=(20,1)),
143148
sg.Text(INFECTED_FILES_DEF,k='-infected_files_text-',expand_x=True,expand_y=True,font='Ariel 12',justification='c',size=(20,1)),
144149
sg.Text(DANGEROUS_GLOBALS_DEF,k='-dangerous_globals_text-',expand_x=True,expand_y=True,font='Ariel 12',justification='right',size=(20,1)),
145-
],
150+
],
151+
152+
[
153+
sg.MLine(k='-console_ml-',reroute_stdout=True,write_only=False,reroute_cprint=True, autoscroll=True, text_color='white', auto_refresh=True,size=(120,30),expand_x=True,expand_y=True)
154+
],
146155
[
147156
sg.Frame('',[
148157
[
149158
sg.Text('',key='-status_state_text-', expand_x=True,expand_y=True,justification='c',font='Ariel 12 bold',background_color=COLOR_GRAY_9900)
150159
],
151160
],expand_x=True,expand_y=False,relief=sg.RELIEF_FLAT,border_width=0,visible=True,element_justification='c',background_color=COLOR_GRAY_9900,size=(50,30))
152-
],
153-
[
154-
sg.MLine(k='-console_ml-',reroute_stdout=True,write_only=False,reroute_cprint=True, autoscroll=True, text_color='white', auto_refresh=True,size=(120,35),expand_x=True,expand_y=True)
155-
],
156-
],expand_x=True,expand_y=True,border_width=0,relief=sg.RELIEF_FLAT,k='-scanned_frame-')
161+
],
162+
163+
164+
],expand_x=True,expand_y=True,border_width=0,relief=sg.RELIEF_FLAT,k='-scanned_frame-',element_justification="c")
157165
],
158166
]
167+
168+
bottom_column = [
169+
[
170+
sg.Frame('',[
171+
[
172+
sg.Frame(' Status',[
173+
[
174+
sg.Text('',key='-status_info-', expand_x=True,font='Ariel 12 bold')
175+
],
176+
],expand_x=True,expand_y=True,relief=sg.RELIEF_SOLID,border_width=0,visible=True,element_justification='c',background_color=COLOR_GRAY_9900,title_color=COLOR_DARK_BLUE)
177+
],
178+
# [
179+
# sg.Button('Scan',k='-scan_button-',disabled=False,expand_x=True),
180+
# ],
181+
],expand_x=True,border_width=0,relief=sg.RELIEF_FLAT,element_justification='c')
182+
],
183+
]
159184

160185
layout = [
161186

@@ -274,7 +299,6 @@ def browse_layout(type_,visible_,disabled=False):
274299
print(ConnectionRefusedError,e)
275300
isError = 1
276301
status_info_widget.update(value='Fail to scan')
277-
278302
except AttributeError as e:
279303
print(AttributeError,e)
280304
isError = 1
@@ -292,7 +316,6 @@ def browse_layout(type_,visible_,disabled=False):
292316
print(FileNotFoundError,e)
293317
isError = 1
294318
status_info_widget.update(value='Fail to scan')
295-
296319
else:
297320
isError = 1
298321
status_info_widget.update(value='Nothing to scan')
@@ -302,45 +325,54 @@ def browse_layout(type_,visible_,disabled=False):
302325
if len(input_files)>1:
303326
try:
304327
scan_result = scan_file_path(input_files)
328+
if scan_result == None:
329+
isError = 1
330+
status_info_widget.update(value='Fail to scan')
305331
except FileNotFoundError as e:
306332
print(FileNotFoundError,e)
307333
isError = 1
308-
status_info_widget.update(value='Fail to scan')
334+
status_info_widget.update(value='Fail to scan')
309335
else:
310336
isError = 1
311337
status_info_widget.update(value='Nothing to scan')
312338

339+
340+
341+
313342
if not isError:
314-
scanned_files_text_widget.update(value=f'{SCANNED_FILES} {scan_result.scanned_files}')
315-
infected_files_text_widget.update(value=f'{INFECTED_FILES} {scan_result.infected_files}')
316-
dangerous_globals_text_widget.update(value=f'{DANGEROUS_GLOBALS} {scan_result.issues_count}')
317-
scanned_files_len = len(scanned_files)
318-
infected_files_len = len(infected_files)
319-
320-
print('')
321-
if scanned_files_len > 0:
322-
print('----------- SCANNED FILES -----------')
323-
for file in scanned_files:
324-
print(f" {file}")
325-
326-
if infected_files_len == 0:
327-
status_state_text_widget.update(text_color='white')
328-
status_state_text_widget.Widget.config(background=COLOR_DARK_GREEN)
329-
status_state_text_widget.ParentRowFrame.config(background=COLOR_DARK_GREEN)
330-
status_state_text_widget.update(value='PASS')
343+
if scan_result:
344+
scanned_files_text_widget.update(value=f'{SCANNED_FILES} {scan_result.scanned_files}')
345+
infected_files_text_widget.update(value=f'{INFECTED_FILES} {scan_result.infected_files}')
346+
dangerous_globals_text_widget.update(value=f'{DANGEROUS_GLOBALS} {scan_result.issues_count}')
347+
scanned_files_len = len(scanned_files)
348+
infected_files_len = len(infected_files)
331349

332-
if infected_files_len > 0:
333350
print('')
334-
print('----------- INFECTED FILES -----------')
335-
for file in infected_files:
336-
print(f" {file}")
351+
if scanned_files_len > 0:
352+
# print('----------- SCANNED FILES -----------')
353+
# for file in scanned_files:
354+
# print(f" {file}")
355+
356+
if infected_files_len == 0:
357+
status_state_text_widget.update(text_color='white')
358+
status_state_text_widget.Widget.config(background=COLOR_DARK_GREEN)
359+
status_state_text_widget.ParentRowFrame.config(background=COLOR_DARK_GREEN)
360+
status_state_text_widget.update(value='PASS')
361+
362+
if infected_files_len > 0:
363+
print('')
364+
print('----------- INFECTED FILES -----------')
365+
print('')
337366

338-
status_state_text_widget.update(text_color='white')
339-
status_state_text_widget.Widget.config(background=COLOR_RED_ORANGE)
340-
status_state_text_widget.ParentRowFrame.config(background=COLOR_RED_ORANGE)
341-
status_state_text_widget.update(value='INFECTED')
367+
for file in infected_files:
368+
print(f" {file}")
369+
370+
status_state_text_widget.update(text_color='white')
371+
status_state_text_widget.Widget.config(background=COLOR_RED_ORANGE)
372+
status_state_text_widget.ParentRowFrame.config(background=COLOR_RED_ORANGE)
373+
status_state_text_widget.update(value='FAIL')
342374

343-
status_info_widget.update(value='Done')
375+
status_info_widget.update(value='Done')
344376

345377
if event == '-huggingface_radio-':
346378
window['-frame_file-'].update(visible=False)

picklescan/src/picklescan/scanner.py

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,13 @@ class ScanResult:
4141
infected_files: int = 0
4242

4343
def merge(self, sr: "ScanResult"):
44-
self.globals.extend(sr.globals)
45-
self.scanned_files += sr.scanned_files
46-
self.issues_count += sr.issues_count
47-
self.infected_files += sr.infected_files
44+
if sr:
45+
self.globals.extend(sr.globals)
46+
self.scanned_files += sr.scanned_files
47+
self.issues_count += sr.issues_count
48+
self.infected_files += sr.infected_files
49+
else:
50+
return None
4851

4952
_log = logging.getLogger("picklescan")
5053

@@ -136,13 +139,11 @@ def _http_get(url) -> bytes:
136139
_log.debug(f"Request: GET {url}")
137140

138141
parsed_url = urllib.parse.urlparse(url)
139-
# print('parsed_url',parsed_url.path)
140142
path_and_query = parsed_url.path + (
141143
"?" + parsed_url.query if len(parsed_url.query) > 0 else ""
142144
)
143145

144146
conn = http.client.HTTPSConnection(parsed_url.netloc)
145-
# print('path_and_query',path_and_query)
146147

147148
try:
148149
conn.request("GET", path_and_query)
@@ -225,12 +226,10 @@ def scan_pickle_bytes(data: IO[bytes], file_id) -> ScanResult:
225226
if unsafe_filter is not None and (
226227
unsafe_filter == "*" or g.name in unsafe_filter
227228
):
228-
# print('----------- INFECTED FILE -----------')
229229
g.safety = SafetyLevel.Dangerous
230230
_log.warning(
231231
"%s: %s import '%s %s' FOUND", file_id, g.safety.value, g.module, g.name
232232
)
233-
# print(f"{file_id} {g.safety.value} import {g.module} {g.name} FOUND")
234233
infected_files.append(f"{file_id} {g.safety.value} import {g.module} {g.name} FOUND")
235234
issues_count += 1
236235
elif safe_filter is not None and (safe_filter == "*" or g.name in safe_filter):
@@ -244,21 +243,27 @@ def scan_pickle_bytes(data: IO[bytes], file_id) -> ScanResult:
244243

245244
def scan_zip_bytes(data: IO[bytes], file_id) -> ScanResult:
246245
result = ScanResult([])
246+
try:
247+
with zipfile.ZipFile(data, "r") as zip:
248+
file_names = zip.namelist()
249+
_log.debug("Files in archive %s: %s", file_id, file_names)
250+
for file_name in file_names:
251+
if os.path.splitext(file_name)[1] in _pickle_file_extensions:
252+
_log.debug("Scanning file %s in zip archive %s", file_name, file_id)
253+
with zip.open(file_name, "r") as file:
254+
result.merge(scan_pickle_bytes(file, f"{file_id}:{file_name}"))
255+
if result:
256+
return result
257+
except zipfile.BadZipFile as e:
258+
print(" FAIL TO SCAN: Corrupted file",file_id)
247259

248-
with zipfile.ZipFile(data, "r") as zip:
249-
file_names = zip.namelist()
250-
_log.debug("Files in archive %s: %s", file_id, file_names)
251-
for file_name in file_names:
252-
if os.path.splitext(file_name)[1] in _pickle_file_extensions:
253-
_log.debug("Scanning file %s in zip archive %s", file_name, file_id)
254-
with zip.open(file_name, "r") as file:
255-
result.merge(scan_pickle_bytes(file, f"{file_id}:{file_name}"))
256260

257-
return result
258261

259262

260263
def scan_pytorch(data: IO[bytes], file_id) -> ScanResult:
261264
# new pytorch format
265+
print(" Scanning file:",file_id)
266+
262267
if _is_zipfile(data):
263268
return scan_zip_bytes(data, file_id)
264269
# old pytorch format
@@ -273,7 +278,6 @@ def scan_pytorch(data: IO[bytes], file_id) -> ScanResult:
273278
except TarError:
274279
# file does not contain a tar
275280
data.seek(0)
276-
277281
magic = get_magic_number(data)
278282
if magic != MAGIC_NUMBER:
279283
raise InvalidMagicError(magic, MAGIC_NUMBER)
@@ -286,14 +290,20 @@ def scan_pytorch(data: IO[bytes], file_id) -> ScanResult:
286290
for _ in range(5):
287291
scan_result.merge(scan_pickle_bytes(data, file_id))
288292
scan_result.scanned_files = 1
289-
return scan_result
290293

294+
return scan_result
291295

292296
def scan_bytes(data: IO[bytes], file_id, file_ext: Optional[str] = None) -> ScanResult:
293297
if file_ext is not None and file_ext in _pytorch_file_extensions:
294-
return scan_pytorch(data, file_id)
298+
try:
299+
return scan_pytorch(data, file_id)
300+
except:
301+
print(" FAIL TO SCAN: Corrupted file", file_id)
302+
return None
295303
else:
296304
is_zip = zipfile.is_zipfile(data)
305+
if isinstance(data,io.BufferedReader):
306+
print(" Scanning file:",data.name)
297307
data.seek(0)
298308
return (
299309
scan_zip_bytes(data, file_id)
@@ -362,4 +372,5 @@ def scan_file_path(path) -> ScanResult:
362372

363373
def scan_url(url) -> ScanResult:
364374
scanned_files.append(url)
375+
print(" Scanning file: ",url)
365376
return scan_bytes(io.BytesIO(_http_get(url)), url)

0 commit comments

Comments
 (0)