[pypy-svn] r79849 - in pypy/trunk/pypy/module/cpyext: . src test
arigo at codespeak.net
arigo at codespeak.net
Mon Dec 6 16:39:13 CET 2010
Author: arigo
Date: Mon Dec 6 16:39:11 2010
New Revision: 79849
Modified:
pypy/trunk/pypy/module/cpyext/intobject.py
pypy/trunk/pypy/module/cpyext/src/getargs.c
pypy/trunk/pypy/module/cpyext/test/test_intobject.py
Log:
Allow calls to PyInt_AsLong(NULL), and raise TypeError.
Modified: pypy/trunk/pypy/module/cpyext/intobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/intobject.py (original)
+++ pypy/trunk/pypy/module/cpyext/intobject.py Mon Dec 6 16:39:11 2010
@@ -1,5 +1,6 @@
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.interpreter.error import OperationError
from pypy.module.cpyext.api import (cpython_api, PyObject, CANNOT_FAIL,
build_type_checkers, Py_ssize_t)
@@ -19,6 +20,9 @@
already one, and then return its value. If there is an error, -1 is
returned, and the caller should check PyErr_Occurred() to find out whether
there was an error, or whether the value just happened to be -1."""
+ if w_obj is None:
+ raise OperationError(space.w_TypeError,
+ space.wrap("an integer is required, got NULL"))
return space.int_w(space.int(w_obj))
@cpython_api([PyObject], lltype.Unsigned, error=-1)
@@ -26,6 +30,9 @@
"""Return a C unsigned long representation of the contents of pylong.
If pylong is greater than ULONG_MAX, an OverflowError is
raised."""
+ if w_obj is None:
+ raise OperationError(space.w_TypeError,
+ space.wrap("an integer is required, got NULL"))
return space.uint_w(space.int(w_obj))
@cpython_api([PyObject], lltype.Signed, error=CANNOT_FAIL)
@@ -39,6 +46,9 @@
PyLongObject, if it is not already one, and then return its value as
Py_ssize_t.
"""
+ if w_obj is None:
+ raise OperationError(space.w_TypeError,
+ space.wrap("an integer is required, got NULL"))
return space.int_w(w_obj) # XXX this is wrong on win64
@cpython_api([Py_ssize_t], PyObject)
@@ -48,4 +58,3 @@
returned.
"""
return space.wrap(ival) # XXX this is wrong on win64
-
Modified: pypy/trunk/pypy/module/cpyext/src/getargs.c
==============================================================================
--- pypy/trunk/pypy/module/cpyext/src/getargs.c (original)
+++ pypy/trunk/pypy/module/cpyext/src/getargs.c Mon Dec 6 16:39:11 2010
@@ -445,18 +445,22 @@
for (i = 0; i < n; i++) {
char *msg;
PyObject *item;
- item = PySequence_GetItem(arg, i);
+ /* CPython uses PySequence_GetItem() and Py_XDECREF() here,
+ exposing a crash (see http://bugs.python.org/issue6083).
+ It always crashes with PyPy, so we apply the fix being
+ discussed: we only allow a tuple. */
+ item = PyTuple_GetItem(arg, i);
if (item == NULL) {
PyErr_Clear();
levels[0] = i+1;
levels[1] = 0;
- strncpy(msgbuf, "is not retrievable", bufsize);
+ strncpy(msgbuf, "is not retrievable (subargument "
+ "must be a real tuple with PyPy)",
+ bufsize);
return msgbuf;
}
msg = convertitem(item, &format, p_va, flags, levels+1,
msgbuf, bufsize, freelist);
- /* PySequence_GetItem calls tp->sq_item, which INCREFs */
- Py_XDECREF(item);
if (msg != NULL) {
levels[0] = i+1;
return msg;
Modified: pypy/trunk/pypy/module/cpyext/test/test_intobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_intobject.py (original)
+++ pypy/trunk/pypy/module/cpyext/test/test_intobject.py Mon Dec 6 16:39:11 2010
@@ -19,6 +19,10 @@
assert api.PyErr_Occurred() is space.w_TypeError
api.PyErr_Clear()
+ assert api.PyInt_AsLong(None) == -1
+ assert api.PyErr_Occurred() is space.w_TypeError
+ api.PyErr_Clear()
+
assert api.PyInt_AsUnsignedLong(space.wrap(sys.maxint)) == sys.maxint
assert api.PyInt_AsUnsignedLong(space.wrap(-5)) == sys.maxint * 2 + 1
assert api.PyErr_Occurred() is space.w_ValueError
More information about the Pypy-commit
mailing list