Revision: 621 http://rpy.svn.sourceforge.net/rpy/?rev=621&view=rev Author: lgautier Date: 2008-08-08 13:29:24 +0000 (Fri, 08 Aug 2008)
Log Message: ----------- - Overflow issues on Python 2.4/64 bits when indexing R vector with very large integers. - Handling of negative indexes for :class:`SexpVector`'s :meth:`__getitem__` and :meth:`__setitem__` was missing Modified Paths: -------------- branches/rpy_nextgen/NEWS branches/rpy_nextgen/doc/source/overview.rst branches/rpy_nextgen/rpy/rinterface/rinterface.c branches/rpy_nextgen/rpy/rinterface/rinterface.h branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py Modified: branches/rpy_nextgen/NEWS =================================================================== --- branches/rpy_nextgen/NEWS 2008-08-07 17:33:42 UTC (rev 620) +++ branches/rpy_nextgen/NEWS 2008-08-08 13:29:24 UTC (rev 621) @@ -19,6 +19,16 @@ - :class:`R` remains a singleton, but does not throw an exception when multiple instances are requested +Bugs fixed +---------- + +- Unable to compile on Python2.4 (definition of aliases to Python2.5-specific were not where they should be). + +- Overflow issues on Python 2.4/64 bits when indexing R vector with very large integers. + +- Handling of negative indexes for :class:`SexpVector`'s :meth:`__getitem__` and :meth:`__setitem__` was missing + + Release 2.0.0a2 =============== Modified: branches/rpy_nextgen/doc/source/overview.rst =================================================================== --- branches/rpy_nextgen/doc/source/overview.rst 2008-08-07 17:33:42 UTC (rev 620) +++ branches/rpy_nextgen/doc/source/overview.rst 2008-08-08 13:29:24 UTC (rev 621) @@ -44,10 +44,6 @@ This is developped with R-2.7.1 and Python-2.5.2. R-2.8.0-dev is sometimes tested, and it does seem to work well. -Compatibility with Python 2.4 is expected but it was observed to segfault on rare occasions -(and the cause is not yet identified). - - Download ^^^^^^^^ Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.c =================================================================== --- branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-08-07 17:33:42 UTC (rev 620) +++ branches/rpy_nextgen/rpy/rinterface/rinterface.c 2008-08-08 13:29:24 UTC (rev 621) @@ -1237,7 +1237,7 @@ VectorSexp_item(PyObject *object, Py_ssize_t i) { PyObject* res; - R_len_t i_R; + R_len_t i_R, len_R; SEXP *sexp = &(RPY_SEXP((PySexpObject *)object)); if (! sexp) { @@ -1245,12 +1245,27 @@ return NULL; } - /* R is still with int for indexes */ + /* On 64bits, Python is apparently able to use larger integer + * than R for indexing. */ if (i >= R_LEN_T_MAX) { PyErr_Format(PyExc_IndexError, "Index value exceeds what R can handle."); res = NULL; + return; } - else if (i >= GET_LENGTH(*sexp)) { + + len_R = GET_LENGTH(*sexp); + + if (i < 0) { + i = len_R - i; + } + + if (i < 0) { + PyErr_Format(PyExc_IndexError, + "Mysterious error: likely an integer overflow."); + res = NULL; + return; + } + if ((i >= GET_LENGTH(*sexp))) { PyErr_Format(PyExc_IndexError, "Index out of range."); res = NULL; } @@ -1302,16 +1317,22 @@ static int VectorSexp_ass_item(PyObject *object, Py_ssize_t i, PyObject *val) { - R_len_t i_R; + R_len_t i_R, len_R; - /* R is still with int for indexes */ + /* Check for 64 bits platforms */ if (i >= R_LEN_T_MAX) { PyErr_Format(PyExc_IndexError, "Index value exceeds what R can handle."); return -1; } SEXP *sexp = &(RPY_SEXP((PySexpObject *)object)); - if (i >= GET_LENGTH(*sexp)) { + len_R = GET_LENGTH(*sexp); + + if (i < 0) { + i = len_R - i; + } + + if (i >= len_R) { PyErr_Format(PyExc_IndexError, "Index out of range."); return -1; } Modified: branches/rpy_nextgen/rpy/rinterface/rinterface.h =================================================================== --- branches/rpy_nextgen/rpy/rinterface/rinterface.h 2008-08-07 17:33:42 UTC (rev 620) +++ branches/rpy_nextgen/rpy/rinterface/rinterface.h 2008-08-08 13:29:24 UTC (rev 621) @@ -7,6 +7,8 @@ /* Back-compatibility with Python 2.4 */ #if (PY_VERSION_HEX < 0x02050000) +#define PY_SSIZE_T_MAX INT_MAX +#define PY_SSIZE_T_MIN INT_MIN typedef int Py_ssize_t; typedef inquiry lenfunc; typedef intargfunc ssizeargfunc; Modified: branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py =================================================================== --- branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py 2008-08-07 17:33:42 UTC (rev 620) +++ branches/rpy_nextgen/rpy/rinterface/tests/test_SexpVector.py 2008-08-08 13:29:24 UTC (rev 621) @@ -108,6 +108,14 @@ self.assertTrue(idem(mySeq, myList[0])) self.assertTrue(idem(letters_R, myList[1])) + letters_R = ri.globalEnv.get("letters") + self.assertEquals('z', letters_R[-1]) + + def testGetItemNegativeOutOfBound(self): + letters_R = ri.globalEnv.get("letters") + self.assertRaises(IndexError, letters_R.__getitem__, + -100) + def testGetItemOutOfBound(self): myVec = ri.SexpVector([0, 1, 2, 3, 4, 5], ri.INTSXP) self.assertRaises(IndexError, myVec.__getitem__, 10) @@ -118,10 +126,9 @@ def testAssignItemDifferentType(self): c_R = ri.globalEnv.get("c") myVec = c_R(ri.SexpVector([0, 1, 2, 3, 4, 5], ri.INTSXP)) - #import pdb; pdb.set_trace() self.assertRaises(ValueError, myVec.__setitem__, 0, ri.SexpVector(["a", ], ri.STRSXP)) - + def testAssignItemOutOfBound(self): c_R = ri.globalEnv.get("c") myVec = c_R(ri.SexpVector([0, 1, 2, 3, 4, 5], ri.INTSXP)) @@ -137,6 +144,9 @@ myVec[3] = ri.SexpVector([100, ], ri.INTSXP) self.assertTrue(myVec[3] == 100) + myVec[-1] = ri.SexpVector([200, ], ri.INTSXP) + self.assertTrue(myVec[5] == 200) + def testAssignItemReal(self): c_R = ri.globalEnv.get("c") myVec = c_R(ri.SexpVector([0.0, 1.0, 2.0, 3.0, 4.0, 5.0], This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ rpy-list mailing list rpy-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rpy-list