From 082f334c22f2a84aaa38de67f5e88473f8e664a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Tue, 19 Nov 2013 15:26:45 +0200 Subject: [PATCH] If URL download fails, delete the partially downloaded file (if it exists). If unzipping fails, print an error, and if the zip was corrupted, delete the corrupted file. Fixes https://github.com/kripken/emscripten/issues/1687. --- emsdk | 122 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 65 insertions(+), 57 deletions(-) diff --git a/emsdk b/emsdk index 47a7fb0..c6757dc 100644 --- a/emsdk +++ b/emsdk @@ -110,49 +110,54 @@ def unzip(source_filename, dest_dir, unpack_even_if_exists=False): print "Unpacking '" + source_filename + "' to '" + dest_dir + "'" mkdir_p(dest_dir) common_subdir = None - with zipfile.ZipFile(source_filename) as zf: - # Implement '--strip 1' behavior to unzipping by testing if all the files in the zip reside in a common subdirectory, and if so, - # we move the output tree at the end of uncompression step. - for member in zf.infolist(): - words = member.filename.split('/') - if common_subdir == None: - common_subdir = words[0] - elif common_subdir != words[0]: - common_subdir = '' - break + try: + with zipfile.ZipFile(source_filename) as zf: + # Implement '--strip 1' behavior to unzipping by testing if all the files in the zip reside in a common subdirectory, and if so, + # we move the output tree at the end of uncompression step. + for member in zf.infolist(): + words = member.filename.split('/') + if len(words) > 1: # If there is a directory component? + if common_subdir == None: + common_subdir = words[0] + elif common_subdir != words[0]: + common_subdir = '' + break - unzip_to_dir = dest_dir - if common_subdir: - unzip_to_dir = os.path.join('/'.join(dest_dir.split('/')[:-1]), 'unzip_temp') + unzip_to_dir = dest_dir + if common_subdir: + unzip_to_dir = os.path.join('/'.join(dest_dir.split('/')[:-1]), 'unzip_temp') - # Now do the actual decompress. - for member in zf.infolist(): - # Path traversal defense copied from - # http://hg.python.org/cpython/file/tip/Lib/http/server.py#l789 - words = member.filename.split('/') -# print "words: " + str(words) - path = unzip_to_dir - for word in words[:-1]: - drive, word = os.path.splitdrive(word) - head, word = os.path.split(word) - if word in (os.curdir, os.pardir, ''): continue - path = os.path.join(path, word) -# print "Extracting " + member.filename + " to " + path -# zf.extract(member, path) -# print "Extracting " + member.filename + " to " + unzip_to_dir - zf.extract(member, unzip_to_dir) + # Now do the actual decompress. + for member in zf.infolist(): + # Path traversal defense copied from + # http://hg.python.org/cpython/file/tip/Lib/http/server.py#l789 + words = member.filename.split('/') + path = unzip_to_dir + for word in words[:-1]: + drive, word = os.path.splitdrive(word) + head, word = os.path.split(word) + if word in (os.curdir, os.pardir, ''): continue + path = os.path.join(path, word) + zf.extract(member, unzip_to_dir) - if common_subdir: - try: - if os.path.exists(dest_dir): - shutil.rmtree(dest_dir) - except: - pass - shutil.copytree(os.path.join(unzip_to_dir, common_subdir), dest_dir) - try: - shutil.rmtree(unzip_to_dir) - except: - pass + if common_subdir: + try: + if os.path.exists(dest_dir): + shutil.rmtree(dest_dir) + except: + pass + shutil.copytree(os.path.join(unzip_to_dir, common_subdir), dest_dir) + try: + shutil.rmtree(unzip_to_dir) + except: + pass + except zipfile.BadZipfile, e: + print "Unzipping file '" + source_filename + "' failed due to reason: " + str(e) + "! Removing the corrupted zip file." + rmfile(source_filename) + return False + except Exception, e: + print "Unzipping file '" + source_filename + "' failed due to reason: " + str(e) + return False return True @@ -190,27 +195,30 @@ def download_file(url, dstpath, download_even_if_exists=False): try: u = urllib2.urlopen(url) mkdir_p(os.path.dirname(file_name)) - f = open(file_name, 'wb') - meta = u.info() - file_size = int(meta.getheaders("Content-Length")[0]) - print "Downloading: %s from %s Bytes: %s" % (file_name, url, file_size) + with open(file_name, 'wb') as f: + meta = u.info() + file_size = int(meta.getheaders("Content-Length")[0]) + print "Downloading: %s from %s Bytes: %s" % (file_name, url, file_size) - file_size_dl = 0 - block_sz = 8192 - while True: - buffer = u.read(block_sz) - if not buffer: - break + file_size_dl = 0 + block_sz = 8192 + while True: + buffer = u.read(block_sz) + if not buffer: + break - file_size_dl += len(buffer) - f.write(buffer) - status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size) - status = status + chr(8)*(len(status)+1) - print status, - - f.close() + file_size_dl += len(buffer) + f.write(buffer) + status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size) + status = status + chr(8)*(len(status)+1) + print status, except urllib2.HTTPError, e: print "HTTP error with URL '" + url + "': " + str(e) + rmfile(file_name) + return None + except: + print "Error downloading URL '" + url + "'!" + rmfile(file_name) return None return file_name