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

SourceForge.net noreply@sourceforge.net
Wed, 16 Jul 2003 10:09:12 -0700


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

Category: None
Group: None
>Status: Closed
>Resolution: Fixed
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: Jeremy Hylton (jhylton)
Date: 2003-07-16 17:09

Message:
Logged In: YES 
user_id=31392

My checkin 2.240 had the side-effect of restoring the
behavior we got in 2.2.x.  My checkin comment wasn't very
clear about this (nor was the 2.215 comment that added this
feature).

Somehow the check for whether slots were allowed added a
condition that could never be true.  So there was no way to
get the TypeError "nonempty __slots__ not supported for
subtype of '%s'".

I don't think the change was intentional.  In addition to
the string crash, it created the possiblity for mutable tuples:
>>> class T(tuple):
...     __slots__ = "x", "y"
... 
>>> t = T((1, 2))
>>> t
(1, 2)
>>> t.x
1
>>> t.y
2
>>> t.y = -1
>>> t
(1, -1)



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

Comment By: Neal Norwitz (nnorwitz)
Date: 2003-07-15 21: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 16: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 22: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 21: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 17: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