On Mon, Dec 14, 2015 at 10:01 AM, Armin Rigo <ar...@tunes.org> wrote:
> Hi Elmir, > > On Sun, Dec 13, 2015 at 10:19 PM, Elmir Jagudin <el...@unity3d.com> wrote: > > The error happens in the python-ldap C code that converts ["uid", "cn"] > > array to char **. > > > > In this file: > > > http://python-ldap.cvs.sourceforge.net/viewvc/python-ldap/python-ldap/Modules/LDAPObject.c?revision=1.91&view=markup > > > > in function attrs_from_List() there is this code (lines 289-290): > > > > 289: attrs[i] = PyString_AsString(item); > > 290: Py_DECREF(item); > > > > On line 289 the assigned string is correct, however after executing line > > 290, the string will be corrupted. > > > > I have noticed that under cpython, the refcount for 'item' is larger > then 1. > > However under pypy it is always 1, and I guess after decreasing it, the > > 'item' is freed, and attrs[i] pointer becomes invalid. > > Ok. However the sentence "under CPython the refcount for 'item' is > larger than 1" is not true in all cases. It is true for simple lists > or tuples, but not for more complex types. That means that you can > probably get already-freed strings under CPython too. Try for > example: > > class CustomSeq(object): > def __getitem__(self, i): > return str(i) # returns a refcount=1 result > def __len__(self): > return 2 > > res = l.search_s(BASE_DN, > ldap.SCOPE_SUBTREE, > FILTER, > CustomSeq()) > > > So it means it's really a bug of python-ldap, which just happens to > crash more often on PyPy than on CPython. It should be fixed there. > Yepp, you are right. Following version of the code above clearly shows that it's broken under CPython as well: class CustomSeq(object): def __getitem__(self, i): return str(i) # returns a refcount=1 result def __len__(self): return 20 The resulting query send over network will be wrong. Thanks for clarification. /Elmir
_______________________________________________ pypy-dev mailing list pypy-dev@python.org https://mail.python.org/mailman/listinfo/pypy-dev