Commit 6600ecce authored by Jim Fulton's avatar Jim Fulton

Bug Fixed

- BTrees allowed object keys with insane comparison. (Comparison
  inherited from object, which compares based on in-process address.)
  Now BTrees raise TypeError is an attempt is made to save a key with
  comparison inherited from object. (This doesn't apply to old-style
  class instances.)
parent 0e2bcbd7
...@@ -465,6 +465,12 @@ INITMODULE (void) ...@@ -465,6 +465,12 @@ INITMODULE (void)
{ {
PyObject *m, *d, *c; PyObject *m, *d, *c;
#ifdef KEY_TYPE_IS_PYOBJECT
object_ = PyTuple_GetItem(Py_None->ob_type->tp_bases, 0);
if (object_ == NULL)
return;
#endif
sort_str = PyString_InternFromString("sort"); sort_str = PyString_InternFromString("sort");
if (!sort_str) if (!sort_str)
return; return;
......
#define KEYMACROS_H "$Id$\n" #define KEYMACROS_H "$Id$\n"
#define KEY_TYPE PyObject * #define KEY_TYPE PyObject *
#define KEY_TYPE_IS_PYOBJECT #define KEY_TYPE_IS_PYOBJECT
#include "Python.h"
static PyObject *object_;
static int
check_argument_cmp(PyObject *arg)
{
if (arg->ob_type->tp_richcompare == NULL
&&
arg->ob_type->tp_compare ==
((PyTypeObject *)object_)->ob_type->tp_compare
)
{
PyErr_SetString(PyExc_TypeError, "Object has default comparison");
return 0;
}
return 1;
}
#define TEST_KEY_SET_OR(V, KEY, TARGET) if ( ( (V) = PyObject_Compare((KEY),(TARGET)) ), PyErr_Occurred() ) #define TEST_KEY_SET_OR(V, KEY, TARGET) if ( ( (V) = PyObject_Compare((KEY),(TARGET)) ), PyErr_Occurred() )
#define INCREF_KEY(k) Py_INCREF(k) #define INCREF_KEY(k) Py_INCREF(k)
#define DECREF_KEY(KEY) Py_DECREF(KEY) #define DECREF_KEY(KEY) Py_DECREF(KEY)
#define COPY_KEY(KEY, E) KEY=(E) #define COPY_KEY(KEY, E) KEY=(E)
#define COPY_KEY_TO_OBJECT(O, K) O=(K); Py_INCREF(O) #define COPY_KEY_TO_OBJECT(O, K) O=(K); Py_INCREF(O)
#define COPY_KEY_FROM_ARG(TARGET, ARG, S) TARGET=(ARG) #define COPY_KEY_FROM_ARG(TARGET, ARG, S) \
TARGET=(ARG); \
(S) = check_argument_cmp(ARG);
...@@ -1884,6 +1884,39 @@ class OOBTreeTest(BTreeTests): ...@@ -1884,6 +1884,39 @@ class OOBTreeTest(BTreeTests):
def setUp(self): def setUp(self):
self.t = OOBTree() self.t = OOBTree()
def testRejectDefaultComparison(self):
# Check that passing int keys w default comparison fails.
# Only applies to new-style class instances. Old-style
# instances are too hard to introspect.
# This is white box because we know that the check is being
# used in a function that's used in lots of places.
# Otherwise, there are many permutations that would have to be
# checked.
class C(object):
pass
self.assertRaises(TypeError, lambda : self.t.__setitem__(C(), 1))
class C(object):
def __cmp__(*args):
return 1
c = C()
self.t[c] = 1
self.t.clear()
class C(object):
def __lt__(*args):
return 1
c = C()
self.t[c] = 1
self.t.clear()
if using64bits: if using64bits:
class IIBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues): class IIBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues):
def setUp(self): def setUp(self):
...@@ -1922,9 +1955,6 @@ class OLBTreeTest(BTreeTests, TestLongIntValues): ...@@ -1922,9 +1955,6 @@ class OLBTreeTest(BTreeTests, TestLongIntValues):
self.t = OLBTree() self.t = OLBTree()
def getTwoKeys(self): def getTwoKeys(self):
return object(), object() return object(), object()
class OOBTreeTest(BTreeTests):
def setUp(self):
self.t = OOBTree()
# cmp error propagation tests # cmp error propagation tests
......
...@@ -2,6 +2,18 @@ ...@@ -2,6 +2,18 @@
Change History Change History
================ ================
3.11.0 (2010-??-??)
===================
Bugs Fixed
----------
- BTrees allowed object keys with insane comparison. (Comparison
inherited from object, which compares based on in-process address.)
Now BTrees raise TypeError is an attempt is made to save a key with
comparison inherited from object. (This doesn't apply to old-style
class instances.)
3.10.1 (2010-10-??) 3.10.1 (2010-10-??)
=================== ===================
......
...@@ -65,6 +65,11 @@ use: ...@@ -65,6 +65,11 @@ use:
from persistent import Persistent from persistent import Persistent
class PCounter(Persistent): class PCounter(Persistent):
'`value` is readonly; increment it with `inc`.' '`value` is readonly; increment it with `inc`.'
def __cmp__(self, other):
'Fool BTree checks for sane comparison :/'
return object.__cmp__(self, other)
_val = 0 _val = 0
def inc(self): def inc(self):
self._val += 1 self._val += 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment