Mutliple issues here:
* tarfile can throw IOErrors in addition to OSErrors, and both may need
the filename attribute set
* tarfile needs to be told to raise exceptions for errors, rather than
ignoring them (errorlevel=1 to the constructor)
* tarfile needs to be told to raise exceptions for tar format corruptions
and not just I/O errors (errorlevel=2)
* the exception should be re-raised with a plain "raise" instead of "raise
e"
to preserve the stack trace correctly; it's OK to modify the exception
before re-raising it
Also moved the creating of tf to the rest of the code that sets it up,
for clarity.
I've tested these changes manually, but not written a test case,
since a test case is tricky to write for this.
Originally found by Joe Burmeister.
---
morphlib/bins.py | 13 ++++++-------
1 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/morphlib/bins.py b/morphlib/bins.py
index ec750db..00b0c2f 100644
--- a/morphlib/bins.py
+++ b/morphlib/bins.py
@@ -116,8 +116,6 @@ def unpack_binary_from_file(f, dirname): # pragma: no cover
'''
- tf = tarfile.open(fileobj=f)
-
# This is evil, but necessary. For some reason Python's system
# call wrappers (os.mknod and such) do not (always?) set the
# filename attribute of the OSError exception they raise. We
@@ -177,16 +175,17 @@ def unpack_binary_from_file(f, dirname): # pragma: no cover
def make_something(tarinfo, targetpath): # pragma: no cover
prepare_extract(tarinfo, targetpath)
try:
- return real(tarinfo, targetpath)
- except OSError, e:
+ ret = real(tarinfo, targetpath)
+ except (IOError, OSError), e:
if e.errno != errno.EEXIST:
if e.filename is None:
e.filename = targetpath
- raise e
- else:
- raise
+ raise
+ else:
+ return ret
return make_something
+ tf = tarfile.open(fileobj=f, errorlevel=2)
tf.makedir = monkey_patcher(tf.makedir)
tf.makefile = monkey_patcher(tf.makefile)
tf.makeunknown = monkey_patcher(tf.makeunknown)
--
1.7.2.5