88"""
99import itertools
1010import os
11+ import re
1112import shutil
1213import sys
1314import tempfile
@@ -47,11 +48,11 @@ def __init__(self, logger=None, error_mode=ErrorMode.TruncTrace):
4748 self .extract_file_rpm : {".rpm" },
4849 self .extract_file_deb : {".deb" , ".ipk" },
4950 self .extract_file_cab : {".cab" },
51+ self .extract_file_apk : {".apk" },
5052 self .extract_file_zip : {
5153 ".exe" ,
5254 ".zip" ,
5355 ".jar" ,
54- ".apk" ,
5556 ".msi" ,
5657 ".egg" ,
5758 ".whl" ,
@@ -78,13 +79,13 @@ async def extract_file_rpm(self, filename, extraction_path):
7879 if not await aio_inpath ("rpm2cpio" ) or not await aio_inpath ("cpio" ):
7980 await rpmextract ("-xC" , extraction_path , filename )
8081 else :
81- stdout , stderr = await aio_run_command (["rpm2cpio" , filename ])
82+ stdout , stderr , _ = await aio_run_command (["rpm2cpio" , filename ])
8283 if stderr or not stdout :
8384 return 1
8485 cpio_path = os .path .join (extraction_path , "data.cpio" )
8586 async with FileIO (cpio_path , "wb" ) as f :
8687 await f .write (stdout )
87- stdout , stderr = await aio_run_command (
88+ stdout , stderr , _ = await aio_run_command (
8889 ["cpio" , "-idm" , "--file" , cpio_path ]
8990 )
9091 if stdout or not stderr :
@@ -94,13 +95,13 @@ async def extract_file_rpm(self, filename, extraction_path):
9495 with ErrorHandler (mode = self .error_mode , logger = self .logger ):
9596 raise Exception ("7z is required to extract rpm files" )
9697 else :
97- stdout , stderr = await aio_run_command (["7z" , "x" , filename ])
98+ stdout , stderr , _ = await aio_run_command (["7z" , "x" , filename ])
9899 if stderr or not stdout :
99100 return 1
100101 filenames = await aio_glob (os .path .join (extraction_path , "*.cpio" ))
101102 filename = filenames [0 ]
102103
103- stdout , stderr = await aio_run_command (["7z" , "x" , filename ])
104+ stdout , stderr , _ = await aio_run_command (["7z" , "x" , filename ])
104105 if stderr or not stdout :
105106 return 1
106107 return 0
@@ -111,45 +112,82 @@ async def extract_file_deb(self, filename, extraction_path):
111112 with ErrorHandler (mode = self .error_mode , logger = self .logger ):
112113 raise Exception ("'ar' is required to extract deb files" )
113114 else :
114- stdout , stderr = await aio_run_command (["ar" , "x" , filename ])
115+ stdout , stderr , _ = await aio_run_command (["ar" , "x" , filename ])
115116 if stderr :
116117 return 1
117118 datafile = await aio_glob (os .path .join (extraction_path , "data.tar.*" ))
118119 with ErrorHandler (mode = ErrorMode .Ignore ) as e :
119120 await aio_unpack_archive (datafile [0 ], extraction_path )
120121 return e .exit_code
121122
123+ async def extract_file_apk (self , filename , extraction_path ):
124+ """Check whether it is alpine or android package"""
125+
126+ is_tar = True
127+ process_can_fail = True
128+ if await aio_inpath ("unzip" ):
129+ stdout , stderr , return_code = await aio_run_command (
130+ ["unzip" , "-l" , filename ], process_can_fail
131+ )
132+ if return_code == 0 :
133+ is_tar = False
134+ elif await aio_inpath ("7z" ):
135+ stdout , stderr , return_code = await aio_run_command (
136+ ["7z" , "t" , filename ], process_can_fail
137+ )
138+ if re .search (b"Type = Zip" , stdout ):
139+ is_tar = False
140+ elif await aio_inpath ("zipinfo" ):
141+ stdout , stderr , return_code = await aio_run_command (
142+ ["zipinfo" , filename ], process_can_fail
143+ )
144+ if return_code == 0 :
145+ is_tar = False
146+ elif await aio_inpath ("file" ):
147+ stdout , stderr , return_code = await aio_run_command (
148+ ["file" , filename ], process_can_fail
149+ )
150+ if re .search (b"Zip archive data" , stdout ):
151+ is_tar = False
152+ if is_tar :
153+ self .logger .debug (f"Extracting { filename } as a tar.gzip file" )
154+ with ErrorHandler (mode = ErrorMode .Ignore ) as e :
155+ await aio_unpack_archive (filename , extraction_path , format = "gztar" )
156+ return e .exit_code
157+ else :
158+ return await self .extract_file_zip (filename , extraction_path )
159+
122160 @staticmethod
123161 async def extract_file_cab (filename , extraction_path ):
124162 """Extract cab files"""
125163 if sys .platform .startswith ("linux" ):
126164 if not await aio_inpath ("cabextract" ):
127165 raise Exception ("'cabextract' is required to extract cab files" )
128166 else :
129- stdout , stderr = await aio_run_command (
167+ stdout , stderr , _ = await aio_run_command (
130168 ["cabextract" , "-d" , extraction_path , filename ]
131169 )
132170 if stderr or not stdout :
133171 return 1
134172 else :
135- stdout , stderr = await aio_run_command (
173+ stdout , stderr , _ = await aio_run_command (
136174 ["Expand" , filename , "-R -F:*" , extraction_path ]
137175 )
138176 if stderr or not stdout :
139177 return 1
140178 return 0
141179
142180 @staticmethod
143- async def extract_file_zip (filename , extraction_path ):
181+ async def extract_file_zip (filename , extraction_path , process_can_fail = False ):
144182 """Extract zip files"""
145183 if await aio_inpath ("unzip" ):
146- stdout , stderr = await aio_run_command (
184+ stdout , stderr , _ = await aio_run_command (
147185 ["unzip" , "-n" , "-d" , extraction_path , filename ]
148186 )
149187 if stderr or not stdout :
150188 return 1
151189 elif await aio_inpath ("7z" ):
152- stdout , stderr = await aio_run_command (["7z" , "x" , filename ])
190+ stdout , stderr , _ = await aio_run_command (["7z" , "x" , filename ])
153191 if stderr or not stdout :
154192 return 1
155193 else :
0 commit comments