|
46 | 46 | EXTENSIONS = "extensions"
|
47 | 47 | MIMES = "mimes"
|
48 | 48 |
|
| 49 | +# Invalid key for unzip and 7z extraction to prevent freezing on password |
| 50 | +# protected files. |
| 51 | +STATIC_INVALID_KEY = "StaticInvalidKey" |
| 52 | + |
| 53 | + |
| 54 | +async def unzip_file(filename, extraction_path, process_can_fail): |
| 55 | + """Extracts files using the unzip utility.""" |
| 56 | + stdout, stderr, _ = await aio_run_command( |
| 57 | + ["unzip", "-P", STATIC_INVALID_KEY, "-n", "-d", extraction_path, filename], |
| 58 | + process_can_fail, |
| 59 | + ) |
| 60 | + if not stderr: |
| 61 | + return 0 |
| 62 | + if "incorrect password" in stderr.decode(): |
| 63 | + LOGGER.error(f"Failed to extract {filename}: The file is password protected") |
| 64 | + return 0 |
| 65 | + is_exe = filename.endswith(".exe") |
| 66 | + if is_exe: |
| 67 | + return 0 # not all .exe files are zipfiles, no need for error |
| 68 | + return 1 |
| 69 | + |
| 70 | + |
| 71 | +async def unzip_7z(filename, extraction_path, process_can_fail): |
| 72 | + """Extracts files using the 7z utility. 7z supports more file format than\ |
| 73 | + unzip does. |
| 74 | + """ |
| 75 | + stdout, stderr, _ = await aio_run_command( |
| 76 | + ["7z", "x", f"-p{STATIC_INVALID_KEY}", filename], process_can_fail |
| 77 | + ) |
| 78 | + if stdout and not stderr: |
| 79 | + return 0 |
| 80 | + if "Wrong password" in stderr.decode(): |
| 81 | + LOGGER.error(f"Failed to extract {filename}: The file is password protected") |
| 82 | + return 0 |
| 83 | + is_exe = filename.endswith(".exe") |
| 84 | + if is_exe: |
| 85 | + return 0 # not all .exe files are zipfiles, no need for error |
| 86 | + return 1 |
| 87 | + |
49 | 88 |
|
50 | 89 | class BaseExtractor:
|
51 | 90 | """Extracts tar, rpm, etc. files"""
|
@@ -382,41 +421,17 @@ async def extract_file_zip(filename, extraction_path, process_can_fail=True):
|
382 | 421 | freezing during extraction if they are password protected.
|
383 | 422 | Providing a key during extraction has no effect if the zip file is
|
384 | 423 | not password protected and extraction will happen as normal."""
|
385 |
| - |
386 |
| - is_exe = filename.endswith(".exe") |
387 |
| - key = "StaticInvalidKey" |
388 | 424 | if await aio_inpath("unzip"):
|
389 |
| - stdout, stderr, _ = await aio_run_command( |
390 |
| - ["unzip", "-P", key, "-n", "-d", extraction_path, filename], |
391 |
| - process_can_fail, |
392 |
| - ) |
393 |
| - if stderr: |
394 |
| - if "incorrect password" in stderr.decode(): |
395 |
| - LOGGER.error( |
396 |
| - f"Failed to extract {filename}: The file is password protected" |
397 |
| - ) |
398 |
| - return 0 |
399 |
| - if is_exe: |
400 |
| - return 0 # not all .exe files are zipfiles, no need for error |
401 |
| - return 1 |
402 |
| - elif await aio_inpath("7z"): |
403 |
| - stdout, stderr, _ = await aio_run_command( |
404 |
| - ["7z", "x", f"-p{key}", filename], process_can_fail |
405 |
| - ) |
406 |
| - if stderr or not stdout: |
407 |
| - if "Wrong password" in stderr.decode(): |
408 |
| - LOGGER.error( |
409 |
| - f"Failed to extract {filename}: The file is password protected" |
410 |
| - ) |
411 |
| - return 0 |
412 |
| - if is_exe: |
413 |
| - return 0 # not all .exe files are zipfiles, no need for error |
414 |
| - return 1 |
| 425 | + result = await unzip_file(filename, extraction_path, process_can_fail) |
| 426 | + if result == 0: |
| 427 | + return result |
| 428 | + LOGGER.debug(f"Failed to extract {filename} using unzip. Trying 7z.") |
| 429 | + if await aio_inpath("7z"): |
| 430 | + return await unzip_7z(filename, extraction_path, process_can_fail) |
415 | 431 | else:
|
416 | 432 | with ErrorHandler(mode=ErrorMode.Ignore) as e:
|
417 | 433 | await aio_unpack_archive(filename, extraction_path)
|
418 | 434 | return e.exit_code
|
419 |
| - return 0 |
420 | 435 |
|
421 | 436 |
|
422 | 437 | class TempDirExtractorContext(BaseExtractor):
|
|
0 commit comments