diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_csv.c | 10 | ||||
-rw-r--r-- | Modules/arraymodule.c | 35 | ||||
-rw-r--r-- | Modules/audioop.c | 68 | ||||
-rw-r--r-- | Modules/binascii.c | 40 | ||||
-rw-r--r-- | Modules/cjkcodecs/multibytecodec.c | 38 | ||||
-rw-r--r-- | Modules/datetimemodule.c | 7 |
6 files changed, 172 insertions, 26 deletions
diff --git a/Modules/_csv.c b/Modules/_csv.c index c654712..430ccdc 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -533,6 +533,10 @@ parse_grow_buff(ReaderObj *self) self->field = PyMem_New(Py_UNICODE, self->field_size); } else { + if (self->field_size > INT_MAX / 2) { + PyErr_NoMemory(); + return 0; + } self->field_size *= 2; self->field = PyMem_Resize(self->field, Py_UNICODE, self->field_size); @@ -1038,6 +1042,12 @@ join_append_data(WriterObj *self, Py_UNICODE *field, int quote_empty, static int join_check_rec_size(WriterObj *self, int rec_len) { + + if (rec_len < 0 || rec_len > INT_MAX - MEM_INCR) { + PyErr_NoMemory(); + return 0; + } + if (rec_len > self->rec_size) { if (self->rec_size == 0) { self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR; diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 3e26369..d2ae367 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -642,6 +642,9 @@ array_concat(arrayobject *a, PyObject *bb) PyErr_BadArgument(); return NULL; } + if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) { + return PyErr_NoMemory(); + } size = Py_SIZE(a) + Py_SIZE(b); np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); if (np == NULL) { @@ -664,6 +667,9 @@ array_repeat(arrayobject *a, Py_ssize_t n) Py_ssize_t nbytes; if (n < 0) n = 0; + if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) { + return PyErr_NoMemory(); + } size = Py_SIZE(a) * n; np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); if (np == NULL) @@ -853,6 +859,10 @@ array_inplace_repeat(arrayobject *self, Py_ssize_t n) if (n < 0) n = 0; items = self->ob_item; + if ((self->ob_descr->itemsize != 0) && + (Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { + return PyErr_NoMemory(); + } size = Py_SIZE(self) * self->ob_descr->itemsize; if (n == 0) { PyMem_FREE(items); @@ -861,6 +871,9 @@ array_inplace_repeat(arrayobject *self, Py_ssize_t n) self->allocated = 0; } else { + if (size > PY_SSIZE_T_MAX / n) { + return PyErr_NoMemory(); + } PyMem_Resize(items, char, n * size); if (items == NULL) return PyErr_NoMemory(); @@ -1142,6 +1155,10 @@ array_reduce(arrayobject *array) Py_INCREF(dict); } if (Py_SIZE(array) > 0) { + if (array->ob_descr->itemsize + > PY_SSIZE_T_MAX / Py_SIZE(array)) { + return PyErr_NoMemory(); + } result = Py_BuildValue("O(cy#)O", Py_TYPE(array), array->ob_descr->typecode, @@ -1315,6 +1332,9 @@ array_fromlist(arrayobject *self, PyObject *list) if ((*self->ob_descr->setitem)(self, Py_SIZE(self) - n + i, v) != 0) { Py_SIZE(self) -= n; + if (itemsize && (Py_SIZE(self) > PY_SSIZE_T_MAX / itemsize)) { + return PyErr_NoMemory(); + } PyMem_RESIZE(item, char, Py_SIZE(self) * itemsize); self->ob_item = item; @@ -1373,6 +1393,10 @@ array_fromstring(arrayobject *self, PyObject *args) n = n / itemsize; if (n > 0) { char *item = self->ob_item; + if ((n > PY_SSIZE_T_MAX - Py_SIZE(self)) || + ((Py_SIZE(self) + n) > PY_SSIZE_T_MAX / itemsize)) { + return PyErr_NoMemory(); + } PyMem_RESIZE(item, char, (Py_SIZE(self) + n) * itemsize); if (item == NULL) { PyErr_NoMemory(); @@ -1398,8 +1422,12 @@ values, as if it had been read from a file using the fromfile() method)."); static PyObject * array_tostring(arrayobject *self, PyObject *unused) { - return PyBytes_FromStringAndSize(self->ob_item, - Py_SIZE(self) * self->ob_descr->itemsize); + if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) { + return PyBytes_FromStringAndSize(self->ob_item, + Py_SIZE(self) * self->ob_descr->itemsize); + } else { + return PyErr_NoMemory(); + } } PyDoc_STRVAR(tostring_doc, @@ -1428,6 +1456,9 @@ array_fromunicode(arrayobject *self, PyObject *args) } if (n > 0) { Py_UNICODE *item = (Py_UNICODE *) self->ob_item; + if (Py_SIZE(self) > PY_SSIZE_T_MAX - n) { + return PyErr_NoMemory(); + } PyMem_RESIZE(item, Py_UNICODE, Py_SIZE(self) + n); if (item == NULL) { PyErr_NoMemory(); diff --git a/Modules/audioop.c b/Modules/audioop.c index 57f25c6..c660501 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -829,7 +829,7 @@ static PyObject * audioop_tostereo(PyObject *self, PyObject *args) { signed char *cp, *ncp; - int len, size, val1, val2, val = 0; + int len, new_len, size, val1, val2, val = 0; double fac1, fac2, fval, maxval; PyObject *rv; int i; @@ -846,7 +846,14 @@ audioop_tostereo(PyObject *self, PyObject *args) return 0; } - rv = PyBytes_FromStringAndSize(NULL, len*2); + new_len = len*2; + if (new_len < 0) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } + + rv = PyBytes_FromStringAndSize(NULL, new_len); if ( rv == 0 ) return 0; ncp = (signed char *)PyBytes_AsString(rv); @@ -1009,7 +1016,7 @@ audioop_lin2lin(PyObject *self, PyObject *args) { signed char *cp; unsigned char *ncp; - int len, size, size2, val = 0; + int len, new_len, size, size2, val = 0; PyObject *rv; int i, j; @@ -1023,7 +1030,13 @@ audioop_lin2lin(PyObject *self, PyObject *args) return 0; } - rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2); + new_len = (len/size)*size2; + if (new_len < 0) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } + rv = PyBytes_FromStringAndSize(NULL, new_len); if ( rv == 0 ) return 0; ncp = (unsigned char *)PyBytes_AsString(rv); @@ -1059,6 +1072,7 @@ audioop_ratecv(PyObject *self, PyObject *args) 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; @@ -1101,8 +1115,14 @@ audioop_ratecv(PyObject *self, PyObject *args) inrate /= d; outrate /= d; - prev_i = (int *) malloc(nchannels * sizeof(int)); - cur_i = (int *) malloc(nchannels * sizeof(int)); + alloc_size = sizeof(int) * (unsigned)nchannels; + if (alloc_size < nchannels) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } + prev_i = (int *) malloc(alloc_size); + cur_i = (int *) malloc(alloc_size); if (prev_i == NULL || cur_i == NULL) { (void) PyErr_NoMemory(); goto exit; @@ -1275,7 +1295,7 @@ audioop_ulaw2lin(PyObject *self, PyObject *args) unsigned char *cp; unsigned char cval; signed char *ncp; - int len, size, val; + int len, new_len, size, val; PyObject *rv; int i; @@ -1288,12 +1308,18 @@ audioop_ulaw2lin(PyObject *self, PyObject *args) return 0; } - rv = PyBytes_FromStringAndSize(NULL, len*size); + new_len = len*size; + if (new_len < 0) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } + rv = PyBytes_FromStringAndSize(NULL, new_len); if ( rv == 0 ) return 0; ncp = (signed char *)PyBytes_AsString(rv); - for ( i=0; i < len*size; i += size ) { + for ( i=0; i < new_len; i += size ) { cval = *cp++; val = st_ulaw2linear16(cval); @@ -1343,7 +1369,7 @@ audioop_alaw2lin(PyObject *self, PyObject *args) unsigned char *cp; unsigned char cval; signed char *ncp; - int len, size, val; + int len, new_len, size, val; PyObject *rv; int i; @@ -1356,12 +1382,18 @@ audioop_alaw2lin(PyObject *self, PyObject *args) return 0; } - rv = PyBytes_FromStringAndSize(NULL, len*size); + new_len = len*size; + if (new_len < 0) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } + rv = PyBytes_FromStringAndSize(NULL, new_len); if ( rv == 0 ) return 0; ncp = (signed char *)PyBytes_AsString(rv); - for ( i=0; i < len*size; i += size ) { + for ( i=0; i < new_len; i += size ) { cval = *cp++; val = st_alaw2linear16(cval); @@ -1486,7 +1518,7 @@ audioop_adpcm2lin(PyObject *self, PyObject *args) { signed char *cp; signed char *ncp; - int len, size, valpred, step, delta, index, sign, vpdiff; + int len, new_len, size, valpred, step, delta, index, sign, vpdiff; PyObject *rv, *str, *state; int i, inputbuffer = 0, bufferstep; @@ -1508,7 +1540,13 @@ audioop_adpcm2lin(PyObject *self, PyObject *args) } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) ) return 0; - str = PyBytes_FromStringAndSize(NULL, len*size*2); + new_len = len*size*2; + if (new_len < 0) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return 0; + } + str = PyBytes_FromStringAndSize(NULL, new_len); if ( str == 0 ) return 0; ncp = (signed char *)PyBytes_AsString(str); @@ -1516,7 +1554,7 @@ audioop_adpcm2lin(PyObject *self, PyObject *args) step = stepsizeTable[index]; bufferstep = 0; - for ( i=0; i < len*size*2; i += size ) { + for ( i=0; i < new_len; i += size ) { /* Step 1 - get the delta value and compute next index */ if ( bufferstep ) { delta = inputbuffer & 0xf; diff --git a/Modules/binascii.c b/Modules/binascii.c index d3e8a51..ea34bcd 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -198,6 +198,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args) if ( !PyArg_ParseTuple(args, "t#:a2b_uu", &ascii_data, &ascii_len) ) return NULL; + assert(ascii_len >= 0); + /* First byte: binary data length (in bytes) */ bin_len = (*ascii_data++ - ' ') & 077; ascii_len--; @@ -355,6 +357,11 @@ binascii_a2b_base64(PyObject *self, PyObject *args) if ( !PyArg_ParseTuple(args, "t#:a2b_base64", &ascii_data, &ascii_len) ) return NULL; + assert(ascii_len >= 0); + + if (ascii_len > PY_SSIZE_T_MAX - 3) + return PyErr_NoMemory(); + bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ /* Allocate the buffer */ @@ -448,6 +455,9 @@ binascii_b2a_base64(PyObject *self, PyObject *args) if ( !PyArg_ParseTuple(args, "s#:b2a_base64", &bin_data, &bin_len) ) return NULL; + + assert(bin_len >= 0); + if ( bin_len > BASE64_MAXBIN ) { PyErr_SetString(Error, "Too much data for base64 line"); return NULL; @@ -507,6 +517,11 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) if ( !PyArg_ParseTuple(args, "t#:a2b_hqx", &ascii_data, &len) ) return NULL; + assert(len >= 0); + + if (len > PY_SSIZE_T_MAX - 2) + return PyErr_NoMemory(); + /* Allocate a string that is too big (fixed later) Add two to the initial length to prevent interning which would preclude subsequent resizing. */ @@ -574,6 +589,11 @@ binascii_rlecode_hqx(PyObject *self, PyObject *args) if ( !PyArg_ParseTuple(args, "s#:rlecode_hqx", &in_data, &len) ) return NULL; + assert(len >= 0); + + if (len > PY_SSIZE_T_MAX / 2 - 2) + return PyErr_NoMemory(); + /* Worst case: output is twice as big as input (fixed later) */ if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) return NULL; @@ -627,6 +647,11 @@ binascii_b2a_hqx(PyObject *self, PyObject *args) if ( !PyArg_ParseTuple(args, "s#:b2a_hqx", &bin_data, &len) ) return NULL; + assert(len >= 0); + + if (len > PY_SSIZE_T_MAX / 2 - 2) + return PyErr_NoMemory(); + /* Allocate a buffer that is at least large enough */ if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) return NULL; @@ -669,9 +694,13 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) if ( !PyArg_ParseTuple(args, "s#:rledecode_hqx", &in_data, &in_len) ) return NULL; + assert(in_len >= 0); + /* Empty string is a special case */ if ( in_len == 0 ) return PyBytes_FromStringAndSize("", 0); + else if (in_len > PY_SSIZE_T_MAX / 2) + return PyErr_NoMemory(); /* Allocate a buffer of reasonable size. Resized when needed */ out_len = in_len*2; @@ -697,6 +726,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) #define OUTBYTE(b) \ do { \ if ( --out_len_left < 0 ) { \ + if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \ if (_PyBytes_Resize(&rv, 2*out_len) < 0) \ { Py_DECREF(rv); return NULL; } \ out_data = (unsigned char *)PyBytes_AS_STRING(rv) \ @@ -769,7 +799,7 @@ binascii_crc_hqx(PyObject *self, PyObject *args) if ( !PyArg_ParseTuple(args, "s#i:crc_hqx", &bin_data, &len, &crc) ) return NULL; - while(len--) { + while(len-- > 0) { crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++]; } @@ -925,7 +955,7 @@ binascii_crc32(PyObject *self, PyObject *args) return NULL; crc = ~ crc; - while (len--) { + while (len-- > 0) { crc = crc_32_tab[(crc ^ *bin_data++) & 0xff] ^ (crc >> 8); /* Note: (crc >> 8) MUST zero fill on left */ } @@ -948,6 +978,10 @@ binascii_hexlify(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s#:b2a_hex", &argbuf, &arglen)) return NULL; + assert(arglen >= 0); + if (arglen > PY_SSIZE_T_MAX / 2) + return PyErr_NoMemory(); + retval = PyBytes_FromStringAndSize(NULL, arglen*2); if (!retval) return NULL; @@ -999,6 +1033,8 @@ binascii_unhexlify(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s#:a2b_hex", &argbuf, &arglen)) return NULL; + assert(arglen >= 0); + /* XXX What should we do about strings with an odd length? Should * we add an implicit leading zero, or a trailing zero? For now, * raise an exception. diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 546f4e2..d6bafe7 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -172,13 +172,17 @@ static PyGetSetDef codecctx_getsets[] = { static int expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) { - Py_ssize_t orgpos, orgsize; + Py_ssize_t orgpos, orgsize, incsize; orgpos = (Py_ssize_t)((char *)buf->outbuf - PyBytes_AS_STRING(buf->outobj)); orgsize = PyBytes_GET_SIZE(buf->outobj); - if (_PyBytes_Resize(&buf->outobj, orgsize + ( - esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize)) == -1) + incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize); + + if (orgsize > PY_SSIZE_T_MAX - incsize) + return -1; + + if (_PyBytes_Resize(&buf->outobj, orgsize + incsize) == -1) return -1; buf->outbuf = (unsigned char *)PyBytes_AS_STRING(buf->outobj) +orgpos; @@ -481,6 +485,12 @@ multibytecodec_encode(MultibyteCodec *codec, buf.excobj = NULL; buf.inbuf = buf.inbuf_top = *data; buf.inbuf_end = buf.inbuf_top + datalen; + + if (datalen > (PY_SSIZE_T_MAX - 16) / 2) { + PyErr_NoMemory(); + goto errorexit; + } + buf.outobj = PyBytes_FromStringAndSize(NULL, datalen * 2 + 16); if (buf.outobj == NULL) goto errorexit; @@ -743,6 +753,11 @@ encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, origpending = ctx->pendingsize; if (origpending > 0) { + if (datalen > PY_SSIZE_T_MAX - ctx->pendingsize) { + PyErr_NoMemory(); + /* inbuf_tmp == NULL */ + goto errorexit; + } inbuf_tmp = PyMem_New(Py_UNICODE, datalen + ctx->pendingsize); if (inbuf_tmp == NULL) goto errorexit; @@ -805,9 +820,10 @@ decoder_append_pending(MultibyteStatefulDecoderContext *ctx, Py_ssize_t npendings; npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); - if (npendings + ctx->pendingsize > MAXDECPENDING) { - PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow"); - return -1; + if (npendings + ctx->pendingsize > MAXDECPENDING || + npendings > PY_SSIZE_T_MAX - ctx->pendingsize) { + PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow"); + return -1; } memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings); ctx->pendingsize += npendings; @@ -1009,7 +1025,7 @@ mbidecoder_decode(MultibyteIncrementalDecoderObject *self, PyObject *args, PyObject *kwargs) { MultibyteDecodeBuffer buf; - char *data, *wdata; + char *data, *wdata = NULL; Py_ssize_t wsize, finalsize = 0, size, origpending; int final = 0; @@ -1025,6 +1041,10 @@ mbidecoder_decode(MultibyteIncrementalDecoderObject *self, wdata = data; } else { + if (size > PY_SSIZE_T_MAX - self->pendingsize) { + PyErr_NoMemory(); + goto errorexit; + } wsize = size + self->pendingsize; wdata = PyMem_Malloc(wsize); if (wdata == NULL) @@ -1244,6 +1264,10 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self, PyObject *ctr; char *ctrdata; + if (PyBytes_GET_SIZE(cres) > PY_SSIZE_T_MAX - self->pendingsize) { + PyErr_NoMemory(); + goto errorexit; + } rsize = PyBytes_GET_SIZE(cres) + self->pendingsize; ctr = PyBytes_FromStringAndSize(NULL, rsize); if (ctr == NULL) diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c index 6c2d5a0..4dd4fe31 100644 --- a/Modules/datetimemodule.c +++ b/Modules/datetimemodule.c @@ -1111,6 +1111,8 @@ format_utcoffset(char *buf, size_t buflen, const char *sep, char sign; int none; + assert(buflen >= 1); + offset = call_utcoffset(tzinfo, tzinfoarg, &none); if (offset == -1 && PyErr_Occurred()) return -1; @@ -1250,6 +1252,11 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, * a new format. Since computing the replacements for those codes * is expensive, don't unless they're actually used. */ + if (flen > INT_MAX - 1) { + PyErr_NoMemory(); + goto Done; + } + totalnew = flen + 1; /* realistic if no %z/%Z */ newfmt = PyBytes_FromStringAndSize(NULL, totalnew); if (newfmt == NULL) goto Done; |