This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: long_subtype_new segfault in pure-Python code
Type: crash Stage:
Components: Interpreter Core Versions: Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: mark.dickinson Nosy List: cwitty, eric.smith, mark.dickinson, pitrou
Priority: high Keywords: patch

Created on 2010-09-16 07:51 by cwitty, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
python_long_bug.py cwitty, 2010-09-16 07:51 on my machine, causes segfault with python2.5, python2.6, python2.7
issue9869.patch mark.dickinson, 2010-09-18 10:48
Messages (8)
msg116514 - (view) Author: Carl Witty (cwitty) Date: 2010-09-16 07:51
PyNumber_Long() (and hence long_new()) are willing to return ints, rather than longs.  However, when long_subtype_new() calls long_new(), it casts the result to PyLongObject* without a check.  (Well, there is an assertion, so if assertions are enabled you'd get an assertion failure instead of a potential segmentation fault.)

The attached program segfaults for me; returning smaller numbers than 1000000 sometimes gives bad answers instead of crashing.
msg116761 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-09-18 10:48
Problem confirmed here; thanks for the report.

I think it's also a bug that after:

class A(object):
    def __long__(self):
        return 42

long(A()) returns an object of type 'int' rather than an object of type 'long'.  It's inconsistent with what happens with __trunc__, too:

>>> class A(object):
...     def __trunc__(self): return 42
... 
[37198 refs]
>>> long(A())
42L
[37201 refs]

What's a little bit odd is that there's a test for the __long__-returning-int behaviour in test_class that asserts the return type should be int.

Here's a patch that fixes the return type of long (and PyNumber_Long) to be long in these cases.
msg116762 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-09-18 10:52
Removing 2.6 from the versions, since this isn't a security problem (as far as I know).
msg116766 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-09-18 12:03
> What's a little bit odd is that there's a test for the __long__-
> returning-int behaviour in test_class that asserts the return type
> should be int.

If there is a test then the behaviour is probably deliberate, and changing it would break compatibility.
msg116769 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2010-09-18 12:44
There are plenty of tests that check implementation specific internal behaviors. I don't think the presence of test alone would mean that it can't be changed.
msg116770 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-09-18 12:48
> There are plenty of tests that check implementation specific internal
> behaviors. I don't think the presence of test alone would mean that it
> can't be changed.

Right. In practice, returning a long instead of an int can produce bugs,
mainly because some C functions will only accept ints and refuse longs.

(which is the C functions' fault, but unless you want to find and fix
all of them (including perhaps in 3rd-party libraries), I think it's
better not to change the current behaviour)
msg117408 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-09-26 10:16
> Right. In practice, returning a long instead of an int can produce bugs,
> mainly because some C functions will only accept ints and refuse longs.

I'd say 'in theory' rather than 'in practice' here.  In this particular case, I don't see much danger:  any C code explicitly calling PyNumber_Long (rather than PyNumber_Int) surely has to be prepared to deal with a long, since that's what's going to be returned in the vast majority of cases.  Similarly for Python code calling 'long' rather than 'int'.

I'd also note that the docs state clearly that PyNumber_Long returns a long (while PyNumber_Int, in contrast, is permitted to return either an int or a long);  similarly for the builtin 'long' function.

And finally, looking at the history of the test_class test (see issue 1671298), it doesn't look as if anyone was thinking too hard about return types at that point---it looks like the test was just fit to the existing semi-broken behaviour.

So I'm still proposing to apply this patch, in spite of Antoine's -1. ;-)
msg117409 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2010-09-26 10:38
Committed in r85016.  I'll take responsibility for any broken 3rd party code...
History
Date User Action Args
2022-04-11 14:57:06adminsetgithub: 54078
2010-09-26 10:38:31mark.dickinsonsetstatus: open -> closed
resolution: fixed
messages: + msg117409
2010-09-26 10:16:33mark.dickinsonsetmessages: + msg117408
2010-09-18 12:48:17pitrousetmessages: + msg116770
2010-09-18 12:44:36eric.smithsetmessages: + msg116769
2010-09-18 12:03:08pitrousetnosy: + pitrou
messages: + msg116766
2010-09-18 10:52:16mark.dickinsonsetmessages: + msg116762
versions: - Python 2.6
2010-09-18 10:48:35mark.dickinsonsetfiles: + issue9869.patch
keywords: + patch
messages: + msg116761
2010-09-16 18:10:44eric.smithsetnosy: + eric.smith

versions: - Python 2.5
2010-09-16 11:13:40mark.dickinsonsetpriority: normal -> high
assignee: mark.dickinson

nosy: + mark.dickinson
2010-09-16 07:51:50cwittycreate