summaryrefslogtreecommitdiffstats
path: root/Objects/dictobject.c
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-06-03 04:54:32 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-06-03 04:54:32 (GMT)
commit453163d842568dd066cfb5f047f3948d177743d7 (patch)
tree79d56026ba883ec59810d1eb8dfa476d10ddb39a /Objects/dictobject.c
parent7b5d0afb1ec0e9cc10e74779d0e80bb1bee83577 (diff)
downloadcpython-453163d842568dd066cfb5f047f3948d177743d7.zip
cpython-453163d842568dd066cfb5f047f3948d177743d7.tar.gz
cpython-453163d842568dd066cfb5f047f3948d177743d7.tar.bz2
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.
Diffstat (limited to 'Objects/dictobject.c')
-rw-r--r--Objects/dictobject.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 69fe67e..ce44abe 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -255,6 +255,7 @@ lookdict(dictobject *mp, PyObject *key, register long hash)
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, register long hash)
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.
+ */
+ ep = lookdict(mp, key, hash);
+ goto Done;
+ }
}
freeslot = NULL;
}
@@ -302,11 +315,23 @@ lookdict(dictobject *mp, PyObject *key, register long hash)
&err_tb);
}
}
- cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ);
- if (cmp > 0)
- break;
+ 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)
+ break;
+ }
+ else {
+ /* The compare did major nasty stuff to the
+ * dict: start over.
+ * XXX A clever adversary could prevent this
+ * XXX from terminating.
+ */
+ ep = lookdict(mp, key, hash);
+ break;
+ }
}
else if (ep->me_key == dummy && freeslot == NULL)
freeslot = ep;