From 6e96393a658985bad6c4b9a7c459055075479709 Mon Sep 17 00:00:00 2001 From: Mike Boers Date: Tue, 3 Nov 2015 14:13:57 -0800 Subject: [PATCH] Protect against infinite recursion --- sgschema/schema.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sgschema/schema.py b/sgschema/schema.py index 00947b2..d287e9f 100644 --- a/sgschema/schema.py +++ b/sgschema/schema.py @@ -436,7 +436,7 @@ def has_field(self, entity_type, field_spec, **kwargs): else: raise - def resolve_structure(self, x, entity_type=None, **kwargs): + def resolve_structure(self, x, entity_type=None, _seen=None, **kwargs): """Traverse a nested structure resolving names in entities. Recurses into ``list``, ``tuple`` and ``dict``, looking for ``dicts`` @@ -449,8 +449,16 @@ def resolve_structure(self, x, entity_type=None, **kwargs): """ + # Protect from infinite recursion. + if _seen is None: + _seen = set() + id_ = id(x) + if id_ in _seen: + return + _seen.add(id_) + if isinstance(x, (list, tuple)): - return type(x)(self.resolve_structure(x, **kwargs) for x in x) + return type(x)(self.resolve_structure(x, None, _seen, **kwargs) for x in x) elif isinstance(x, dict): entity_type = entity_type or x.get('type') @@ -463,7 +471,7 @@ def resolve_structure(self, x, entity_type=None, **kwargs): return new_values else: return { - k: self.resolve_structure(v, **kwargs) + k: self.resolve_structure(v, None, _seen, **kwargs) for k, v in x.iteritems() }