KF8 Input: Do not fail if the input file contains corrupted font records. Fixes #953260 (error converting kindle ebooks)

This commit is contained in:
Kovid Goyal 2012-03-13 09:47:53 +05:30
parent 1549bf12d3
commit 32cbc84fc3
3 changed files with 21 additions and 6 deletions

View File

@ -52,7 +52,7 @@ class MOBIInput(InputFormatPlugin):
mr.extract_content(u'.', parse_cache) mr.extract_content(u'.', parse_cache)
if mr.kf8_type is not None: 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 from calibre.ebooks.mobi.reader.mobi8 import Mobi8Reader
return os.path.abspath(Mobi8Reader(mr, log)()) return os.path.abspath(Mobi8Reader(mr, log)())

View File

@ -1148,7 +1148,8 @@ class OPFCreator(Metadata):
self.manifest = Manifest.from_paths(entries) self.manifest = Manifest.from_paths(entries)
self.manifest.set_basedir(self.base_path) 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 = [] entries = []
def dodir(dir): def dodir(dir):
@ -1156,7 +1157,7 @@ class OPFCreator(Metadata):
root, files = spec[0], spec[-1] root, files = spec[0], spec[-1]
for name in files: for name in files:
path = os.path.join(root, name) path = os.path.join(root, name)
if os.path.isfile(path): if os.path.isfile(path) and not exclude(path):
entries.append((path, None)) entries.append((path, None))
for i in files_and_dirs: for i in files_and_dirs:

View File

@ -347,8 +347,18 @@ class Mobi8Reader(object):
# bytes 12 - 15: ?? offset to start of compressed data ?? (typically 0x00000018 = 24) # bytes 12 - 15: ?? offset to start of compressed data ?? (typically 0x00000018 = 24)
# bytes 16 - 23: ?? typically all 0x00 ?? Are these compression flags from zlib? # 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 # The compressed data begins with 2 bytes of header and has 4 bytes of checksum at the end
data = data[26:-4] try:
uncompressed_data = zlib.decompress(data, -15) 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] hdr = uncompressed_data[0:4]
ext = 'dat' ext = 'dat'
if hdr == b'\0\1\0\0' or hdr == b'true' or hdr == b'ttcf': 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 = OPFCreator(os.getcwdu(), mi)
opf.guide = guide 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.create_spine(spine)
opf.set_toc(toc) opf.set_toc(toc)