cpython: Objects/dictobject.c diff (original) (raw)
Mercurial > cpython
diff Objects/dictobject.c @ 18023:8d2bbbbf2cb9 legacy-trunk
lookdict: stop more insane core-dump mutating comparison cases. Should be possible to provoke unbounded recursion now, but leaving that to someone else to provoke and repair. Bugfix candidate -- although this is getting harder to backstitch, and the cases it's protecting against are mondo contrived.
author | Tim Peters tim.peters@gmail.com |
---|---|
date | Sun, 03 Jun 2001 04:54:32 +0000 |
parents | bd1c4fe977cb |
children | b99979d0f9e7 |
line wrap: on
line diff
--- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -255,6 +255,7 @@ lookdict(dictobject *mp, PyObject *key, register int checked_error; register int cmp; PyObject *err_type, *err_value, *err_tb; + PyObject *startkey; i = hash & mask; ep = &ep0[i]; @@ -272,11 +273,23 @@ lookdict(dictobject *mp, PyObject key, restore_error = 1; PyErr_Fetch(&err_type, &err_value, &err_tb); } - cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ); - if (cmp > 0) - goto Done; + startkey = ep->me_key; + cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); if (cmp < 0) PyErr_Clear(); + if (ep0 == mp->ma_table && ep->me_key == startkey) { + if (cmp > 0) + goto Done; + } + else { + / The compare did major nasty stuff to the + * dict: start over. + * XXX A clever adversary could prevent this + * XXX from terminating.
*/[](#l1.31)
ep = lookdict(mp, key, hash);[](#l1.32)
goto Done;[](#l1.33)
} @@ -302,11 +315,23 @@ lookdict(dictobject *mp, PyObject *key, &err_tb); } }}[](#l1.34) }[](#l1.35) freeslot = NULL;[](#l1.36)
cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ);[](#l1.42)
if (cmp > 0)[](#l1.43)
break;[](#l1.44)
startkey = ep->me_key;[](#l1.45)
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);[](#l1.46) if (cmp < 0)[](#l1.47) PyErr_Clear();[](#l1.48)
if (ep0 == mp->ma_table && ep->me_key == startkey) {[](#l1.49)
if (cmp > 0)[](#l1.50)
break;[](#l1.51)
}[](#l1.52)
else {[](#l1.53)
/* The compare did major nasty stuff to the[](#l1.54)
* dict: start over.[](#l1.55)
* XXX A clever adversary could prevent this[](#l1.56)
* XXX from terminating.[](#l1.57)
*/[](#l1.58)
ep = lookdict(mp, key, hash);[](#l1.59)
break;[](#l1.60)
}[](#l1.61) }[](#l1.62) else if (ep->me_key == dummy && freeslot == NULL)[](#l1.63) freeslot = ep;[](#l1.64)