diff --git a/Lib/fontTools/feaLib/lexer.py b/Lib/fontTools/feaLib/lexer.py index a5fdf55c9..0d071917e 100644 --- a/Lib/fontTools/feaLib/lexer.py +++ b/Lib/fontTools/feaLib/lexer.py @@ -102,9 +102,9 @@ class Lexer(object): glyphclass = text[start + 1:self.pos_] if len(glyphclass) < 1: raise FeatureLibError("Expected glyph class name", location) - if len(glyphclass) > 30: + if len(glyphclass) > 63: raise FeatureLibError( - "Glyph class names must not be longer than 30 characters", + "Glyph class names must not be longer than 63 characters", location) if not Lexer.RE_GLYPHCLASS.match(glyphclass): raise FeatureLibError( diff --git a/Lib/fontTools/feaLib/lexer_test.py b/Lib/fontTools/feaLib/lexer_test.py index 3758948b1..f082b244c 100644 --- a/Lib/fontTools/feaLib/lexer_test.py +++ b/Lib/fontTools/feaLib/lexer_test.py @@ -40,8 +40,8 @@ class LexerTest(unittest.TestCase): self.assertRaisesRegex(FeatureLibError, "Expected glyph class", lex, "@ A") self.assertRaisesRegex(FeatureLibError, - "not be longer than 30 characters", - lex, "@a123456789.a123456789.a123456789.x") + "not be longer than 63 characters", + lex, "@" + ("A" * 64)) self.assertRaisesRegex(FeatureLibError, "Glyph class names must consist of", lex, "@Ab:c") diff --git a/Lib/fontTools/feaLib/parser.py b/Lib/fontTools/feaLib/parser.py index f10ee8151..07622f3bc 100644 --- a/Lib/fontTools/feaLib/parser.py +++ b/Lib/fontTools/feaLib/parser.py @@ -192,19 +192,20 @@ class Parser(object): glyphs = set() location = self.cur_token_location_ while self.next_token_ != "]": - self.advance_lexer_() - if self.cur_token_type_ is Lexer.NAME: + if self.next_token_type_ is Lexer.NAME: + glyph = self.expect_glyph_() if self.next_token_ == "-": range_location = self.cur_token_location_ - range_start = self.cur_token_ + range_start = glyph self.expect_symbol_("-") - range_end = self.expect_name_() + range_end = self.expect_glyph_() glyphs.update(self.make_glyph_range_(range_location, range_start, range_end)) else: - glyphs.add(self.cur_token_) - elif self.cur_token_type_ is Lexer.CID: + glyphs.add(glyph) + elif self.next_token_type_ is Lexer.CID: + glyph = self.expect_glyph_() if self.next_token_ == "-": range_location = self.cur_token_location_ range_start = self.cur_token_ @@ -214,7 +215,8 @@ class Parser(object): range_start, range_end)) else: glyphs.add("cid%05d" % self.cur_token_) - elif self.cur_token_type_ is Lexer.GLYPHCLASS: + elif self.next_token_type_ is Lexer.GLYPHCLASS: + self.advance_lexer_() gc = self.glyphclasses_.resolve(self.cur_token_) if gc is None: raise FeatureLibError( @@ -225,7 +227,7 @@ class Parser(object): raise FeatureLibError( "Expected glyph name, glyph range, " "or glyph class reference", - self.cur_token_location_) + self.next_token_location_) self.expect_symbol_("]") return ast.GlyphClass(location, glyphs) @@ -876,6 +878,10 @@ class Parser(object): def expect_glyph_(self): self.advance_lexer_() if self.cur_token_type_ is Lexer.NAME: + if len(self.cur_token_) > 63: + raise FeatureLibError( + "Glyph names must not be longer than 63 characters", + self.cur_token_location_) return self.cur_token_ elif self.cur_token_type_ is Lexer.CID: return "cid%05d" % self.cur_token_ diff --git a/Lib/fontTools/feaLib/parser_test.py b/Lib/fontTools/feaLib/parser_test.py index f27163af9..1b7942b65 100644 --- a/Lib/fontTools/feaLib/parser_test.py +++ b/Lib/fontTools/feaLib/parser_test.py @@ -154,6 +154,11 @@ class ParserTest(unittest.TestCase): self.assertEqual(gc.name, "dash") self.assertEqual(gc.glyphs, {"endash", "emdash", "figuredash"}) + def test_glyphclass_glyphNameTooLong(self): + self.assertRaisesRegex( + FeatureLibError, "must not be longer than 63 characters", + self.parse, "@GlyphClass = [%s];" % ("G" * 64)) + def test_glyphclass_bad(self): self.assertRaisesRegex( FeatureLibError,