--- python/branches/py3k/Modules/audioop.c 2010/05/09 15:52:27 81032 +++ python/branches/py3k/Modules/audioop.c 2010/05/11 13:09:58 81081 @@ -834,7 +834,7 @@ audioop_tostereo(PyObject *self, PyObject *args) { signed char *cp, *ncp; - int len, new_len, size, val1, val2, val = 0; + int len, size, val1, val2, val = 0; double fac1, fac2, fval, maxval; PyObject *rv; int i; @@ -851,14 +851,13 @@ return 0; } - new_len = len*2; - if (new_len < 0) { + if (len > INT_MAX/2) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return 0; } - rv = PyBytes_FromStringAndSize(NULL, new_len); + rv = PyBytes_FromStringAndSize(NULL, len*2); if ( rv == 0 ) return 0; ncp = (signed char *)PyBytes_AsString(rv); @@ -1021,7 +1020,7 @@ { signed char *cp; unsigned char *ncp; - int len, new_len, size, size2, val = 0; + int len, size, size2, val = 0; PyObject *rv; int i, j; @@ -1035,13 +1034,12 @@ return 0; } - new_len = (len/size)*size2; - if (new_len < 0) { + if (len/size > INT_MAX/size2) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return 0; } - rv = PyBytes_FromStringAndSize(NULL, new_len); + rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2); if ( rv == 0 ) return 0; ncp = (unsigned char *)PyBytes_AsString(rv); @@ -1077,7 +1075,6 @@ int chan, d, *prev_i, *cur_i, cur_o; PyObject *state, *samps, *str, *rv = NULL; int bytes_per_frame; - size_t alloc_size; weightA = 1; weightB = 0; @@ -1120,14 +1117,13 @@ inrate /= d; outrate /= d; - alloc_size = sizeof(int) * (unsigned)nchannels; - if (alloc_size < (unsigned)nchannels) { + if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return 0; } - prev_i = (int *) malloc(alloc_size); - cur_i = (int *) malloc(alloc_size); + prev_i = (int *) malloc(nchannels * sizeof(int)); + cur_i = (int *) malloc(nchannels * sizeof(int)); if (prev_i == NULL || cur_i == NULL) { (void) PyErr_NoMemory(); goto exit; @@ -1164,25 +1160,16 @@ ceiling(len*outrate/inrate) output frames, and each frame requires bytes_per_frame bytes. Computing this without spurious overflow is the challenge; we can - settle for a reasonable upper bound, though. */ - int ceiling; /* the number of output frames */ - int nbytes; /* the number of output bytes needed */ - int q = len / inrate; - /* Now len = q * inrate + r exactly (with r = len % inrate), - and this is less than q * inrate + inrate = (q+1)*inrate. - So a reasonable upper bound on len*outrate/inrate is - ((q+1)*inrate)*outrate/inrate = - (q+1)*outrate. - */ - ceiling = (q+1) * outrate; - nbytes = ceiling * bytes_per_frame; - /* See whether anything overflowed; if not, get the space. */ - if (q+1 < 0 || - ceiling / outrate != q+1 || - nbytes / bytes_per_frame != ceiling) + settle for a reasonable upper bound, though, in this + case ceiling(len/inrate) * outrate. */ + + /* compute ceiling(len/inrate) without overflow */ + int q = len > 0 ? 1 + (len - 1) / inrate : 0; + if (outrate > INT_MAX / q / bytes_per_frame) str = NULL; else - str = PyBytes_FromStringAndSize(NULL, nbytes); + str = PyBytes_FromStringAndSize(NULL, + q * outrate * bytes_per_frame); if (str == NULL) { PyErr_SetString(PyExc_MemoryError, @@ -1300,7 +1287,7 @@ unsigned char *cp; unsigned char cval; signed char *ncp; - int len, new_len, size, val; + int len, size, val; PyObject *rv; int i; @@ -1313,18 +1300,17 @@ return 0; } - new_len = len*size; - if (new_len < 0) { + if (len > INT_MAX/size) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return 0; } - rv = PyBytes_FromStringAndSize(NULL, new_len); + rv = PyBytes_FromStringAndSize(NULL, len*size); if ( rv == 0 ) return 0; ncp = (signed char *)PyBytes_AsString(rv); - for ( i=0; i < new_len; i += size ) { + for ( i=0; i < len*size; i += size ) { cval = *cp++; val = st_ulaw2linear16(cval); @@ -1374,7 +1360,7 @@ unsigned char *cp; unsigned char cval; signed char *ncp; - int len, new_len, size, val; + int len, size, val; PyObject *rv; int i; @@ -1387,18 +1373,17 @@ return 0; } - new_len = len*size; - if (new_len < 0) { + if (len > INT_MAX/size) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return 0; } - rv = PyBytes_FromStringAndSize(NULL, new_len); + rv = PyBytes_FromStringAndSize(NULL, len*size); if ( rv == 0 ) return 0; ncp = (signed char *)PyBytes_AsString(rv); - for ( i=0; i < new_len; i += size ) { + for ( i=0; i < len*size; i += size ) { cval = *cp++; val = st_alaw2linear16(cval); @@ -1523,7 +1508,7 @@ { signed char *cp; signed char *ncp; - int len, new_len, size, valpred, step, delta, index, sign, vpdiff; + int len, size, valpred, step, delta, index, sign, vpdiff; PyObject *rv, *str, *state; int i, inputbuffer = 0, bufferstep; @@ -1545,13 +1530,12 @@ } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) ) return 0; - new_len = len*size*2; - if (new_len < 0) { + if (len > (INT_MAX/2)/size) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return 0; } - str = PyBytes_FromStringAndSize(NULL, new_len); + str = PyBytes_FromStringAndSize(NULL, len*size*2); if ( str == 0 ) return 0; ncp = (signed char *)PyBytes_AsString(str); @@ -1559,7 +1543,7 @@ step = stepsizeTable[index]; bufferstep = 0; - for ( i=0; i < new_len; i += size ) { + for ( i=0; i < len*size*2; i += size ) { /* Step 1 - get the delta value and compute next index */ if ( bufferstep ) { delta = inputbuffer & 0xf;