Forward-port of r52136,52138: a review of overflow-detecting code.

* unified the way intobject, longobject and mystrtoul handle
  values around -sys.maxint-1.

* in general, trying to entierely avoid overflows in any computation
  involving signed ints or longs is extremely involved.  Fixed a few
  simple cases where a compiler might be too clever (but that's all
  guesswork).

* more overflow checks against bad data in marshal.c.

* 2.5 specific: fixed a number of places that were still confusing int
  and Py_ssize_t.  Some of them could potentially have caused
  "real-world" breakage.

* list.pop(x): fixing overflow issues on x was messy.  I just reverted
  to PyArg_ParseTuple("n"), which does the right thing.  (An obscure
  test was trying to give a Decimal to list.pop()... doesn't make
  sense any more IMHO)

* trying to write a few tests...
This commit is contained in:
Armin Rigo 2006-10-04 12:17:45 +00:00
parent 0d2f498a4c
commit 7ccbca93a2
19 changed files with 186 additions and 106 deletions

View file

@ -1024,7 +1024,7 @@ save_int(Picklerobject *self, PyObject *args)
static int
save_long(Picklerobject *self, PyObject *args)
{
int size;
Py_ssize_t size;
int res = -1;
PyObject *repr = NULL;
@ -1066,7 +1066,7 @@ save_long(Picklerobject *self, PyObject *args)
* byte at the start, and cut it back later if possible.
*/
nbytes = (nbits >> 3) + 1;
if ((int)nbytes < 0 || (size_t)(int)nbytes != nbytes) {
if (nbytes > INT_MAX) {
PyErr_SetString(PyExc_OverflowError, "long too large "
"to pickle");
goto finally;
@ -1208,12 +1208,14 @@ save_string(Picklerobject *self, PyObject *args, int doput)
c_str[1] = size;
len = 2;
}
else {
else if (size <= INT_MAX) {
c_str[0] = BINSTRING;
for (i = 1; i < 5; i++)
c_str[i] = (int)(size >> ((i - 1) * 8));
len = 5;
}
else
return -1; /* string too large */
if (self->write_func(self, c_str, len) < 0)
return -1;
@ -1286,7 +1288,7 @@ modified_EncodeRawUnicodeEscape(const Py_UNICODE *s, int size)
static int
save_unicode(Picklerobject *self, PyObject *args, int doput)
{
int size, len;
Py_ssize_t size, len;
PyObject *repr=0;
if (!PyUnicode_Check(args))
@ -1325,6 +1327,8 @@ save_unicode(Picklerobject *self, PyObject *args, int doput)
if ((size = PyString_Size(repr)) < 0)
goto err;
if (size > INT_MAX)
return -1; /* string too large */
c_str[0] = BINUNICODE;
for (i = 1; i < 5; i++)