[Python-checkins] cpython: Issue #23450: Fixed possible integer overflows.

serhiy.storchaka python-checkins at python.org
Mon Feb 16 20:14:27 CET 2015


https://hg.python.org/cpython/rev/a84ae2ccd220
changeset: 94653:a84ae2ccd220
user: Serhiy Storchaka <storchaka at gmail.com>
date: Mon Feb 16 20:52:17 2015 +0200
summary:
 Issue #23450: Fixed possible integer overflows.
files:
 Modules/_ctypes/_ctypes.c | 2 +-
 Modules/_elementtree.c | 57 +++++++++++++++-----------
 Modules/_sqlite/row.c | 2 +-
 Modules/_tkinter.c | 45 +++++++++++---------
 Objects/bytesobject.c | 2 +-
 Objects/obmalloc.c | 2 +-
 Python/codecs.c | 2 +-
 Python/marshal.c | 2 +-
 8 files changed, 64 insertions(+), 50 deletions(-)
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -301,7 +301,7 @@
 char *new_prefix;
 char *result;
 char buf[32];
- int prefix_len;
+ Py_ssize_t prefix_len;
 int k;
 
 prefix_len = 32 * ndim + 3;
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -11,6 +11,8 @@
 *--------------------------------------------------------------------
 */
 
+#define PY_SSIZE_T_CLEAN
+
 #include "Python.h"
 #include "structmember.h"
 
@@ -185,8 +187,8 @@
 PyObject* attrib;
 
 /* child elements */
- int length; /* actual number of items */
- int allocated; /* allocated items */
+ Py_ssize_t length; /* actual number of items */
+ Py_ssize_t allocated; /* allocated items */
 
 /* this either points to _children or to a malloced buffer */
 PyObject* *children;
@@ -251,7 +253,7 @@
 dealloc_extra(ElementObject* self)
 {
 ElementObjectExtra *myextra;
- int i;
+ Py_ssize_t i;
 
 if (!self->extra)
 return;
@@ -429,9 +431,9 @@
 }
 
 LOCAL(int)
