From 7dd67a6193695f9def1ac2384d9ab0f71ea44c8b Mon Sep 17 00:00:00 2001 From: Uiri Date: Sat, 27 Oct 2018 00:35:14 -0400 Subject: [PATCH] Fix #217: dumps unable to detect circular refs If an object is passed to dumps, and that object has a circular reference, then dumps will raise a ValueError because an object with circular references cannot be encoded as valid TOML. --- tests/test_api.py | 13 +++++++++++++ toml/encoder.py | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 5f94778..f14057a 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -51,6 +51,19 @@ def test_valid_tests(): toml.dumps(toml.load(open(os.path.join(valid_dir, f)))) +def test_circular_ref(): + a = {} + b = {} + b['c'] = 4 + b['self'] = b + a['b'] = b + with pytest.raises(ValueError): + toml.dumps(a) + + with pytest.raises(ValueError): + toml.dumps(b) + + def test__dict(): class TestDict(dict): pass diff --git a/toml/encoder.py b/toml/encoder.py index 79bfd37..4b54afa 100644 --- a/toml/encoder.py +++ b/toml/encoder.py @@ -46,7 +46,13 @@ def dumps(o, encoder=None): encoder = TomlEncoder(o.__class__) addtoretval, sections = encoder.dump_sections(o, "") retval += addtoretval + outer_objs = [id(o)] while sections: + section_ids = [id(section) for section in sections] + for outer_obj in outer_objs: + if outer_obj in section_ids: + raise ValueError("Circular reference detected") + outer_objs += section_ids newsections = encoder.get_empty_table() for section in sections: addtoretval, addtosections = encoder.dump_sections(