mirror of
https://github.com/facebook/proxygen.git
synced 2025-08-07 07:02:53 +03:00
fail if unknown variables are used in a manifest
Summary: Check that all variable names are valid when loading manifest files. This ensures that getdeps.py will error out if someone makes a typo in a variable name, rather than treating it as never equal to anything. Reviewed By: pkaush Differential Revision: D16477397 fbshipit-source-id: 030e0642ff4a08db8eb74a0a0223e03d53e4880f
This commit is contained in:
committed by
Facebook Github Bot
parent
55fb767d25
commit
7844e79b03
@@ -12,7 +12,7 @@ import re
|
|||||||
import shlex
|
import shlex
|
||||||
|
|
||||||
|
|
||||||
def parse_expr(expr_text):
|
def parse_expr(expr_text, valid_variables):
|
||||||
""" parses the simple criteria expression syntax used in
|
""" parses the simple criteria expression syntax used in
|
||||||
dependency specifications.
|
dependency specifications.
|
||||||
Returns an ExprNode instance that can be evaluated like this:
|
Returns an ExprNode instance that can be evaluated like this:
|
||||||
@@ -37,7 +37,7 @@ def parse_expr(expr_text):
|
|||||||
# none of them evaluated true.
|
# none of them evaluated true.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
p = Parser(expr_text)
|
p = Parser(expr_text, valid_variables)
|
||||||
return p.parse()
|
return p.parse()
|
||||||
|
|
||||||
|
|
||||||
@@ -112,9 +112,10 @@ class EqualExpr(ExprNode):
|
|||||||
|
|
||||||
|
|
||||||
class Parser(object):
|
class Parser(object):
|
||||||
def __init__(self, text):
|
def __init__(self, text, valid_variables):
|
||||||
self.text = text
|
self.text = text
|
||||||
self.lex = shlex.shlex(text)
|
self.lex = shlex.shlex(text)
|
||||||
|
self.valid_variables = valid_variables
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
expr = self.top()
|
expr = self.top()
|
||||||
@@ -141,6 +142,8 @@ class Parser(object):
|
|||||||
return func()
|
return func()
|
||||||
|
|
||||||
if op == "=":
|
if op == "=":
|
||||||
|
if name not in self.valid_variables:
|
||||||
|
raise Exception("unknown variable %r in expression" % (name,))
|
||||||
return EqualExpr(name, self.lex.get_token())
|
return EqualExpr(name, self.lex.get_token())
|
||||||
|
|
||||||
raise Exception(
|
raise Exception(
|
||||||
|
@@ -88,10 +88,12 @@ ALLOWED_EXPR_SECTIONS = [
|
|||||||
"install.files",
|
"install.files",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
ALLOWED_VARIABLES = {"os", "distro", "distro_vers", "fb", "test"}
|
||||||
|
|
||||||
|
|
||||||
def parse_conditional_section_name(name, section_def):
|
def parse_conditional_section_name(name, section_def):
|
||||||
expr = name[len(section_def) + 1 :]
|
expr = name[len(section_def) + 1 :]
|
||||||
return parse_expr(expr)
|
return parse_expr(expr, ALLOWED_VARIABLES)
|
||||||
|
|
||||||
|
|
||||||
def validate_allowed_fields(file_name, section, config, allowed_fields):
|
def validate_allowed_fields(file_name, section, config, allowed_fields):
|
||||||
|
@@ -15,28 +15,38 @@ from ..expr import parse_expr
|
|||||||
|
|
||||||
class ExprTest(unittest.TestCase):
|
class ExprTest(unittest.TestCase):
|
||||||
def test_equal(self):
|
def test_equal(self):
|
||||||
e = parse_expr("foo=bar")
|
valid_variables = {"foo", "some_var", "another_var"}
|
||||||
|
e = parse_expr("foo=bar", valid_variables)
|
||||||
self.assertTrue(e.eval({"foo": "bar"}))
|
self.assertTrue(e.eval({"foo": "bar"}))
|
||||||
self.assertFalse(e.eval({"foo": "not-bar"}))
|
self.assertFalse(e.eval({"foo": "not-bar"}))
|
||||||
self.assertFalse(e.eval({"not-foo": "bar"}))
|
self.assertFalse(e.eval({"not-foo": "bar"}))
|
||||||
|
|
||||||
def test_not_equal(self):
|
def test_not_equal(self):
|
||||||
e = parse_expr("not(foo=bar)")
|
valid_variables = {"foo"}
|
||||||
|
e = parse_expr("not(foo=bar)", valid_variables)
|
||||||
self.assertFalse(e.eval({"foo": "bar"}))
|
self.assertFalse(e.eval({"foo": "bar"}))
|
||||||
self.assertTrue(e.eval({"foo": "not-bar"}))
|
self.assertTrue(e.eval({"foo": "not-bar"}))
|
||||||
|
|
||||||
def test_bad_not(self):
|
def test_bad_not(self):
|
||||||
|
valid_variables = {"foo"}
|
||||||
with self.assertRaises(Exception):
|
with self.assertRaises(Exception):
|
||||||
parse_expr("foo=not(bar)")
|
parse_expr("foo=not(bar)", valid_variables)
|
||||||
|
|
||||||
|
def test_bad_variable(self):
|
||||||
|
valid_variables = {"bar"}
|
||||||
|
with self.assertRaises(Exception):
|
||||||
|
parse_expr("foo=bar", valid_variables)
|
||||||
|
|
||||||
def test_all(self):
|
def test_all(self):
|
||||||
e = parse_expr("all(foo = bar, baz = qux)")
|
valid_variables = {"foo", "baz"}
|
||||||
|
e = parse_expr("all(foo = bar, baz = qux)", valid_variables)
|
||||||
self.assertTrue(e.eval({"foo": "bar", "baz": "qux"}))
|
self.assertTrue(e.eval({"foo": "bar", "baz": "qux"}))
|
||||||
self.assertFalse(e.eval({"foo": "bar", "baz": "nope"}))
|
self.assertFalse(e.eval({"foo": "bar", "baz": "nope"}))
|
||||||
self.assertFalse(e.eval({"foo": "nope", "baz": "nope"}))
|
self.assertFalse(e.eval({"foo": "nope", "baz": "nope"}))
|
||||||
|
|
||||||
def test_any(self):
|
def test_any(self):
|
||||||
e = parse_expr("any(foo = bar, baz = qux)")
|
valid_variables = {"foo", "baz"}
|
||||||
|
e = parse_expr("any(foo = bar, baz = qux)", valid_variables)
|
||||||
self.assertTrue(e.eval({"foo": "bar", "baz": "qux"}))
|
self.assertTrue(e.eval({"foo": "bar", "baz": "qux"}))
|
||||||
self.assertTrue(e.eval({"foo": "bar", "baz": "nope"}))
|
self.assertTrue(e.eval({"foo": "bar", "baz": "nope"}))
|
||||||
self.assertFalse(e.eval({"foo": "nope", "baz": "nope"}))
|
self.assertFalse(e.eval({"foo": "nope", "baz": "nope"}))
|
||||||
|
@@ -142,16 +142,16 @@ a
|
|||||||
b
|
b
|
||||||
c
|
c
|
||||||
|
|
||||||
[dependencies.foo=bar]
|
[dependencies.test=on]
|
||||||
foo
|
foo
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
self.assertEqual(p.get_section_as_args("dependencies"), ["a", "b", "c"])
|
self.assertEqual(p.get_section_as_args("dependencies"), ["a", "b", "c"])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
p.get_section_as_args("dependencies", {"foo": "not-bar"}), ["a", "b", "c"]
|
p.get_section_as_args("dependencies", {"test": "off"}), ["a", "b", "c"]
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
p.get_section_as_args("dependencies", {"foo": "bar"}),
|
p.get_section_as_args("dependencies", {"test": "on"}),
|
||||||
["a", "b", "c", "foo"],
|
["a", "b", "c", "foo"],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -180,13 +180,13 @@ name = foo
|
|||||||
[cmake.defines]
|
[cmake.defines]
|
||||||
foo = bar
|
foo = bar
|
||||||
|
|
||||||
[cmake.defines.bar=baz]
|
[cmake.defines.test=on]
|
||||||
foo = baz
|
foo = baz
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
self.assertEqual(p.get_section_as_dict("cmake.defines"), {"foo": "bar"})
|
self.assertEqual(p.get_section_as_dict("cmake.defines"), {"foo": "bar"})
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
p.get_section_as_dict("cmake.defines", {"bar": "baz"}), {"foo": "baz"}
|
p.get_section_as_dict("cmake.defines", {"test": "on"}), {"foo": "baz"}
|
||||||
)
|
)
|
||||||
|
|
||||||
p2 = ManifestParser(
|
p2 = ManifestParser(
|
||||||
@@ -195,7 +195,7 @@ foo = baz
|
|||||||
[manifest]
|
[manifest]
|
||||||
name = foo
|
name = foo
|
||||||
|
|
||||||
[cmake.defines.bar=baz]
|
[cmake.defines.test=on]
|
||||||
foo = baz
|
foo = baz
|
||||||
|
|
||||||
[cmake.defines]
|
[cmake.defines]
|
||||||
@@ -203,7 +203,7 @@ foo = bar
|
|||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
p2.get_section_as_dict("cmake.defines", {"bar": "baz"}),
|
p2.get_section_as_dict("cmake.defines", {"test": "on"}),
|
||||||
{"foo": "bar"},
|
{"foo": "bar"},
|
||||||
msg="sections cascade in the order they appear in the manifest",
|
msg="sections cascade in the order they appear in the manifest",
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user