zipfile.BadZipfile: File name in directory "AndroidManifest.xml" and header "META-INF/MANIFEST.MF" d
阿新 • • 發佈:2019-01-06
問題
python 使用zipfile庫來解壓apk壓縮檔案的時候,出現了報錯zipfile.BadZipfile: File name in directory "AndroidManifest.xml" and header "META-INF/MANIFEST.MF" differ.
剖析問題
根據異常日誌,
File “c:\Python27\lib\zipfile.py”, line 1028, in extract
return self._extract_member(member, path, pwd)
File “c:\Python27\lib\zipfile.py
with self.open(member, pwd=pwd) as source,
File “c:\Python27\lib\zipfile.py”, line 980, in open
zinfo.orig_filename, fname)
zipfile.BadZipfile: File name in directory “AndroidManifest.xml” and header “META-INF/MANIFEST.MF” differ.
丟擲異常的地方是:c:\Python27\lib\zipfile.py", line 980
從下面程式碼可以看出,這是個開啟壓縮檔案的函式,找準關鍵點
fname != zinfo.orig_filename
這兩個變數是關鍵,fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) 這個語句大致可以從命名看出是讀取檔案頭一定偏移處的內容,大概。zinfo.orig_filename
這個是zipinfo物件的檔名,也就是我想提取出來的檔名稱,是zipinfo物件的一個屬性,也就是可能是檔案頭一定偏移處的內容和要提取的檔名對比,出現的不同
def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" if mode not in ("r", "U", "rU"): raise RuntimeError, 'open() requires mode "r", "U", or "rU"' if not self.fp: raise RuntimeError, \ "Attempt to read ZIP archive that was already closed" # Only open a new file for instances where we were not # given a file object in the constructor if self._filePassed: zef_file = self.fp should_close = False else: zef_file = open(self.filename, 'rb') should_close = True try: # Make sure we have an info object if isinstance(name, ZipInfo): # 'name' is already an info object zinfo = name else: # Get info object for name zinfo = self.getinfo(name) zef_file.seek(zinfo.header_offset, 0) # Skip the file header: fheader = zef_file.read(sizeFileHeader) if len(fheader) != sizeFileHeader: raise BadZipfile("Truncated file header") fheader = struct.unpack(structFileHeader, fheader) if fheader[_FH_SIGNATURE] != stringFileHeader: raise BadZipfile("Bad magic number for file header") fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) if fheader[_FH_EXTRA_FIELD_LENGTH]: zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname)
為了確認上面的分析的正確性,我們看看這個zip包的檔案結構
下面是一個可以使用zipfile提取檔案的壓縮包的檔案結構,我們對比一下,可以看出確實是檔案頭這塊除了問題。然後嘗試提取這個有出現問題zip包的其他檔案,是可以提取的
解決方法
上面這個問題的解決方法我自己沒有找到辦法,如果有大佬知道,歡迎評論。
暫時使用別的方法來替代這個zipfile壓縮庫,我選擇的是使用java 寫一個jar解壓工具,使用流的方式來解壓縮