Mojo: Mojom: Detect (lexically) bad or missing ordinals.

(Explicitly disallow octal and hexadecimal ordinals.)

R=darin@chromium.org

Review URL: https://codereview.chromium.org/217093002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260355 0039d316-1c4b-4281-b951-d872f2087c98
parent 54f0cc8d
...@@ -161,6 +161,13 @@ class Lexer(object): ...@@ -161,6 +161,13 @@ class Lexer(object):
'('+hex_prefix+'('+hex_digits+'|'+hex_fractional_constant+')'+ \ '('+hex_prefix+'('+hex_digits+'|'+hex_fractional_constant+')'+ \
binary_exponent_part+'[FfLl]?)' binary_exponent_part+'[FfLl]?)'
# Ordinals
ordinal = r'@[0-9]+'
missing_ordinal_value = r'@'
# Don't allow ordinal values in octal (even invalid octal, like 09) or
# hexadecimal.
octal_or_hex_ordinal_disallowed = r'@((0[0-9]+)|('+hex_prefix+hex_digits+'))'
## ##
## Rules for the normal state ## Rules for the normal state
## ##
...@@ -204,7 +211,6 @@ class Lexer(object): ...@@ -204,7 +211,6 @@ class Lexer(object):
t_SEMI = r';' t_SEMI = r';'
t_STRING_LITERAL = string_literal t_STRING_LITERAL = string_literal
t_ORDINAL = r'@[0-9]*'
# The following floating and integer constants are defined as # The following floating and integer constants are defined as
# functions to impose a strict order (otherwise, decimal # functions to impose a strict order (otherwise, decimal
...@@ -260,6 +266,21 @@ class Lexer(object): ...@@ -260,6 +266,21 @@ class Lexer(object):
msg = "String contains invalid escape code" msg = "String contains invalid escape code"
self._error(msg, t) self._error(msg, t)
# Handle ordinal-related tokens in the right order:
@TOKEN(octal_or_hex_ordinal_disallowed)
def t_OCTAL_OR_HEX_ORDINAL_DISALLOWED(self, t):
msg = "Octal and hexadecimal ordinal values not allowed"
self._error(msg, t)
@TOKEN(ordinal)
def t_ORDINAL(self, t):
return t
@TOKEN(missing_ordinal_value)
def t_BAD_ORDINAL(self, t):
msg = "Missing ordinal value"
self._error(msg, t)
@TOKEN(identifier) @TOKEN(identifier)
def t_NAME(self, t): def t_NAME(self, t):
t.type = self.keyword_map.get(t.value, "NAME") t.type = self.keyword_map.get(t.value, "NAME")
......
...@@ -83,7 +83,6 @@ enum MyEnum { ...@@ -83,7 +83,6 @@ enum MyEnum {
} // my_module } // my_module
""" """
self.maxDiff = 2000
expected = \ expected = \
[('MODULE', [('MODULE',
'my_module', 'my_module',
...@@ -133,6 +132,99 @@ enum MyEnum { ...@@ -133,6 +132,99 @@ enum MyEnum {
r"^my_file\.mojom:4: Error: Illegal character '\?'$"): r"^my_file\.mojom:4: Error: Illegal character '\?'$"):
mojo_parser.Parse(source, "my_file.mojom") mojo_parser.Parse(source, "my_file.mojom")
def testSimpleOrdinals(self):
"""Tests that (valid) ordinal values are scanned correctly."""
source = """\
module my_module {
// This isn't actually valid .mojom, but the problem (missing ordinals) should
// be handled at a different level.
struct MyStruct {
int32 a0 @0;
int32 a1 @1;
int32 a2 @2;
int32 a9 @9;
int32 a10 @10;
int32 a11 @11;
int32 a29 @29;
int32 a1234567890 @1234567890;
};
} // module my_module
"""
expected = \
[('MODULE',
'my_module',
[('STRUCT',
'MyStruct',
None,
[('FIELD', 'int32', 'a0', '@0', None),
('FIELD', 'int32', 'a1', '@1', None),
('FIELD', 'int32', 'a2', '@2', None),
('FIELD', 'int32', 'a9', '@9', None),
('FIELD', 'int32', 'a10', '@10', None),
('FIELD', 'int32', 'a11', '@11', None),
('FIELD', 'int32', 'a29', '@29', None),
('FIELD', 'int32', 'a1234567890', '@1234567890', None)])])]
self.assertEquals(mojo_parser.Parse(source, "my_file.mojom"), expected)
def testInvalidOrdinals(self):
"""Tests that (lexically) invalid ordinals are correctly detected."""
source1 = """\
module my_module {
struct MyStruct {
int32 a_missing @;
};
} // module my_module
"""
with self.assertRaisesRegexp(
mojo_lexer.LexError,
r"^my_file\.mojom:4: Error: Missing ordinal value$"):
mojo_parser.Parse(source1, "my_file.mojom")
source2 = """\
module my_module {
struct MyStruct {
int32 a_octal @01;
};
} // module my_module
"""
with self.assertRaisesRegexp(
mojo_lexer.LexError,
r"^my_file\.mojom:4: Error: "
r"Octal and hexadecimal ordinal values not allowed$"):
mojo_parser.Parse(source2, "my_file.mojom")
source3 = """\
module my_module { struct MyStruct { int32 a_invalid_octal @08; }; }
"""
with self.assertRaisesRegexp(
mojo_lexer.LexError,
r"^my_file\.mojom:1: Error: "
r"Octal and hexadecimal ordinal values not allowed$"):
mojo_parser.Parse(source3, "my_file.mojom")
source4 = """\
module my_module { struct MyStruct { int32 a_hex @0x1aB9; }; }
"""
with self.assertRaisesRegexp(
mojo_lexer.LexError,
r"^my_file\.mojom:1: Error: "
r"Octal and hexadecimal ordinal values not allowed$"):
mojo_parser.Parse(source4, "my_file.mojom")
source5 = """\
module my_module { struct MyStruct { int32 a_hex @0X0; }; }
"""
with self.assertRaisesRegexp(
mojo_lexer.LexError,
r"^my_file\.mojom:1: Error: "
r"Octal and hexadecimal ordinal values not allowed$"):
mojo_parser.Parse(source5, "my_file.mojom")
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment