From: Ira W. Snyder Date: Mon, 1 Jan 2007 02:59:48 +0000 (-0800) Subject: [PAR2PARSER] Force file closure X-Git-Tag: v2.0.0~17 X-Git-Url: https://www.irasnyder.com/gitweb/?a=commitdiff_plain;ds=sidebyside;h=390d46a48947106283cf21883a28e7cddc665c12;p=rarslave2.git [PAR2PARSER] Force file closure Make sure that the par2 file we are parsing gets closed after each time we parse it, regardless of whether or not we return successfully or raise an exception. Signed-off-by: Ira W. Snyder --- diff --git a/Par2Parser.py b/Par2Parser.py index c57d1e6..6940101 100644 --- a/Par2Parser.py +++ b/Par2Parser.py @@ -43,60 +43,67 @@ def get_protected_files (dir, filename): expected_file_ids = None filenames = [] - while 1: - d = file.read(pkt_header_size) - if not d: - break - - magic, pkt_len, pkt_md5, set_id, pkt_type = struct.unpack(pkt_header_fmt, d) - - if docrcchecks: - control_md5 = md5.new() - control_md5.update(d[0x20:]) - d = file.read(pkt_len - pkt_header_size) - control_md5.update(d) + # This try is here to ensure that we close the open file before + # returning. Since this code was (pretty much) borrowed verbatim + # from the cfv project, I didn't want to refactor it to make file + # closing more sane, so I just used a try / finally clause. + try: + while 1: + d = file.read(pkt_header_size) + if not d: + break - if control_md5.digest() != pkt_md5: - raise EnvironmentError, (errno.EINVAL, \ - "corrupt par2 file - bad packet hash") + magic, pkt_len, pkt_md5, set_id, pkt_type = struct.unpack(pkt_header_fmt, d) - if pkt_type == 'PAR 2.0\0FileDesc': - if not docrcchecks: + if docrcchecks: + control_md5 = md5.new() + control_md5.update(d[0x20:]) d = file.read(pkt_len - pkt_header_size) + control_md5.update(d) - file_id, file_md5, file_md5_16k, file_size = \ - struct.unpack(file_pkt_fmt, d[:file_pkt_size]) + if control_md5.digest() != pkt_md5: + raise EnvironmentError, (errno.EINVAL, \ + "corrupt par2 file - bad packet hash") - if seen_file_ids.get(file_id) is None: - seen_file_ids[file_id] = 1 - filename = chompnulls(d[file_pkt_size:]) - filenames.append(filename) + if pkt_type == 'PAR 2.0\0FileDesc': + if not docrcchecks: + d = file.read(pkt_len - pkt_header_size) - elif pkt_type == "PAR 2.0\0Main\0\0\0\0": - if not docrcchecks: - d = file.read(pkt_len - pkt_header_size) + file_id, file_md5, file_md5_16k, file_size = \ + struct.unpack(file_pkt_fmt, d[:file_pkt_size]) + + if seen_file_ids.get(file_id) is None: + seen_file_ids[file_id] = 1 + filename = chompnulls(d[file_pkt_size:]) + filenames.append(filename) - if expected_file_ids is None: - expected_file_ids = [] - slice_size, num_files = struct.unpack(main_pkt_fmt, d[:main_pkt_size]) - num_nonrecovery = (len(d)-main_pkt_size)/16 - num_files + elif pkt_type == "PAR 2.0\0Main\0\0\0\0": + if not docrcchecks: + d = file.read(pkt_len - pkt_header_size) - for i in range(main_pkt_size,main_pkt_size+(num_files+num_nonrecovery)*16,16): - expected_file_ids.append(d[i:i+16]) + if expected_file_ids is None: + expected_file_ids = [] + slice_size, num_files = struct.unpack(main_pkt_fmt, d[:main_pkt_size]) + num_nonrecovery = (len(d)-main_pkt_size)/16 - num_files - else: - if not docrcchecks: - file.seek(pkt_len - pkt_header_size, 1) + for i in range(main_pkt_size,main_pkt_size+(num_files+num_nonrecovery)*16,16): + expected_file_ids.append(d[i:i+16]) - if expected_file_ids is None: - raise EnvironmentError, (errno.EINVAL, \ - "corrupt or unsupported par2 file - no main packet found") + else: + if not docrcchecks: + file.seek(pkt_len - pkt_header_size, 1) - for id in expected_file_ids: - if not seen_file_ids.has_key(id): + if expected_file_ids is None: raise EnvironmentError, (errno.EINVAL, \ - "corrupt or unsupported par2 file - " \ - "expected file description packet not found") + "corrupt or unsupported par2 file - no main packet found") + + for id in expected_file_ids: + if not seen_file_ids.has_key(id): + raise EnvironmentError, (errno.EINVAL, \ + "corrupt or unsupported par2 file - " \ + "expected file description packet not found") + finally: + file.close () return filenames