-element_resize(ElementObject* self, int extra)
+element_resize(ElementObject* self, Py_ssize_t extra)
 {
- int size;
+ Py_ssize_t size;
 PyObject* *children;
 
 /* make sure self->children can hold the given number of extra
@@ -442,7 +444,7 @@
 return -1;
 }
 
- size = self->extra->length + extra;
+ size = self->extra->length + extra; /* never overflows */
 
 if (size > self->extra->allocated) {
 /* use Python 2.4's list growth strategy */
@@ -453,6 +455,8 @@
 * be safe.
 */
 size = size ? size : 1;
+ if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*))
+ goto nomemory;
 if (self->extra->children != self->extra->_children) {
 /* Coverity CID #182 size_error: Allocating 1 bytes to pointer
 * "children", which needs at least 4 bytes. Although it's a
@@ -613,7 +617,7 @@
 Py_VISIT(JOIN_OBJ(self->tail));
 
 if (self->extra) {
- int i;
+ Py_ssize_t i;
 Py_VISIT(self->extra->attrib);
 
 for (i = 0; i < self->extra->length; ++i)
@@ -689,7 +693,7 @@
 static PyObject*
 element_copy(ElementObject* self, PyObject* args)
 {
- int i;
+ Py_ssize_t i;
 ElementObject* element;
 
 if (!PyArg_ParseTuple(args, ":__copy__"))
@@ -728,7 +732,7 @@
 static PyObject*
 element_deepcopy(ElementObject* self, PyObject* args)
 {
- int i;
+ Py_ssize_t i;
 ElementObject* element;
 PyObject* tag;
 PyObject* attrib;
@@ -839,7 +843,7 @@
 static PyObject *
 element_getstate(ElementObject *self)
 {
- int i, noattrib;
+ Py_ssize_t i, noattrib;
 PyObject *instancedict = NULL, *children;
 
 /* Build a list of children. */
@@ -1077,7 +1081,7 @@
 static PyObject*
 element_find(ElementObject *self, PyObject *args, PyObject *kwds)
 {
- int i;
+ Py_ssize_t i;
 PyObject* tag;
 PyObject* namespaces = Py_None;
 static char *kwlist[] = {"path", "namespaces", 0};
@@ -1112,7 +1116,7 @@
 static PyObject*
 element_findtext(ElementObject *self, PyObject *args, PyObject *kwds)
 {
- int i;
+ Py_ssize_t i;
 PyObject* tag;
 PyObject* default_value = Py_None;
 PyObject* namespaces = Py_None;
@@ -1153,7 +1157,7 @@
 static PyObject*
 element_findall(ElementObject *self, PyObject *args, PyObject *kwds)
 {
- int i;
+ Py_ssize_t i;
 PyObject* out;
 PyObject* tag;
 PyObject* namespaces = Py_None;
@@ -1238,7 +1242,7 @@
 static PyObject*
 element_getchildren(ElementObject* self, PyObject* args)
 {
- int i;
+ Py_ssize_t i;
 PyObject* list;
 
 /* FIXME: report as deprecated? */
@@ -1310,11 +1314,9 @@
 static PyObject*
 element_insert(ElementObject* self, PyObject* args)
 {
- int i;
-
- int index;
+ Py_ssize_t index, i;
 PyObject* element;
- if (!PyArg_ParseTuple(args, "iO!:insert", &index,
+ if (!PyArg_ParseTuple(args, "nO!:insert", &index,
 &Element_Type, &element))
 return NULL;
 
@@ -1402,7 +1404,7 @@
 static PyObject*
 element_remove(ElementObject* self, PyObject* args)
 {
- int i;
+ Py_ssize_t i;
 
 PyObject* element;
 if (!PyArg_ParseTuple(args, "O!:remove", &Element_Type, &element))
@@ -1481,7 +1483,7 @@
 element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
 {
 ElementObject* self = (ElementObject*) self_;
- int i;
+ Py_ssize_t i;
 PyObject* old;
 
 if (!self->extra || index < 0 || index >= self->extra->length) {
@@ -2819,12 +2821,13 @@
 * message string is the default for the given error_code.
 */
 static void
-expat_set_error(enum XML_Error error_code, int line, int column, char *message)
+expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column,
+ const char *message)
 {
 PyObject *errmsg, *error, *position, *code;
 elementtreestate *st = ET_STATE_GLOBAL;
 
- errmsg = PyUnicode_FromFormat("%s: line %d, column %d",
+ errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd",
 message ? message : EXPAT(ErrorString)(error_code),
 line, column);
 if (errmsg == NULL)
@@ -2848,7 +2851,7 @@
 }
 Py_DECREF(code);
 
- position = Py_BuildValue("(ii)", line, column);
+ position = Py_BuildValue("(nn)", line, column);
 if (!position) {
 Py_DECREF(error);
 return;
@@ -3477,8 +3480,14 @@
 break;
 }
 
+ if (PyBytes_GET_SIZE(buffer) > INT_MAX) {
+ Py_DECREF(buffer);
+ Py_DECREF(reader);
+ PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
+ return NULL;
+ }
 res = expat_parse(
- self, PyBytes_AS_STRING(buffer), PyBytes_GET_SIZE(buffer), 0
+ self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0
 );
 
 Py_DECREF(buffer);
diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c
--- a/Modules/_sqlite/row.c
+++ b/Modules/_sqlite/row.c
@@ -159,7 +159,7 @@
 PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs)
 {
 PyObject* list;
- int nitems, i;
+ Py_ssize_t nitems, i;
 
 list = PyList_New(0);
 if (!list) {
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -21,6 +21,7 @@
 
 */
 
+#define PY_SSIZE_T_CLEAN
 
 #include "Python.h"
 #include <ctype.h>
@@ -34,7 +35,7 @@
 #endif
 
 #define CHECK_SIZE(size, elemsize) \
- ((size_t)(size) <= Py_MAX((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize)))
+ ((size_t)(size) <= Py_MIN((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize)))
 
 /* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
 it always; if Tcl is not threaded, the thread functions in
@@ -409,7 +410,7 @@
 SplitObj(PyObject *arg)
 {
 if (PyTuple_Check(arg)) {
- int i, size;
+ Py_ssize_t i, size;
 PyObject *elem, *newelem, *result;
 
 size = PyTuple_Size(arg);
@@ -425,7 +426,7 @@
 return NULL;
 }
 if (!result) {
- int k;
+ Py_ssize_t k;
 if (newelem == elem) {
 Py_DECREF(newelem);
 continue;
@@ -446,7 +447,7 @@
 /* Fall through, returning arg. */
 }
 else if (PyList_Check(arg)) {
- int i, size;
+ Py_ssize_t i, size;
 PyObject *elem, *newelem, *result;
 
 size = PyList_GET_SIZE(arg);
@@ -632,12 +633,12 @@
 /* some initial arguments need to be in argv */
 if (sync || use) {
 char *args;
- int len = 0;
+ Py_ssize_t len = 0;
 
 if (sync)
 len += sizeof "-sync";
 if (use)
- len += strlen(use) + sizeof "-use ";
+ len += strlen(use) + sizeof "-use "; /* never overflows */
 
 args = (char*)PyMem_Malloc(len);
 if (!args) {
@@ -887,9 +888,14 @@
 long longVal;
 int overflow;
 
- if (PyBytes_Check(value))
+ if (PyBytes_Check(value)) {
+ if (PyBytes_GET_SIZE(value) >= INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError, "bytes object is too long");
+ return NULL;
+ }
 return Tcl_NewByteArrayObj((unsigned char *)PyBytes_AS_STRING(value),
- PyBytes_GET_SIZE(value));
+ (int)PyBytes_GET_SIZE(value));
+ }
 else if (PyBool_Check(value))
 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
 else if (PyLong_CheckExact(value) &&
@@ -921,7 +927,7 @@
 }
 for (i = 0; i < size; i++)
 argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i));
- result = Tcl_NewListObj(size, argv);
+ result = Tcl_NewListObj((int)size, argv);
 PyMem_Free(argv);
 return result;
 }
@@ -946,7 +952,7 @@
 }
 kind = PyUnicode_KIND(value);
 if (kind == sizeof(Tcl_UniChar))
- return Tcl_NewUnicodeObj(inbuf, size);
+ return Tcl_NewUnicodeObj(inbuf, (int)size);
 allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
 outbuf = (Tcl_UniChar*)PyMem_Malloc(allocsize);
 /* Else overflow occurred, and we take the next exit */
@@ -971,7 +977,7 @@
 #endif
 outbuf[i] = ch;
 }
- result = Tcl_NewUnicodeObj(outbuf, size);
+ result = Tcl_NewUnicodeObj(outbuf, (int)size);
 PyMem_Free(outbuf);
 return result;
 }
@@ -1139,10 +1145,10 @@
 Tcl_IncrRefCount(objv[i]);
 }
 }
- *pobjc = objc;
+ *pobjc = (int)objc;
 return objv;
 finally:
- Tkapp_CallDeallocArgs(objv, objStore, objc);
+ Tkapp_CallDeallocArgs(objv, objStore, (int)objc);
 return NULL;
 }
 
@@ -1495,7 +1501,6 @@
 #ifdef WITH_THREAD
 TkappObject *self = (TkappObject*)selfptr;
 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
- TkappObject *self = (TkappObject*)selfptr;
 VarEvent *ev;
 PyObject *res, *exc_type, *exc_val;
 Tcl_Condition cond = NULL;
@@ -2721,20 +2726,20 @@
 
 typedef struct {
 PyObject* tuple;
- int size; /* current size */
- int maxsize; /* allocated size */
+ Py_ssize_t size; /* current size */
+ Py_ssize_t maxsize; /* allocated size */
 } FlattenContext;
 
 static int
-_bump(FlattenContext* context, int size)
+_bump(FlattenContext* context, Py_ssize_t size)
 {
 /* expand tuple to hold (at least) size new items.
 return true if successful, false if an exception was raised */
 
- int maxsize = context->maxsize * 2;
+ Py_ssize_t maxsize = context->maxsize * 2; /* never overflows */
 
 if (maxsize < context->size + size)
- maxsize = context->size + size;
+ maxsize = context->size + size; /* never overflows */
 
 context->maxsize = maxsize;
 
@@ -2746,7 +2751,7 @@
 {
 /* add tuple or list to argument tuple (recursively) */
 
- int i, size;
+ Py_ssize_t i, size;
 
 if (depth > 1000) {
 PyErr_SetString(PyExc_ValueError,
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -673,7 +673,7 @@
 "* wants int");
 goto error;
 }
- prec = PyLong_AsSsize_t(v);
+ prec = _PyLong_AsInt(v);
 if (prec == -1 && PyErr_Occurred())
 goto error;
 if (prec < 0)
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -1339,7 +1339,7 @@
 pool = (poolp)usable_arenas->pool_address;
 assert((block*)pool <= (block*)usable_arenas->address +
 ARENA_SIZE - POOL_SIZE);
- pool->arenaindex = usable_arenas - arenas;
+ pool->arenaindex = (uint)(usable_arenas - arenas);
 assert(&arenas[pool->arenaindex] == usable_arenas);
 pool->szidx = DUMMY_SIZE_IDX;
 usable_arenas->pool_address += POOL_SIZE;
diff --git a/Python/codecs.c b/Python/codecs.c
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -1006,7 +1006,7 @@
 c = PyUnicode_READ_CHAR(object, i);
 if (ucnhash_CAPI &&
 ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) {
- replsize = 1+1+1+strlen(buffer)+1;
+ replsize = 1+1+1+(int)strlen(buffer)+1;
 }
 else if (c >= 0x10000) {
 replsize = 1+1+8;
diff --git a/Python/marshal.c b/Python/marshal.c
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -279,7 +279,7 @@
 PyErr_SetString(PyExc_ValueError, "too many objects");
 goto err;
 }
- w = s;
+ w = (int)s;
 Py_INCREF(v);
 if (_Py_HASHTABLE_SET(p->hashtable, v, w) < 0) {
 Py_DECREF(v);
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /