mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix long standing bug in lrf-meta that could cause corruption when setting metadata. This affects the 'Save to disk' and 'Send to device' actions
This commit is contained in:
parent
e0e796ebdd
commit
32bf0d62ed
@ -12,7 +12,7 @@ to get and set meta information. For example:
|
|||||||
>>> lrf.category = "History"
|
>>> lrf.category = "History"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import struct, zlib, sys
|
import struct, zlib, sys, os
|
||||||
from shutil import copyfileobj
|
from shutil import copyfileobj
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
import xml.dom.minidom as dom
|
import xml.dom.minidom as dom
|
||||||
@ -147,6 +147,7 @@ class xml_field(object):
|
|||||||
if not val:
|
if not val:
|
||||||
val = ''
|
val = ''
|
||||||
document = obj.info
|
document = obj.info
|
||||||
|
|
||||||
def create_elem():
|
def create_elem():
|
||||||
elem = document.createElement(self.tag_name)
|
elem = document.createElement(self.tag_name)
|
||||||
parent = document.getElementsByTagName(self.parent)[0]
|
parent = document.getElementsByTagName(self.parent)[0]
|
||||||
@ -173,6 +174,7 @@ class xml_field(object):
|
|||||||
else:
|
else:
|
||||||
elem = create_elem()
|
elem = create_elem()
|
||||||
elem.appendChild(document.createTextNode(val))
|
elem.appendChild(document.createTextNode(val))
|
||||||
|
|
||||||
obj.info = document
|
obj.info = document
|
||||||
|
|
||||||
|
|
||||||
@ -370,6 +372,7 @@ class LRFMetaFile(object):
|
|||||||
self.compressed_info_size = len(stream) + 4
|
self.compressed_info_size = len(stream) + 4
|
||||||
delta = insert_into_file(self._file, stream, self.info_start, \
|
delta = insert_into_file(self._file, stream, self.info_start, \
|
||||||
self.info_start + orig_size - 4)
|
self.info_start + orig_size - 4)
|
||||||
|
|
||||||
self.toc_object_offset += delta
|
self.toc_object_offset += delta
|
||||||
self.object_index_offset += delta
|
self.object_index_offset += delta
|
||||||
self.update_object_offsets(delta)
|
self.update_object_offsets(delta)
|
||||||
@ -441,27 +444,16 @@ class LRFMetaFile(object):
|
|||||||
def update_object_offsets(self, delta):
|
def update_object_offsets(self, delta):
|
||||||
""" Run through the LRF Object index changing the offset by C{delta}. """
|
""" Run through the LRF Object index changing the offset by C{delta}. """
|
||||||
self._file.seek(self.object_index_offset)
|
self._file.seek(self.object_index_offset)
|
||||||
while(True):
|
count = self.number_of_objects
|
||||||
try:
|
while count > 0:
|
||||||
self._file.read(4)
|
raw = self._file.read(8)
|
||||||
except EOFError:
|
new_offset = struct.unpack(DWORD, raw[4:8])[0] + delta
|
||||||
break
|
if new_offset >= (2**8)**4 or new_offset < 0x4C:
|
||||||
pos = self._file.tell()
|
raise LRFException(_('Invalid LRF file. Could not set metadata.'))
|
||||||
try:
|
self._file.seek(-4, os.SEEK_CUR)
|
||||||
offset = self.unpack(fmt=DWORD, start=pos)[0] + delta
|
self._file.write(struct.pack(DWORD, new_offset))
|
||||||
except struct.error:
|
self._file.seek(8, os.SEEK_CUR)
|
||||||
break
|
count -= 1
|
||||||
if offset >= (2**8)**4:
|
|
||||||
# New offset is larger than a DWORD, so leave
|
|
||||||
# offset unchanged. I'm assuming offset is an offset from
|
|
||||||
# the previous object, otherwise this would impose a ~ 4MB limit
|
|
||||||
# on LRF files.
|
|
||||||
offset -= delta
|
|
||||||
self.pack(offset, fmt=DWORD, start=pos)
|
|
||||||
try:
|
|
||||||
self._file.read(12)
|
|
||||||
except EOFError:
|
|
||||||
break
|
|
||||||
self._file.flush()
|
self._file.flush()
|
||||||
|
|
||||||
@safe
|
@safe
|
||||||
@ -474,7 +466,6 @@ class LRFMetaFile(object):
|
|||||||
"""
|
"""
|
||||||
end = start + struct.calcsize(fmt)
|
end = start + struct.calcsize(fmt)
|
||||||
self._file.seek(start)
|
self._file.seek(start)
|
||||||
self._file.seek(start)
|
|
||||||
ret = struct.unpack(fmt, self._file.read(end-start))
|
ret = struct.unpack(fmt, self._file.read(end-start))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user