[Patches] [ python-Patches-757997 ] Using __slots__ with str derived classes can cause segfault

SourceForge.net noreply@sourceforge.net
Tue, 15 Jul 2003 14:06:51 -0700


Patches item #757997, was opened at 2003-06-20 12:28
Message generated for change (Comment added) made by nnorwitz
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=757997&group_id=5470

Category: None
Group: None
Status: Open
Resolution: None
Priority: 7
Submitted By: John Ehresman (jpe)
>Assigned to: Jeremy Hylton (jhylton)
Summary: Using __slots__ with str derived classes can cause segfault

Initial Comment:
The following results in a segfault on Linux with 2.3b1:
-------------------------
class StringDerived(str):
  __slots__ = ['a']
  def __init__(self, string):
    str.__init__(self, string)
    self.a = 1

class DerivedAgain(StringDerived):
  pass

o = DerivedAgain('hello world')
o.b = 2
--------------------------
Python 2.2.2 raises a TypeError when attempting to
derive a class from str with a non-empty __slots__,
maybe 2.3 should do the same?

I have no use case for deriving from str and defining
__slots__; I encountered the bug when writing test
cases for a debugger.

----------------------------------------------------------------------

>Comment By: Neal Norwitz (nnorwitz)
Date: 2003-07-15 17:06

Message:
Logged In: YES 
user_id=33168

Jeremy, I agree with Guido, I think nonempty slots shouldn't
be allowed for strings.  I think this is just a matter of
removing && !PyType_Check(base) in Objects/typeobject.c
around line 1656.  I don't have time to test it and I'm not
sure what the ramifications of this change are.  Can you get
this into 2.3?

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2003-07-09 12:13

Message:
Logged In: YES 
user_id=6380

Neal, I don't think your patch can work, unless you
change the *descriptors* used for slots also:
the slot offsets used by the slot descriptors
will still be constant and hence overwrite the
characters of the string (see structmember.c).
Example (with your patch):

>>> class C(str): __slots__ = ['a'] 
...      
>>> s = C("hello world") 
>>> s.a 
'\x00\x00\x00\x00\x90\x86\x12\x08\x00\x00' 
>>>  

I'd rather see the 2.2 situation back, where
it's simply illegal to use __slots__ in a str subclass
(or any subclass of a class whose tp_itemsize
!= 0).

----------------------------------------------------------------------

Comment By: Neal Norwitz (nnorwitz)
Date: 2003-06-20 18:05

Message:
Logged In: YES 
user_id=33168

Ain't testing grand.  Found a couple more problems.  Patch 2
is better, but I'm still not sure it's complete or correct.

I'm thinking the slot offset should be fixed when it's set,
rather than at each usage of the slot offset.

----------------------------------------------------------------------

Comment By: Neal Norwitz (nnorwitz)
Date: 2003-06-20 17:23

Message:
Logged In: YES 
user_id=33168

I think the problem is that strings are variable length. 
clear_slots() doesn't handle this condtion.  The attached
patch fixes the crash and works fine under valgrind, but I'm
not entirely sure it's correct.  Hopefully someone more
familiar with the TypeObject code can review this.

I'll add a test later.

----------------------------------------------------------------------

Comment By: Neal Norwitz (nnorwitz)
Date: 2003-06-20 13:18

Message:
Logged In: YES 
user_id=33168

unicode, list, and dict don't crash, only string.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=757997&group_id=5470