From 32cbc84fc36fb41b216e97af3037eb99b9b62064 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 13 Mar 2012 09:47:53 +0530 Subject: [PATCH] KF8 Input: Do not fail if the input file contains corrupted font records. Fixes #953260 (error converting kindle ebooks) --- .../ebooks/conversion/plugins/mobi_input.py | 2 +- src/calibre/ebooks/metadata/opf2.py | 5 +++-- src/calibre/ebooks/mobi/reader/mobi8.py | 20 ++++++++++++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/calibre/ebooks/conversion/plugins/mobi_input.py b/src/calibre/ebooks/conversion/plugins/mobi_input.py index f56eb2002c..8ce44efa96 100644 --- a/src/calibre/ebooks/conversion/plugins/mobi_input.py +++ b/src/calibre/ebooks/conversion/plugins/mobi_input.py @@ -52,7 +52,7 @@ class MOBIInput(InputFormatPlugin): mr.extract_content(u'.', parse_cache) if mr.kf8_type is not None: - log('Found KF8 MOBI') + log('Found KF8 MOBI of type %s'%mr.kf8_type) from calibre.ebooks.mobi.reader.mobi8 import Mobi8Reader return os.path.abspath(Mobi8Reader(mr, log)()) diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index 91b6b571ec..c30545e6e1 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -1148,7 +1148,8 @@ class OPFCreator(Metadata): self.manifest = Manifest.from_paths(entries) self.manifest.set_basedir(self.base_path) - def create_manifest_from_files_in(self, files_and_dirs): + def create_manifest_from_files_in(self, files_and_dirs, + exclude=lambda x:False): entries = [] def dodir(dir): @@ -1156,7 +1157,7 @@ class OPFCreator(Metadata): root, files = spec[0], spec[-1] for name in files: path = os.path.join(root, name) - if os.path.isfile(path): + if os.path.isfile(path) and not exclude(path): entries.append((path, None)) for i in files_and_dirs: diff --git a/src/calibre/ebooks/mobi/reader/mobi8.py b/src/calibre/ebooks/mobi/reader/mobi8.py index dbe027f521..e459287331 100644 --- a/src/calibre/ebooks/mobi/reader/mobi8.py +++ b/src/calibre/ebooks/mobi/reader/mobi8.py @@ -347,8 +347,18 @@ class Mobi8Reader(object): # bytes 12 - 15: ?? offset to start of compressed data ?? (typically 0x00000018 = 24) # bytes 16 - 23: ?? typically all 0x00 ?? Are these compression flags from zlib? # The compressed data begins with 2 bytes of header and has 4 bytes of checksum at the end - data = data[26:-4] - uncompressed_data = zlib.decompress(data, -15) + try: + fields = struct.unpack_from(b'>LLLL', data, 4) + except: + fields = None + #self.log.debug('Font record fields: %s'%(fields,)) + cdata = data[26:-4] + try: + uncompressed_data = zlib.decompress(cdata, -15) + except: + self.log.warn('Failed to uncompress embedded font %d: ' + 'Fields: %s' % (fname_idx, fields,)) + uncompressed_data = data[4:] hdr = uncompressed_data[0:4] ext = 'dat' if hdr == b'\0\1\0\0' or hdr == b'true' or hdr == b'ttcf': @@ -379,7 +389,11 @@ class Mobi8Reader(object): opf = OPFCreator(os.getcwdu(), mi) opf.guide = guide - opf.create_manifest_from_files_in([os.getcwdu()]) + + def exclude(path): + return os.path.basename(path) == 'debug-raw.html' + + opf.create_manifest_from_files_in([os.getcwdu()], exclude=exclude) opf.create_spine(spine) opf.set_toc(toc)