[prev in list] [next in list] [prev in thread] [next in thread]
List: pypy-dev
Subject: Re: [pypy-dev] using python-ldap under pypy
From: Elmir Jagudin <elmir () unity3d ! com>
Date: 2015-12-14 11:38:10
Message-ID: CAN1hHsro_mzuyhTwERvfho3e6hep9=qaRw8z4wJ5d-DgegCNVg () mail ! gmail ! com
[Download RAW message or body]
[Attachment #2 (multipart/alternative)]
On Mon, Dec 14, 2015 at 10:01 AM, Armin Rigo <arigo@tunes.org> wrote:
> Hi Elmir,
>
> On Sun, Dec 13, 2015 at 10:19 PM, Elmir Jagudin <elmir@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
[Attachment #5 (text/html)]
<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec \
14, 2015 at 10:01 AM, Armin Rigo <span dir="ltr"><<a href="mailto:arigo@tunes.org" \
target="_blank">arigo@tunes.org</a>></span> wrote:<br><blockquote \
class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid \
rgb(204,204,204);padding-left:1ex">Hi Elmir,<br> <span class=""><br>
On Sun, Dec 13, 2015 at 10:19 PM, Elmir Jagudin <<a \
href="mailto:elmir@unity3d.com">elmir@unity3d.com</a>> wrote:<br> > The error \
happens in the python-ldap C code that converts ["uid", "cn"]<br> \
> array to char **.<br> ><br>
> In this file:<br>
> <a href="http://python-ldap.cvs.sourceforge.net/viewvc/python-ldap/python-ldap/Modules/LDAPObject.c?revision=1.91&view=markup" \
rel="noreferrer" target="_blank">http://python-ldap.cvs.sourceforge.net/viewvc/python-ldap/python-ldap/Modules/LDAPObject.c?revision=1.91&view=markup</a><br>
><br>
> in function attrs_from_List() there is this code (lines 289-290):<br>
><br>
> 289: attrs[i] = PyString_AsString(item);<br>
> 290: Py_DECREF(item);<br>
><br>
> On line 289 the assigned string is correct, however after executing line<br>
> 290, the string will be corrupted.<br>
><br>
> I have noticed that under cpython, the refcount for 'item' is larger \
then 1.<br> > However under pypy it is always 1, and I guess after decreasing it, \
the<br> > 'item' is freed, and attrs[i] pointer becomes invalid.<br>
<br>
</span>Ok. However the sentence "under CPython the refcount for 'item' \
is<br> larger than 1" is not true in all cases. It is true for simple \
lists<br> or tuples, but not for more complex types. That means that you can<br>
probably get already-freed strings under CPython too. Try for<br>
example:<br>
<br>
class CustomSeq(object):<br>
def __getitem__(self, i):<br>
return str(i) # returns a refcount=1 result<br>
def __len__(self):<br>
return 2<br>
<span class=""><br>
res = l.search_s(BASE_DN,<br>
ldap.SCOPE_SUBTREE,<br>
FILTER,<br>
</span> CustomSeq())<br>
<br>
<br>
So it means it's really a bug of python-ldap, which just happens to<br>
crash more often on PyPy than on CPython. It should be fixed \
there.<br></blockquote><div><br></div><div>Yepp, you are right. Following version of \
the code above clearly shows that it's broken under CPython as well:<br><br>class \
CustomSeq(object):<br> def __getitem__(self, i):<br> return \
str(i) # returns a refcount=1 result<br> def __len__(self):<br> \
return 20<br><br></div><div>The resulting query send over network will be \
wrong.<br><br></div><div>Thanks for \
clarification.<br></div><div><br></div><div>/Elmir<br></div></div><br></div></div>
_______________________________________________
pypy-dev mailing list
pypy-dev@python.org
https://mail.python.org/mailman/listinfo/pypy-dev
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic