From: Ira W. Snyder Date: Thu, 28 Dec 2006 05:09:36 +0000 (-0800) Subject: [PAR2PARSER] Fix Par2Parser class X-Git-Tag: v2.0.0~27 X-Git-Url: https://www.irasnyder.com/gitweb/?p=rarslave2.git;a=commitdiff_plain;h=177e50d8e9bd3f89a5ef83418f2e21f30f909b5d;hp=942307c46d276488cb42bcf4d2244979b14cbca1 [PAR2PARSER] Fix Par2Parser class The original class was registering every PAR2 file as corrupt, even though the old parser handled them fine. This reverts to the old parser, fixing the problem. Signed-off-by: Ira W. Snyder --- diff --git a/Par2Parser.py b/Par2Parser.py index 804848f..c57d1e6 100644 --- a/Par2Parser.py +++ b/Par2Parser.py @@ -7,10 +7,7 @@ # This was stolen from cfv (see http://cfv.sourceforge.net/ for a copy) ################################################################################ -import struct, errno, os - -def get_full_filename (dir, file): - return os.path.abspath (os.path.expanduser (os.path.join (dir, file))) +import struct, errno, os, md5 def chompnulls(line): p = line.find('\0') @@ -21,13 +18,19 @@ def get_protected_files (dir, filename): """Get all of the filenames that are protected by the par2 file given as the filename""" - full_filename = get_full_filename (dir, filename) + assert os.path.isdir (dir) # MUST be a valid directory + assert os.path.isfile (os.path.join (dir, filename)) + + full_filename = os.path.join (dir, filename) try: file = open(full_filename, 'rb') except: print 'Could not open %s' % (full_filename, ) - raise EnvironmentError, (errno.EINVAL, 'can not open par2 file') + return [] + + # We always want to do crc checks + docrcchecks = True pkt_header_fmt = '< 8s Q 16s 16s 16s' pkt_header_size = struct.calcsize(pkt_header_fmt) @@ -41,16 +44,26 @@ def get_protected_files (dir, filename): filenames = [] while 1: - try: - d = file.read(pkt_header_size) - except OverflowError: - raise EnvironmentError, (errno.EINVAL, 'bad par2 file') + 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) + + if control_md5.digest() != pkt_md5: + raise EnvironmentError, (errno.EINVAL, \ + "corrupt par2 file - bad packet hash") + if pkt_type == 'PAR 2.0\0FileDesc': + 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]) @@ -60,10 +73,8 @@ def get_protected_files (dir, filename): filenames.append(filename) elif pkt_type == "PAR 2.0\0Main\0\0\0\0": - try: + if not docrcchecks: d = file.read(pkt_len - pkt_header_size) - except OverflowError: - raise EnvironmentError, (errno.EINVAL, 'corrupt par2 file') if expected_file_ids is None: expected_file_ids = [] @@ -74,10 +85,8 @@ def get_protected_files (dir, filename): expected_file_ids.append(d[i:i+16]) else: - try: + if not docrcchecks: file.seek(pkt_len - pkt_header_size, 1) - except OverflowError, IOError: - raise EnvironmentError, (errno.EINVAL, 'corrupt par2 file') if expected_file_ids is None: raise EnvironmentError, (errno.EINVAL, \ diff --git a/rarslave.py b/rarslave.py index ce6e6ec..f02f356 100644 --- a/rarslave.py +++ b/rarslave.py @@ -210,7 +210,7 @@ def find_likely_files (dir, p2file): name_matches = [f for f in os.listdir (dir) if regex.match (f)] try: parsed_matches = Par2Parser.get_protected_files (dir, p2file) - except EnvironmentError: + except EnvironmentError, OSError, OverflowError: parsed_matches = [] logger.addMessage ('Bad par2 file: %s' % p2file, RarslaveLogger.MessageType.Fatal) @@ -283,7 +283,7 @@ def find_extraction_heads (dir, files): try: prot_files = Par2Parser.get_protected_files (dir, f) done = True - except EnvironmentError: + except EnvironmentError, OverflowError, OSError: logger.addMessage ('Error parsing PAR2 file: %s', f) continue