Queue cleanup

Paul Rubin no.email at nospam.invalid
Mon Aug 30 02:07:03 EDT 2010


Lawrence D'Oliveiro <ldo at geek-central.gen.new_zealand> writes:
> static void GetBufferInfo
>   ( ...
>     do /*once*/
>       {
>         TheBufferInfo = PyObject_CallMethod(FromArray, "buffer_info", "");
>         if (TheBufferInfo == 0)
>             break;
>         AddrObj = PyTuple_GetItem(TheBufferInfo, 0);
>         LenObj = PyTuple_GetItem(TheBufferInfo, 1);
>         if (PyErr_Occurred())
>             break;
>         ...
>         Py_INCREF(AddrObj);
>         Py_INCREF(LenObj);
>       }
>     while (false);
>     Py_XDECREF(AddrObj);
>     Py_XDECREF(LenObj);
>     Py_XDECREF(TheBufferInfo);
>   } /*GetBufferInfo*/
>
> It’s quite easy to assure yourself that this is never going to leak memory. 

Actually that code looks suspicious.  Suppose in

         AddrObj = PyTuple_GetItem(TheBufferInfo, 0);
         LenObj = PyTuple_GetItem(TheBufferInfo, 1);

the first PyTuple_GetItem succeeds and the second one fails.  Then
AddrObj is a borrowed reference to the first tuple element and LenObj is
null, the error flag is set, so you break out of the do/while.  You then
decrement the refcount of AddrObj even though you didn't increment it.
Maybe there's an explanation that makes it ok somehow, but it still
looks messy.  This is the kind of problem I'm referring to in general.



More information about the Python-list mailing list