diff --git a/Lib/fontTools/ttLib/tables/_g_l_y_f.py b/Lib/fontTools/ttLib/tables/_g_l_y_f.py index 8b3605047..148d7ec00 100644 --- a/Lib/fontTools/ttLib/tables/_g_l_y_f.py +++ b/Lib/fontTools/ttLib/tables/_g_l_y_f.py @@ -841,7 +841,10 @@ class Glyph(object): allEndPts = [] for compo in self.components: 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"): # move according to two reference points x1,y1 = allCoords[compo.firstPt] diff --git a/Tests/ttLib/tables/_g_l_y_f_test.py b/Tests/ttLib/tables/_g_l_y_f_test.py index d07869241..e3d09b7e1 100644 --- a/Tests/ttLib/tables/_g_l_y_f_test.py +++ b/Tests/ttLib/tables/_g_l_y_f_test.py @@ -1,7 +1,8 @@ from __future__ import print_function, division, absolute_import from fontTools.misc.py23 import * 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 import sys import array @@ -180,6 +181,13 @@ def strip_ttLibVersion(string): 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 def setUpClass(cls): with open(GLYF_BIN, 'rb') as f: @@ -215,6 +223,23 @@ class glyfTableTest(unittest.TestCase): glyfData = glyfTable.compile(font) 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__": import sys