From 1839235d220e29b58e2af755281dee43e9c4fcb4 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 19 Oct 2019 15:59:05 +0100 Subject: [PATCH] bpo-38525: Fix segfault when using reverse iterators of empty dict literals --- Lib/test/test_dict.py | 13 +++++++++++++ .../2019-10-19-15-58-26.bpo-38525.rmOpTg.rst | 2 ++ Objects/dictobject.c | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-10-19-15-58-26.bpo-38525.rmOpTg.rst diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 13be857f7ab607f..ceebb50f15c2361 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1154,6 +1154,19 @@ def test_reversevaluesiterator_pickling(self): values = list(it) + [drop] self.assertEqual(sorted(values), sorted(data.values())) + def test_reverseiterator_empty_dict(self): + # Check bpo-38525 + + the_dict = {} + self.assertEqual(list(reversed(the_dict)), list()) + self.assertEqual(list(reversed(the_dict.values())), list()) + self.assertEqual(list(reversed(the_dict.keys())), list()) + + the_dict = dict() + self.assertEqual(list(reversed(the_dict)), list()) + self.assertEqual(list(reversed(the_dict.values())), list()) + self.assertEqual(list(reversed(the_dict.keys())), list()) + def test_instance_dict_getattr_str_subclass(self): class Foo: def __init__(self, msg): diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-19-15-58-26.bpo-38525.rmOpTg.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-19-15-58-26.bpo-38525.rmOpTg.rst new file mode 100644 index 000000000000000..977623663309ed0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-10-19-15-58-26.bpo-38525.rmOpTg.rst @@ -0,0 +1,2 @@ +Fix a segmentation fault when using reverse iterators of empty ``dict`` +objects that were created as empty dict literals. Patch by Pablo Galindo. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 64876e05191e237..d694d193023fa70 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -3826,7 +3826,7 @@ dictreviter_iternext(dictiterobject *di) PyObject *key, *value, *result; if (d->ma_values) { - if (i < 0) { + if (i < 0 || i >= d->ma_used) { goto fail; } key = DK_ENTRIES(k)[i].me_key;