[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:
parent
20392fb491
commit
86004df3b0
@ -166,7 +166,8 @@ class Parser(object):
|
|||||||
|
|
||||||
def parse_language_(self):
|
def parse_language_(self):
|
||||||
assert self.is_cur_keyword_("language")
|
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)
|
include_default, required = (True, False)
|
||||||
if self.next_token_ in {"exclude_dflt", "include_dflt"}:
|
if self.next_token_ in {"exclude_dflt", "include_dflt"}:
|
||||||
include_default = (self.expect_name_() == "include_dflt")
|
include_default = (self.expect_name_() == "include_dflt")
|
||||||
@ -201,7 +202,7 @@ class Parser(object):
|
|||||||
|
|
||||||
def parse_script_(self):
|
def parse_script_(self):
|
||||||
assert self.is_cur_keyword_("script")
|
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_(";")
|
self.expect_symbol_(";")
|
||||||
return ast.ScriptStatement(location, script)
|
return ast.ScriptStatement(location, script)
|
||||||
|
|
||||||
@ -294,7 +295,8 @@ class Parser(object):
|
|||||||
def parse_languagesystem_(self):
|
def parse_languagesystem_(self):
|
||||||
assert self.cur_token_ == "languagesystem"
|
assert self.cur_token_ == "languagesystem"
|
||||||
location = self.cur_token_location_
|
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_(";")
|
self.expect_symbol_(";")
|
||||||
if script == "DFLT" and language != "dflt":
|
if script == "DFLT" and language != "dflt":
|
||||||
raise FeatureLibError(
|
raise FeatureLibError(
|
||||||
@ -371,6 +373,22 @@ class Parser(object):
|
|||||||
self.cur_token_location_)
|
self.cur_token_location_)
|
||||||
return (self.cur_token_ + " ")[:4]
|
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):
|
def expect_symbol_(self, symbol):
|
||||||
self.advance_lexer_()
|
self.advance_lexer_()
|
||||||
if self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == symbol:
|
if self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == symbol:
|
||||||
|
@ -199,6 +199,12 @@ class ParserTest(unittest.TestCase):
|
|||||||
self.assertTrue(s.include_default)
|
self.assertTrue(s.include_default)
|
||||||
self.assertTrue(s.required)
|
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):
|
def test_lookup_block(self):
|
||||||
[lookup] = self.parse("lookup Ligatures {} Ligatures;").statements
|
[lookup] = self.parse("lookup Ligatures {} Ligatures;").statements
|
||||||
self.assertEqual(lookup.name, "Ligatures")
|
self.assertEqual(lookup.name, "Ligatures")
|
||||||
@ -256,6 +262,12 @@ class ParserTest(unittest.TestCase):
|
|||||||
self.assertEqual(type(s), ast.ScriptStatement)
|
self.assertEqual(type(s), ast.ScriptStatement)
|
||||||
self.assertEqual(s.script, "cyrl")
|
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
|
def test_substitute_single_format_a(self): # GSUB LookupType 1
|
||||||
doc = self.parse("feature smcp {substitute a by a.sc;} smcp;")
|
doc = self.parse("feature smcp {substitute a by a.sc;} smcp;")
|
||||||
sub = doc.statements[0].statements[0]
|
sub = doc.statements[0].statements[0]
|
||||||
@ -398,6 +410,14 @@ class ParserTest(unittest.TestCase):
|
|||||||
FeatureLibError,
|
FeatureLibError,
|
||||||
'For script "DFLT", the language must be "dflt"',
|
'For script "DFLT", the language must be "dflt"',
|
||||||
self.parse, "languagesystem DFLT DEU;")
|
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(
|
self.assertRaisesRegex(
|
||||||
FeatureLibError, "Expected ';'",
|
FeatureLibError, "Expected ';'",
|
||||||
self.parse, "languagesystem latn DEU")
|
self.parse, "languagesystem latn DEU")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user