1
+ import lzma
1
2
import re
2
3
import zlib
3
- from lzma import LZMADecompressor
4
4
from pathlib import Path
5
- from typing import Optional
5
+ from typing import Callable , Optional
6
6
7
- from pyzstd import EndlessZstdDecompressor
7
+ import pyzstd
8
8
9
9
from unblob .file_utils import (
10
10
Endian ,
39
39
LZMA_COMPRESSION = "#!/bin/sh\x0a #L3.0\x0a "
40
40
ZSTD_COMPRESSION = "#!/bin/sh\x0a #Z4.0\x20 "
41
41
42
- DECOMPRESS_METHOD = {
43
- ZLIB_COMPRESSION .encode (): zlib .decompressobj ,
42
+
43
+ class Decompressor :
44
+ DECOMPRESSOR : Callable
45
+
46
+ def __init__ (self ):
47
+ self ._decompressor = self .DECOMPRESSOR ()
48
+
49
+ def decompress (self , data : bytes ) -> bytes :
50
+ return self ._decompressor .decompress (data )
51
+
52
+ def flush (self ) -> bytes :
53
+ return b""
54
+
55
+
56
+ class LZMADecompressor (Decompressor ):
57
+ DECOMPRESSOR = lzma .LZMADecompressor
58
+
59
+
60
+ class ZLIBDecompressor (Decompressor ):
61
+ DECOMPRESSOR = zlib .decompressobj
62
+
63
+ def flush (self ) -> bytes :
64
+ return self ._decompressor .flush ()
65
+
66
+
67
+ class ZSTDDecompressor (Decompressor ):
68
+ DECOMPRESSOR = pyzstd .EndlessZstdDecompressor
69
+
70
+
71
+ DECOMPRESS_METHOD : dict [bytes , type [Decompressor ]] = {
72
+ ZLIB_COMPRESSION .encode (): ZLIBDecompressor ,
44
73
LZMA_COMPRESSION .encode (): LZMADecompressor ,
45
- ZSTD_COMPRESSION .encode (): EndlessZstdDecompressor ,
74
+ ZSTD_COMPRESSION .encode (): ZSTDDecompressor ,
46
75
}
47
76
48
77
@@ -67,6 +96,7 @@ def extract(self, inpath: Path, outdir: Path):
67
96
decompressor = decompressor_cls ()
68
97
for chunk in iterate_file (infile , current_offset , compressed_len ):
69
98
outfile .write (decompressor .decompress (chunk ))
99
+ outfile .write (decompressor .flush ())
70
100
return ExtractResult (reports = fs .problems )
71
101
72
102
0 commit comments