Bug 1429669 - Recursively check identifiers in schema validation. r=dustin

The taskgraph.util.schema.check_schema function validates key names used
in schemas, ensuring they are dashed lower-case. However, it currently
assumes keys are either direct strings, Required or Optional entries,
and either ignores or fails to recognize other patterns.

For example, it ignores Any, and fails to recognize combinations like
Required(Any(...)), which we're going to use in next patch.

--HG--
extra : rebase_source : 4f6ff51a4a9dc9c7d9b6d070e03c6cc6e1befe80
This commit is contained in:
Mike Hommey 2018-01-11 09:29:19 +09:00
Родитель 0f364f58ca
Коммит dc613af2d0
1 изменённых файлов: 19 добавлений и 7 удалений

Просмотреть файл

@ -161,16 +161,28 @@ def check_schema(schema):
return any(f(path) for f in WHITELISTED_SCHEMA_IDENTIFIERS)
def iter(path, sch):
def check_identifier(path, k):
if k in (basestring, voluptuous.Extra):
pass
elif isinstance(k, basestring):
if not identifier_re.match(k) and not whitelisted(path):
raise RuntimeError(
'YAML schemas should use dashed lower-case identifiers, '
'not {!r} @ {}'.format(k, path))
elif isinstance(k, (voluptuous.Optional, voluptuous.Required)):
check_identifier(path, k.schema)
elif isinstance(k, voluptuous.Any):
for v in k.validators:
check_identifier(path, v)
elif not whitelisted(path):
raise RuntimeError(
'Unexpected type in YAML schema: {} @ {}'.format(
type(k).__name__, path))
if isinstance(sch, collections.Mapping):
for k, v in sch.iteritems():
child = "{}[{!r}]".format(path, k)
if isinstance(k, (voluptuous.Optional, voluptuous.Required)):
k = str(k)
if isinstance(k, basestring):
if not identifier_re.match(k) and not whitelisted(child):
raise RuntimeError(
'YAML schemas should use dashed lower-case identifiers, '
'not {!r} @ {}'.format(k, child))
check_identifier(child, k)
iter(child, v)
elif isinstance(sch, (list, tuple)):
for i, v in enumerate(sch):