diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2020-01-23 14:07:05 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-23 14:07:05 (GMT) |
commit | 79f89e6e5a659846d1068e8b1bd8e491ccdef861 (patch) | |
tree | 41fe7cc643fe8134ca35430345c0ee76991f89b6 /Modules/_heapqmodule.c | |
parent | 13bc13960cc83dbd1cb5701d9a59ac9b9144b205 (diff) | |
download | cpython-79f89e6e5a659846d1068e8b1bd8e491ccdef861.zip cpython-79f89e6e5a659846d1068e8b1bd8e491ccdef861.tar.gz cpython-79f89e6e5a659846d1068e8b1bd8e491ccdef861.tar.bz2 |
bpo-39421: Fix posible crash in heapq with custom comparison operators (GH-18118)
* bpo-39421: Fix posible crash in heapq with custom comparison operators
* fixup! bpo-39421: Fix posible crash in heapq with custom comparison operators
* fixup! fixup! bpo-39421: Fix posible crash in heapq with custom comparison operators
Diffstat (limited to 'Modules/_heapqmodule.c')
-rw-r--r-- | Modules/_heapqmodule.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c index a84cade..6bc18b5 100644 --- a/Modules/_heapqmodule.c +++ b/Modules/_heapqmodule.c @@ -36,7 +36,11 @@ siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) while (pos > startpos) { parentpos = (pos - 1) >> 1; parent = arr[parentpos]; + Py_INCREF(newitem); + Py_INCREF(parent); cmp = PyObject_RichCompareBool(newitem, parent, Py_LT); + Py_DECREF(parent); + Py_DECREF(newitem); if (cmp < 0) return -1; if (size != PyList_GET_SIZE(heap)) { @@ -78,10 +82,13 @@ siftup(PyListObject *heap, Py_ssize_t pos) /* Set childpos to index of smaller child. */ childpos = 2*pos + 1; /* leftmost child position */ if (childpos + 1 < endpos) { - cmp = PyObject_RichCompareBool( - arr[childpos], - arr[childpos + 1], - Py_LT); + PyObject* a = arr[childpos]; + PyObject* b = arr[childpos + 1]; + Py_INCREF(a); + Py_INCREF(b); + cmp = PyObject_RichCompareBool(a, b, Py_LT); + Py_DECREF(a); + Py_DECREF(b); if (cmp < 0) return -1; childpos += ((unsigned)cmp ^ 1); /* increment when cmp==0 */ @@ -264,7 +271,10 @@ _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) return item; } - cmp = PyObject_RichCompareBool(PyList_GET_ITEM(heap, 0), item, Py_LT); + PyObject* top = PyList_GET_ITEM(heap, 0); + Py_INCREF(top); + cmp = PyObject_RichCompareBool(top, item, Py_LT); + Py_DECREF(top); if (cmp < 0) return NULL; if (cmp == 0) { @@ -420,7 +430,11 @@ siftdown_max(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) while (pos > startpos) { parentpos = (pos - 1) >> 1; parent = arr[parentpos]; + Py_INCREF(parent); + Py_INCREF(newitem); cmp = PyObject_RichCompareBool(parent, newitem, Py_LT); + Py_DECREF(parent); + Py_DECREF(newitem); if (cmp < 0) return -1; if (size != PyList_GET_SIZE(heap)) { @@ -462,10 +476,13 @@ siftup_max(PyListObject *heap, Py_ssize_t pos) /* Set childpos to index of smaller child. */ childpos = 2*pos + 1; /* leftmost child position */ if (childpos + 1 < endpos) { - cmp = PyObject_RichCompareBool( - arr[childpos + 1], - arr[childpos], - Py_LT); + PyObject* a = arr[childpos + 1]; + PyObject* b = arr[childpos]; + Py_INCREF(a); + Py_INCREF(b); + cmp = PyObject_RichCompareBool(a, b, Py_LT); + Py_DECREF(a); + Py_DECREF(b); if (cmp < 0) return -1; childpos += ((unsigned)cmp ^ 1); /* increment when cmp==0 */ |