[Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.101,2.102
Tim Peters
tim_one@users.sourceforge.net
2001年6月02日 21:54:34 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv9638/python/dist/src/Objects
Modified Files:
dictobject.c
Log Message:
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.
Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.101
retrieving revision 2.102
diff -C2 -r2.101 -r2.102
*** dictobject.c 2001年06月03日 04:14:43 2.101
--- dictobject.c 2001年06月03日 04:54:32 2.102
***************
*** 256,259 ****
--- 256,260 ----
register int cmp;
PyObject *err_type, *err_value, *err_tb;
+ PyObject *startkey;
i = hash & mask;
***************
*** 273,281 ****
PyErr_Fetch(&err_type, &err_value, &err_tb);
}
! cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ);
! if (cmp > 0)
! goto Done;
if (cmp < 0)
PyErr_Clear();
}
freeslot = NULL;
--- 274,294 ----
PyErr_Fetch(&err_type, &err_value, &err_tb);
}
! 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;
***************
*** 303,311 ****
}
}
! cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ);
! if (cmp > 0)
! break;
if (cmp < 0)
PyErr_Clear();
}
else if (ep->me_key == dummy && freeslot == NULL)
--- 316,336 ----
}
}
! 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)