Skip to content

Commit

Permalink
Support solid archives from in-memory file object
Browse files Browse the repository at this point in the history
Those need to be written fully out to tempfile.

Fixes: markokr#21
  • Loading branch information
markokr committed May 20, 2016
1 parent a65dd86 commit e51d6aa
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
13 changes: 11 additions & 2 deletions dumprar.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

"""Dump archive contents, test extraction."""

import io
import sys
import rarfile as rf
from binascii import crc32, hexlify
Expand Down Expand Up @@ -190,6 +191,7 @@ def show_item(h):
cf_extract = 0
cf_test_read = 0
cf_test_unrar = 0
cf_test_memory = 0

def check_crc(f, inf):
ucrc = f.CRC
Expand Down Expand Up @@ -242,13 +244,17 @@ def test_real(fn, psw):
if cf_verbose > 1:
cb = show_item

rfarg = fn
if cf_test_memory:
fnarg = io.BytesIO(open(fn, 'rb').read())

# check if rar
if not rf.is_rarfile(fn):
if not rf.is_rarfile(rfarg):
xprint(" --- %s is not a RAR file ---", fn)
return

# open
r = rf.RarFile(fn, charset = cf_charset, info_callback = cb)
r = rf.RarFile(rfarg, charset = cf_charset, info_callback = cb)
# set password
if r.needs_password():
if psw:
Expand Down Expand Up @@ -302,6 +308,7 @@ def test(fn, psw):
def main():
global cf_verbose, cf_show_comment, cf_charset
global cf_extract, cf_test_read, cf_test_unrar
global cf_test_memory

# parse args
args = []
Expand Down Expand Up @@ -333,6 +340,8 @@ def main():
cf_test_read += 1
elif a == '-T':
cf_test_unrar = 1
elif a == '-M':
cf_test_memory = 1
elif a[1] == 'C':
cf_charset = a[2:]
else:
Expand Down
23 changes: 23 additions & 0 deletions rarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,8 @@ def open(self, fname, mode = 'r', psw = None):
return self._open_clear(inf)
elif use_hack:
return self._open_hack(inf, psw)
elif is_filelike(self.rarfile):
return self._open_unrar_membuf(self.rarfile, inf, psw)
else:
return self._open_unrar(self.rarfile, inf, psw)

Expand Down Expand Up @@ -1184,6 +1186,27 @@ def _read_comment_v3(self, inf, psw=None):

return self._decode_comment(cmt)

# write in-memory archive to temp file - needed for solid archives
def _open_unrar_membuf(self, memfile, inf, psw):
memfile.seek(0, 0)

tmpfd, tmpname = mkstemp(suffix='.rar')
tmpf = os.fdopen(tmpfd, "wb")

try:
BSIZE = 32*1024
while True:
buf = memfile.read(BSIZE)
if not buf:
break
tmpf.write(buf)
tmpf.close()
except:
tmpf.close()
os.unlink(tmpname)
raise
return self._open_unrar(tmpname, inf, psw, tmpname)

# extract using unrar
def _open_unrar(self, rarfile, inf, psw = None, tmpfile = None):
if is_filelike(rarfile):
Expand Down

0 comments on commit e51d6aa

Please sign in to comment.