[Python-checkins] bpo-38588: Fix possible crashes in dict and list when calling PyObject_RichCompareBool (GH-17734)

Pablo Galindo webhook-mailer at python.org
Mon Dec 30 20:04:30 EST 2019


https://github.com/python/cpython/commit/2d5bf568eaa5059402ccce9ba5a366986ba27c8a
commit: 2d5bf568eaa5059402ccce9ba5a366986ba27c8a
branch: master
author: Dong-hee Na <donghee.na92 at gmail.com>
committer: Pablo Galindo <Pablogsal at gmail.com>
date: 2019年12月31日T01:04:22Z
summary:
bpo-38588: Fix possible crashes in dict and list when calling PyObject_RichCompareBool (GH-17734)
Take strong references before calling PyObject_RichCompareBool to protect against the case
where the object dies during the call.
files:
A Misc/NEWS.d/next/Core and Builtins/2019-12-29-19-13-54.bpo-38588.pgXnNS.rst
M Lib/test/test_dict.py
M Lib/test/test_list.py
M Objects/dictobject.c
M Objects/listobject.c
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index 5b513765f7b08..de483ab552155 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -1221,7 +1221,7 @@ def test_free_after_iterating(self):
 support.check_free_after_iterating(self, lambda d: iter(d.items()), dict)
 
 def test_equal_operator_modifying_operand(self):
- # test fix for seg fault reported in issue 27945 part 3.
+ # test fix for seg fault reported in bpo-27945 part 3.
 class X():
 def __del__(self):
 dict_b.clear()
@@ -1237,6 +1237,16 @@ def __hash__(self):
 dict_b = {X(): X()}
 self.assertTrue(dict_a == dict_b)
 
+ # test fix for seg fault reported in bpo-38588 part 1.
+ class Y:
+ def __eq__(self, other):
+ dict_d.clear()
+ return True
+
+ dict_c = {0: Y()}
+ dict_d = {0: set()}
+ self.assertTrue(dict_c == dict_d)
+
 def test_fromkeys_operator_modifying_dict_operand(self):
 # test fix for seg fault reported in issue 27945 part 4a.
 class X(int):
diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py
index b10a833033f15..6e3c4c109300e 100644
--- a/Lib/test/test_list.py
+++ b/Lib/test/test_list.py
@@ -163,6 +163,31 @@ class L(list): pass
 with self.assertRaises(TypeError):
 (3,) + L([1,2])
 
+ def test_equal_operator_modifying_operand(self):
+ # test fix for seg fault reported in bpo-38588 part 2.
+ class X:
+ def __eq__(self,other) :
+ list2.clear()
+ return NotImplemented
+
+ class Y:
+ def __eq__(self, other):
+ list1.clear()
+ return NotImplemented
+
+ class Z:
+ def __eq__(self, other):
+ list3.clear()
+ return NotImplemented
+
+ list1 = [X()]
+ list2 = [Y()]
+ self.assertTrue(list1 == list2)
+
+ list3 = [Z()]
+ list4 = [1]
+ self.assertFalse(list3 == list4)
+
 @cpython_only
 def test_preallocation(self):
 iterable = [0] * 10
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-12-29-19-13-54.bpo-38588.pgXnNS.rst b/Misc/NEWS.d/next/Core and Builtins/2019-12-29-19-13-54.bpo-38588.pgXnNS.rst
new file mode 100644
index 0000000000000..0b81085a89d25
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-12-29-19-13-54.bpo-38588.pgXnNS.rst	
@@ -0,0 +1,2 @@
+Fix possible crashes in dict and list when calling
+:c:func:`PyObject_RichCompareBool`.
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 4afa19c8a0a90..87f88abbe53bd 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -2777,9 +2777,11 @@ dict_equal(PyDictObject *a, PyDictObject *b)
 return -1;
 return 0;
 }
+ Py_INCREF(bval);
 cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
 Py_DECREF(key);
 Py_DECREF(aval);
+ Py_DECREF(bval);
 if (cmp <= 0) /* error or not equal */
 return cmp;
 }
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 86690f764b7db..abe2604573f95 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -2662,8 +2662,15 @@ list_richcompare(PyObject *v, PyObject *w, int op)
 
 /* Search for the first index where items are different */
 for (i = 0; i < Py_SIZE(vl) && i < Py_SIZE(wl); i++) {
+ PyObject *vitem = vl->ob_item[i];
+ PyObject *witem = wl->ob_item[i];
+
+ Py_INCREF(vitem);
+ Py_INCREF(witem);
 int k = PyObject_RichCompareBool(vl->ob_item[i],
 wl->ob_item[i], Py_EQ);
+ Py_DECREF(vitem);
+ Py_DECREF(witem);
 if (k < 0)
 return NULL;
 if (!k)


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /