[Python-Dev] PyNumber_*() binary operations & coercion

Guido van Rossum guido@beopen.com
Wed, 23 Aug 2000 18:28:03 -0500


> While re-writing the PyNumber_InPlace*() functions in augmented assignment
> to something Guido and I agree on should be the Right Way, I found something
> that *might* be a bug. But I'm not sure.
> 
> The PyNumber_*() methods for binary operations (found in abstract.c) have
> the following construct:
> 
>         if (v->ob_type->tp_as_number != NULL) {
>                 PyObject *x = NULL;
>                 PyObject * (*f)(PyObject *, PyObject *);
>                 if (PyNumber_Coerce(&v, &w) != 0)
>                         return NULL;
>                 if ((f = v->ob_type->tp_as_number->nb_xor) != NULL)
>                         x = (*f)(v, w);
>                 Py_DECREF(v);
>                 Py_DECREF(w);
>                 if (f != NULL)
>                         return x;
>         }
> 
> (This is after a check if either argument is an instance object, so both are
> C objects here.) Now, I'm not sure how coercion is supposed to work, but I
> see one problem here: 'v' can be changed by PyNumber_Coerce(), and the new
> object's tp_as_number pointer could be NULL. I bet it's pretty unlikely that
> (numeric) coercion of a numeric object and an unspecified object turns up a
> non-numeric object, but I don't see anything guaranteeing it won't, either.
> 
> Is this a non-issue, or should I bother with adding the extra check in the
> current binary operations (and the new inplace ones) ?

I think this currently can't happen because coercions never return
non-numeric objects, but it sounds like a good sanity check to add.

Please check this in as a separate patch (not as part of the huge
augmented assignment patch).

--Guido van Rossum (home page: http://www.pythonlabs.com/~guido/)