[cffLib] prevent *Converter.read from changing file positions

This commit is contained in:
derwind 2018-02-22 22:46:46 +09:00
parent d0b4c4b360
commit 91fc3c5c41

View File

@ -1180,6 +1180,7 @@ class PrivateDictConverter(TableConverter):
def read(self, parent, value): def read(self, parent, value):
size, offset = value size, offset = value
file = parent.file file = parent.file
pos = file.tell()
isCFF2 = parent._isCFF2 isCFF2 = parent._isCFF2
try: try:
vstore = parent.vstore vstore = parent.vstore
@ -1191,6 +1192,7 @@ class PrivateDictConverter(TableConverter):
data = file.read(size) data = file.read(size)
assert len(data) == size assert len(data) == size
priv.decompile(data) priv.decompile(data)
file.seek(pos)
return priv return priv
def write(self, parent, value): def write(self, parent, value):
@ -1204,9 +1206,12 @@ class SubrsConverter(TableConverter):
def read(self, parent, value): def read(self, parent, value):
file = parent.file file = parent.file
pos = file.tell()
isCFF2 = parent._isCFF2 isCFF2 = parent._isCFF2
file.seek(parent.offset + value) # Offset(self) file.seek(parent.offset + value) # Offset(self)
return SubrsIndex(file, isCFF2=isCFF2) subrIndex = SubrsIndex(file, isCFF2=isCFF2)
file.seek(pos)
return subrIndex
def write(self, parent, value): def write(self, parent, value):
return 0 # dummy value return 0 # dummy value
@ -1216,6 +1221,7 @@ class CharStringsConverter(TableConverter):
def read(self, parent, value): def read(self, parent, value):
file = parent.file file = parent.file
pos = file.tell()
isCFF2 = parent._isCFF2 isCFF2 = parent._isCFF2
charset = parent.charset charset = parent.charset
globalSubrs = parent.GlobalSubrs globalSubrs = parent.GlobalSubrs
@ -1232,6 +1238,7 @@ class CharStringsConverter(TableConverter):
file.seek(value) # Offset(0) file.seek(value) # Offset(0)
charStrings = CharStrings( charStrings = CharStrings(
file, charset, globalSubrs, private, fdSelect, fdArray, isCFF2=isCFF2) file, charset, globalSubrs, private, fdSelect, fdArray, isCFF2=isCFF2)
file.seek(pos)
return charStrings return charStrings
def write(self, parent, value): def write(self, parent, value):
@ -1264,18 +1271,19 @@ class CharsetConverter(object):
if value > 2: if value > 2:
numGlyphs = parent.numGlyphs numGlyphs = parent.numGlyphs
file = parent.file file = parent.file
pos = file.tell()
file.seek(value) file.seek(value)
log.log(DEBUG, "loading charset at %s", value) log.log(DEBUG, "loading charset at %s", value)
format = readCard8(file) format = readCard8(file)
pos = file.tell()
if format == 0: if format == 0:
charset = parseCharset0(numGlyphs, file, parent.strings, isCID, pos) charset = parseCharset0(numGlyphs, file, parent.strings, isCID)
elif format == 1 or format == 2: elif format == 1 or format == 2:
charset = parseCharset(numGlyphs, file, parent.strings, isCID, format, pos) charset = parseCharset(numGlyphs, file, parent.strings, isCID, format)
else: else:
raise NotImplementedError raise NotImplementedError
assert len(charset) == numGlyphs assert len(charset) == numGlyphs
log.log(DEBUG, " charset end at %s", file.tell()) log.log(DEBUG, " charset end at %s", file.tell())
file.seek(pos)
else: # offset == 0 -> no charset data. else: # offset == 0 -> no charset data.
if isCID or "CharStrings" not in parent.rawDict: if isCID or "CharStrings" not in parent.rawDict:
# We get here only when processing fontDicts from the FDArray of # We get here only when processing fontDicts from the FDArray of
@ -1408,8 +1416,7 @@ def packCharset(charset, isCID, strings):
return bytesjoin(data) return bytesjoin(data)
def parseCharset0(numGlyphs, file, strings, isCID, pos): def parseCharset0(numGlyphs, file, strings, isCID):
file.seek(pos)
charset = [".notdef"] charset = [".notdef"]
if isCID: if isCID:
for i in range(numGlyphs - 1): for i in range(numGlyphs - 1):
@ -1422,8 +1429,7 @@ def parseCharset0(numGlyphs, file, strings, isCID, pos):
return charset return charset
def parseCharset(numGlyphs, file, strings, isCID, fmt, pos): def parseCharset(numGlyphs, file, strings, isCID, fmt):
file.seek(pos)
charset = ['.notdef'] charset = ['.notdef']
count = 1 count = 1
if fmt == 1: if fmt == 1:
@ -1475,6 +1481,7 @@ class EncodingConverter(SimpleConverter):
else: else:
assert value > 1 assert value > 1
file = parent.file file = parent.file
pos = file.tell()
file.seek(value) file.seek(value)
log.log(DEBUG, "loading Encoding at %s", value) log.log(DEBUG, "loading Encoding at %s", value)
fmt = readCard8(file) fmt = readCard8(file)
@ -1483,13 +1490,13 @@ class EncodingConverter(SimpleConverter):
raise NotImplementedError("Encoding supplements are not yet supported") raise NotImplementedError("Encoding supplements are not yet supported")
fmt = fmt & 0x7f fmt = fmt & 0x7f
# save file position against lazy-load of charset # save file position against lazy-load of charset
pos = file.tell()
if fmt == 0: if fmt == 0:
encoding = parseEncoding0(parent.charset, file, haveSupplement, encoding = parseEncoding0(parent.charset, file, haveSupplement,
parent.strings, pos) parent.strings)
elif fmt == 1: elif fmt == 1:
encoding = parseEncoding1(parent.charset, file, haveSupplement, encoding = parseEncoding1(parent.charset, file, haveSupplement,
parent.strings, pos) parent.strings)
file.seek(pos)
return encoding return encoding
def write(self, parent, value): def write(self, parent, value):
@ -1528,8 +1535,7 @@ class EncodingConverter(SimpleConverter):
return encoding return encoding
def parseEncoding0(charset, file, haveSupplement, strings, pos): def parseEncoding0(charset, file, haveSupplement, strings):
file.seek(pos)
nCodes = readCard8(file) nCodes = readCard8(file)
encoding = [".notdef"] * 256 encoding = [".notdef"] * 256
for glyphID in range(1, nCodes + 1): for glyphID in range(1, nCodes + 1):
@ -1539,8 +1545,7 @@ def parseEncoding0(charset, file, haveSupplement, strings, pos):
return encoding return encoding
def parseEncoding1(charset, file, haveSupplement, strings, pos): def parseEncoding1(charset, file, haveSupplement, strings):
file.seek(pos)
nRanges = readCard8(file) nRanges = readCard8(file)
encoding = [".notdef"] * 256 encoding = [".notdef"] * 256
glyphID = 1 glyphID = 1
@ -1619,12 +1624,14 @@ class FDArrayConverter(TableConverter):
except AttributeError: except AttributeError:
vstore = None vstore = None
file = parent.file file = parent.file
pos = file.tell()
isCFF2 = parent._isCFF2 isCFF2 = parent._isCFF2
file.seek(value) file.seek(value)
fdArray = FDArrayIndex(file, isCFF2=isCFF2) fdArray = FDArrayIndex(file, isCFF2=isCFF2)
fdArray.vstore = vstore fdArray.vstore = vstore
fdArray.strings = parent.strings fdArray.strings = parent.strings
fdArray.GlobalSubrs = parent.GlobalSubrs fdArray.GlobalSubrs = parent.GlobalSubrs
file.seek(pos)
return fdArray return fdArray
def write(self, parent, value): def write(self, parent, value):
@ -1644,8 +1651,10 @@ class FDSelectConverter(object):
def read(self, parent, value): def read(self, parent, value):
file = parent.file file = parent.file
pos = file.tell()
file.seek(value) file.seek(value)
fdSelect = FDSelect(file, parent.numGlyphs) fdSelect = FDSelect(file, parent.numGlyphs)
file.seek(pos)
return fdSelect return fdSelect
def write(self, parent, value): def write(self, parent, value):
@ -1669,9 +1678,11 @@ class VarStoreConverter(SimpleConverter):
def read(self, parent, value): def read(self, parent, value):
file = parent.file file = parent.file
pos = file.tell()
file.seek(value) file.seek(value)
varStore = VarStoreData(file) varStore = VarStoreData(file)
varStore.decompile() varStore.decompile()
file.seek(pos)
return varStore return varStore
def write(self, parent, value): def write(self, parent, value):