Commit 7b55db76 authored by Tim Peters's avatar Tim Peters

_bucket_set(): This could leave a mapping bucket in a variety of insane

states when the value passed in was of the wrong type (for example,
doing
    b[obj] = 3.7
when b is an OIBTree).  This manifested as a refcount leak in the test
suite, but could have been much worse (most likely in real life is that
a seemingly arbitrary existing key would "go missing").
parent 10fc64da
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
****************************************************************************/ ****************************************************************************/
#define BUCKETTEMPLATE_C "$Id: BucketTemplate.c,v 1.50 2003/04/07 21:43:14 jeremy Exp $\n" #define BUCKETTEMPLATE_C "$Id: BucketTemplate.c,v 1.51 2003/04/11 19:17:07 tim_one Exp $\n"
/* Use BUCKET_SEARCH to find the index at which a key belongs. /* Use BUCKET_SEARCH to find the index at which a key belongs.
* INDEX An int lvalue to hold the index i such that KEY belongs at * INDEX An int lvalue to hold the index i such that KEY belongs at
...@@ -299,17 +299,25 @@ _bucket_set(Bucket *self, PyObject *keyarg, PyObject *v, ...@@ -299,17 +299,25 @@ _bucket_set(Bucket *self, PyObject *keyarg, PyObject *v,
{ {
int i, cmp; int i, cmp;
KEY_TYPE key; KEY_TYPE key;
VALUE_TYPE value;
int result = -1; /* until proven innocent */ int result = -1; /* until proven innocent */
int copied = 1; int copied = 1;
COPY_KEY_FROM_ARG(key, keyarg, copied); COPY_KEY_FROM_ARG(key, keyarg, copied);
UNLESS(copied) return -1; UNLESS(copied) return -1;
/* Copy the value early (if needed), so that in case of error a
* pile of bucket mutations don't need to be undone.
*/
if (v && !noval) {
COPY_VALUE_FROM_ARG(value, v, copied);
UNLESS(copied) return -1;
}
PER_USE_OR_RETURN(self, -1); PER_USE_OR_RETURN(self, -1);
BUCKET_SEARCH(i, cmp, self, key, goto Done); BUCKET_SEARCH(i, cmp, self, key, goto Done);
if (cmp == 0) { if (cmp == 0) {
VALUE_TYPE value;
/* The key exists, at index i. */ /* The key exists, at index i. */
if (v) { if (v) {
...@@ -397,8 +405,7 @@ _bucket_set(Bucket *self, PyObject *keyarg, PyObject *v, ...@@ -397,8 +405,7 @@ _bucket_set(Bucket *self, PyObject *keyarg, PyObject *v,
INCREF_KEY(self->keys[i]); INCREF_KEY(self->keys[i]);
if (! noval) { if (! noval) {
COPY_VALUE_FROM_ARG(self->values[i], v, copied); COPY_VALUE(self->values[i], value);
UNLESS(copied) return -1;
INCREF_VALUE(self->values[i]); INCREF_VALUE(self->values[i]);
} }
......
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