From b805ee5fcf52fb09ea3d1d9ecc479a7eacc80fb0 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 31 Oct 2010 16:06:55 +0000 Subject: [PATCH] Merged revisions 86037 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r86037 | antoine.pitrou | 2010-10-31 17:04:14 +0100 (dim., 31 oct. 2010) | 4 lines Issue #10266: uu.decode didn't close in_file explicitly when it was given as a filename. Patch by Brian Brazil. ........ --- Lib/test/test_uu.py | 17 +++++++ Lib/uu.py | 110 +++++++++++++++++++++++--------------------- Misc/NEWS | 3 ++ 3 files changed, 77 insertions(+), 53 deletions(-) diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py index a54f2c1df91..d6875c548c8 100644 --- a/Lib/test/test_uu.py +++ b/Lib/test/test_uu.py @@ -196,6 +196,23 @@ class UUFileTest(unittest.TestCase): finally: self._kill(f) + def test_decode_filename(self): + f = None + try: + support.unlink(self.tmpin) + f = open(self.tmpin, 'wb') + f.write(encodedtextwrapped(0o644, self.tmpout)) + f.close() + + uu.decode(self.tmpin) + + f = open(self.tmpout, 'rb') + s = f.read() + f.close() + self.assertEqual(s, plaintext) + finally: + self._kill(f) + def test_decodetwice(self): # Verify that decode() will refuse to overwrite an existing file f = None diff --git a/Lib/uu.py b/Lib/uu.py index 829f2925fd5..30c1ed8728b 100755 --- a/Lib/uu.py +++ b/Lib/uu.py @@ -92,66 +92,70 @@ def decode(in_file, out_file=None, mode=None, quiet=False): # # Open the input file, if needed. # + opened_files = [] if in_file == '-': in_file = sys.stdin.buffer elif isinstance(in_file, str): in_file = open(in_file, 'rb') - # - # Read until a begin is encountered or we've exhausted the file - # - while True: - hdr = in_file.readline() - if not hdr: - raise Error('No valid begin line found in input file') - if not hdr.startswith(b'begin'): - continue - hdrfields = hdr.split(b' ', 2) - if len(hdrfields) == 3 and hdrfields[0] == b'begin': + opened_files.append(in_file) + + try: + # + # Read until a begin is encountered or we've exhausted the file + # + while True: + hdr = in_file.readline() + if not hdr: + raise Error('No valid begin line found in input file') + if not hdr.startswith(b'begin'): + continue + hdrfields = hdr.split(b' ', 2) + if len(hdrfields) == 3 and hdrfields[0] == b'begin': + try: + int(hdrfields[1], 8) + break + except ValueError: + pass + if out_file is None: + # If the filename isn't ASCII, what's up with that?!? + out_file = hdrfields[2].rstrip(b' \t\r\n\f').decode("ascii") + if os.path.exists(out_file): + raise Error('Cannot overwrite existing file: %s' % out_file) + if mode is None: + mode = int(hdrfields[1], 8) + # + # Open the output file + # + if out_file == '-': + out_file = sys.stdout.buffer + elif isinstance(out_file, str): + fp = open(out_file, 'wb') try: - int(hdrfields[1], 8) - break - except ValueError: + os.path.chmod(out_file, mode) + except AttributeError: pass - if out_file is None: - # If the filename isn't ASCII, what's up with that?!? - out_file = hdrfields[2].rstrip(b' \t\r\n\f').decode("ascii") - if os.path.exists(out_file): - raise Error('Cannot overwrite existing file: %s' % out_file) - if mode is None: - mode = int(hdrfields[1], 8) - # - # Open the output file - # - opened = False - if out_file == '-': - out_file = sys.stdout.buffer - elif isinstance(out_file, str): - fp = open(out_file, 'wb') - try: - os.path.chmod(out_file, mode) - except AttributeError: - pass - out_file = fp - opened = True - # - # Main decoding loop - # - s = in_file.readline() - while s and s.strip(b' \t\r\n\f') != b'end': - try: - data = binascii.a2b_uu(s) - except binascii.Error as v: - # Workaround for broken uuencoders by /Fredrik Lundh - nbytes = (((s[0]-32) & 63) * 4 + 5) // 3 - data = binascii.a2b_uu(s[:nbytes]) - if not quiet: - sys.stderr.write("Warning: %s\n" % v) - out_file.write(data) + out_file = fp + opened_files.append(out_file) + # + # Main decoding loop + # s = in_file.readline() - if not s: - raise Error('Truncated input file') - if opened: - out_file.close() + while s and s.strip(b' \t\r\n\f') != b'end': + try: + data = binascii.a2b_uu(s) + except binascii.Error as v: + # Workaround for broken uuencoders by /Fredrik Lundh + nbytes = (((s[0]-32) & 63) * 4 + 5) // 3 + data = binascii.a2b_uu(s[:nbytes]) + if not quiet: + sys.stderr.write("Warning: %s\n" % v) + out_file.write(data) + s = in_file.readline() + if not s: + raise Error('Truncated input file') + finally: + for f in opened_files: + f.close() def test(): """uuencode/uudecode main program""" diff --git a/Misc/NEWS b/Misc/NEWS index b763dab6c45..b7336256e40 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -143,6 +143,9 @@ C-API Library ------- +- Issue #10266: uu.decode didn't close in_file explicitly when it was given + as a filename. Patch by Brian Brazil. + - Issue #10246: uu.encode didn't close file objects explicitly when filenames were given to it. Patch by Brian Brazil.