[ttLib/glyf] raise TTLibError with the offending glyph name in the error message when a component (indirectly) references itself

This commit is contained in:
justvanrossum 2019-03-17 15:30:20 +01:00
parent 5290e831a1
commit ac2413e905
2 changed files with 30 additions and 2 deletions

View File

@ -841,7 +841,10 @@ class Glyph(object):
allEndPts = [] allEndPts = []
for compo in self.components: for compo in self.components:
g = glyfTable[compo.glyphName] g = glyfTable[compo.glyphName]
coordinates, endPts, flags = g.getCoordinates(glyfTable) try:
coordinates, endPts, flags = g.getCoordinates(glyfTable)
except RuntimeError:
raise ttLib.TTLibError("glyph '%s' contains recursive component reference" % compo.glyphName)
if hasattr(compo, "firstPt"): if hasattr(compo, "firstPt"):
# move according to two reference points # move according to two reference points
x1,y1 = allCoords[compo.firstPt] x1,y1 = allCoords[compo.firstPt]

View File

@ -1,7 +1,8 @@
from __future__ import print_function, division, absolute_import from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import * from fontTools.misc.py23 import *
from fontTools.misc.fixedTools import otRound from fontTools.misc.fixedTools import otRound
from fontTools.ttLib import TTFont, newTable from fontTools.pens.ttGlyphPen import TTGlyphPen
from fontTools.ttLib import TTFont, newTable, TTLibError
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates
import sys import sys
import array import array
@ -180,6 +181,13 @@ def strip_ttLibVersion(string):
class glyfTableTest(unittest.TestCase): class glyfTableTest(unittest.TestCase):
def __init__(self, methodName):
unittest.TestCase.__init__(self, methodName)
# Python 3 renamed assertRaisesRegexp to assertRaisesRegex,
# and fires deprecation warnings if a program uses the old name.
if not hasattr(self, "assertRaisesRegex"):
self.assertRaisesRegex = self.assertRaisesRegexp
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
with open(GLYF_BIN, 'rb') as f: with open(GLYF_BIN, 'rb') as f:
@ -215,6 +223,23 @@ class glyfTableTest(unittest.TestCase):
glyfData = glyfTable.compile(font) glyfData = glyfTable.compile(font)
self.assertEqual(glyfData, self.glyfData) self.assertEqual(glyfData, self.glyfData)
def test_recursiveComponent(self):
glyphSet = {}
pen_dummy = TTGlyphPen(glyphSet)
glyph_dummy = pen_dummy.glyph()
glyphSet["A"] = glyph_dummy
glyphSet["B"] = glyph_dummy
pen_A = TTGlyphPen(glyphSet)
pen_A.addComponent("B", (1, 0, 0, 1, 0, 0))
pen_B = TTGlyphPen(glyphSet)
pen_B.addComponent("A", (1, 0, 0, 1, 0, 0))
glyph_A = pen_A.glyph()
glyph_B = pen_B.glyph()
glyphSet["A"] = glyph_A
glyphSet["B"] = glyph_B
with self.assertRaisesRegex(TTLibError, "glyph '.' contains recursive component reference"):
glyph_A.getCoordinates(glyphSet)
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys