[Patches] [ python-Patches-1704621 ] interpreter crash when multiplying large lists

SourceForge.net noreply at sourceforge.net
Sat Apr 21 05:55:32 CEST 2007


Patches item #1704621, was opened at 2007-04-20 17:17
Message generated for change (Comment added) made by agthorr
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1704621&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Core (C code)
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Daniel Stutzbach (agthorr)
Assigned to: Nobody/Anonymous (nobody)
Summary: interpreter crash when multiplying large lists

Initial Comment:
Here's a succinct summary of the problem:

>>> x = [0] * 2**20
>>> x *= 2**20
Segmentation fault (core dumped)

>>> x = [0] * 2**20
>>> x * 2**20
[]
>>>

The problem is that list_repeat()'s check for an overflow is flawed, and list_inplace_repeat() doesn't check at all.  Attached is a patch that adds a correct check to both functions.  With the patch, both variations throw a MemoryError exception.  The patch is against Python 2.5, but should also fix 2.5.1/2.6/3.0.

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

>Comment By: Daniel Stutzbach (agthorr)
Date: 2007-04-20 22:55

Message:
Logged In: YES 
user_id=6324
Originator: YES

Sort of.  Below is a test for 32-bit architectures.  Unfortunately, on
architectures where Py_ssize_t is a 64-bit integer, the multiplication
won't overflow and the test really will try to build a list with 2**32
items (which most likely will eventually raise a MemoryError, but it will
take a LONG time!).  This is probably undesirable.  Is there a way to skip
this test for non-32-bit architectures?

One way would be to only perform the test if sys.maxint <= 2**31.

Below is a test that can be added to seq_tests.py:

    def test_bigrepeat(self):
        x = self.type2test([0])
        x *= 2**16
        self.assertRaises(MemoryError, x.__mul__, 2**16)
        self.assertRaises(MemoryError, x.__imul__, 2**16)

While writing the test I found a bug in my patch for the case where the
list is already size 0.  New patch attached.
File Added: list_repeat.patch

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

Comment By: Neal Norwitz (nnorwitz)
Date: 2007-04-20 22:04

Message:
Logged In: YES 
user_id=33168
Originator: NO

Thanks for the patch!

Can you add a test case for both conditions?

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

Comment By: Jason Orendorff (jorend)
Date: 2007-04-20 17:41

Message:
Logged In: YES 
user_id=18139
Originator: NO

Yes, I see it.  Patch looks good.  I haven't tested it.

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

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


More information about the Patches mailing list