[feaLib] Reject script dflt and language DFLT

These are invalid casing variants of the frequently used
`script DFLT` and `language dflt`. Adobe's makeotf tool
does a similar check.
This commit is contained in:
Sascha Brawer 2015-09-08 09:26:24 +02:00
parent 20392fb491
commit 86004df3b0
2 changed files with 41 additions and 3 deletions

View File

@ -166,7 +166,8 @@ class Parser(object):
def parse_language_(self):
assert self.is_cur_keyword_("language")
location, language = self.cur_token_location_, self.expect_tag_()
location = self.cur_token_location_
language = self.expect_language_tag_()
include_default, required = (True, False)
if self.next_token_ in {"exclude_dflt", "include_dflt"}:
include_default = (self.expect_name_() == "include_dflt")
@ -201,7 +202,7 @@ class Parser(object):
def parse_script_(self):
assert self.is_cur_keyword_("script")
location, script = self.cur_token_location_, self.expect_tag_()
location, script = self.cur_token_location_, self.expect_script_tag_()
self.expect_symbol_(";")
return ast.ScriptStatement(location, script)
@ -294,7 +295,8 @@ class Parser(object):
def parse_languagesystem_(self):
assert self.cur_token_ == "languagesystem"
location = self.cur_token_location_
script, language = self.expect_tag_(), self.expect_tag_()
script = self.expect_script_tag_()
language = self.expect_language_tag_()
self.expect_symbol_(";")
if script == "DFLT" and language != "dflt":
raise FeatureLibError(
@ -371,6 +373,22 @@ class Parser(object):
self.cur_token_location_)
return (self.cur_token_ + " ")[:4]
def expect_script_tag_(self):
tag = self.expect_tag_()
if tag == "dflt":
raise FeatureLibError(
'"dflt" is not a valid script tag; use "DFLT" instead',
self.cur_token_location_)
return tag
def expect_language_tag_(self):
tag = self.expect_tag_()
if tag == "DFLT":
raise FeatureLibError(
'"DFLT" is not a valid language tag; use "dflt" instead',
self.cur_token_location_)
return tag
def expect_symbol_(self, symbol):
self.advance_lexer_()
if self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == symbol:

View File

@ -199,6 +199,12 @@ class ParserTest(unittest.TestCase):
self.assertTrue(s.include_default)
self.assertTrue(s.required)
def test_language_DFLT(self):
self.assertRaisesRegex(
FeatureLibError,
'"DFLT" is not a valid language tag; use "dflt" instead',
self.parse, "feature test { language DFLT; } test;")
def test_lookup_block(self):
[lookup] = self.parse("lookup Ligatures {} Ligatures;").statements
self.assertEqual(lookup.name, "Ligatures")
@ -256,6 +262,12 @@ class ParserTest(unittest.TestCase):
self.assertEqual(type(s), ast.ScriptStatement)
self.assertEqual(s.script, "cyrl")
def test_script_dflt(self):
self.assertRaisesRegex(
FeatureLibError,
'"dflt" is not a valid script tag; use "DFLT" instead',
self.parse, "feature test {script dflt;} test;")
def test_substitute_single_format_a(self): # GSUB LookupType 1
doc = self.parse("feature smcp {substitute a by a.sc;} smcp;")
sub = doc.statements[0].statements[0]
@ -398,6 +410,14 @@ class ParserTest(unittest.TestCase):
FeatureLibError,
'For script "DFLT", the language must be "dflt"',
self.parse, "languagesystem DFLT DEU;")
self.assertRaisesRegex(
FeatureLibError,
'"dflt" is not a valid script tag; use "DFLT" instead',
self.parse, "languagesystem dflt dflt;")
self.assertRaisesRegex(
FeatureLibError,
'"DFLT" is not a valid language tag; use "dflt" instead',
self.parse, "languagesystem latn DFLT;")
self.assertRaisesRegex(
FeatureLibError, "Expected ';'",
self.parse, "languagesystem latn DEU")