[ttFont] fail when input is not seekable and lazy=True
the SFNTReader expects the input file to be seekable, and it already rewinds the file with file.seek(0) to get to the sfnt table directory. Thus, if TTFont is loaded with an unseekable file object and lazy=True, we raise a TTLibError requiring one to either pass a seekable input file, or to not set lazy=True (in which case the input is loaded in a seekable BytesIO) Fixes https://github.com/fonttools/fonttools/issues/3052
This commit is contained in:
parent
1d5feb81e5
commit
4543910367
@ -6,7 +6,7 @@ from fontTools.misc.loggingTools import deprecateArgument
|
|||||||
from fontTools.ttLib import TTLibError
|
from fontTools.ttLib import TTLibError
|
||||||
from fontTools.ttLib.ttGlyphSet import _TTGlyph, _TTGlyphSetCFF, _TTGlyphSetGlyf
|
from fontTools.ttLib.ttGlyphSet import _TTGlyph, _TTGlyphSetCFF, _TTGlyphSetGlyf
|
||||||
from fontTools.ttLib.sfnt import SFNTReader, SFNTWriter
|
from fontTools.ttLib.sfnt import SFNTReader, SFNTWriter
|
||||||
from io import BytesIO, StringIO
|
from io import BytesIO, StringIO, UnsupportedOperation
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
@ -126,6 +126,7 @@ class TTFont(object):
|
|||||||
self.flavor = flavor
|
self.flavor = flavor
|
||||||
self.flavorData = None
|
self.flavorData = None
|
||||||
return
|
return
|
||||||
|
seekable = True
|
||||||
if not hasattr(file, "read"):
|
if not hasattr(file, "read"):
|
||||||
closeStream = True
|
closeStream = True
|
||||||
# assume file is a string
|
# assume file is a string
|
||||||
@ -146,12 +147,20 @@ class TTFont(object):
|
|||||||
else:
|
else:
|
||||||
# assume "file" is a readable file object
|
# assume "file" is a readable file object
|
||||||
closeStream = False
|
closeStream = False
|
||||||
if file.seekable():
|
# SFNTReader wants the input file to be seekable.
|
||||||
file.seek(0)
|
# SpooledTemporaryFile has no seekable() on < 3.11, but still can seek:
|
||||||
|
# https://github.com/fonttools/fonttools/issues/3052
|
||||||
|
if hasattr(file, "seekable"):
|
||||||
|
seekable = file.seekable()
|
||||||
|
elif hasattr(file, "seek"):
|
||||||
|
try:
|
||||||
|
file.seek(0)
|
||||||
|
except UnsupportedOperation:
|
||||||
|
seekable = False
|
||||||
|
|
||||||
if not self.lazy:
|
if not self.lazy:
|
||||||
# read input file in memory and wrap a stream around it to allow overwriting
|
# read input file in memory and wrap a stream around it to allow overwriting
|
||||||
if file.seekable():
|
if seekable:
|
||||||
file.seek(0)
|
file.seek(0)
|
||||||
tmp = BytesIO(file.read())
|
tmp = BytesIO(file.read())
|
||||||
if hasattr(file, "name"):
|
if hasattr(file, "name"):
|
||||||
@ -160,6 +169,8 @@ class TTFont(object):
|
|||||||
if closeStream:
|
if closeStream:
|
||||||
file.close()
|
file.close()
|
||||||
file = tmp
|
file = tmp
|
||||||
|
elif not seekable:
|
||||||
|
raise TTLibError("Input file must be seekable when lazy=True")
|
||||||
self._tableCache = _tableCache
|
self._tableCache = _tableCache
|
||||||
self.reader = SFNTReader(file, checkChecksums, fontNumber=fontNumber)
|
self.reader = SFNTReader(file, checkChecksums, fontNumber=fontNumber)
|
||||||
self.sfntVersion = self.reader.sfntVersion
|
self.sfntVersion = self.reader.sfntVersion
|
||||||
|
Loading…
x
Reference in New Issue
Block a user