]> granicus.if.org Git - python/commitdiff
Issue #23450: Fixed possible integer overflows.
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 16 Feb 2015 18:52:17 +0000 (20:52 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Mon, 16 Feb 2015 18:52:17 +0000 (20:52 +0200)
Modules/_ctypes/_ctypes.c
Modules/_elementtree.c
Modules/_sqlite/row.c
Modules/_tkinter.c
Objects/bytesobject.c
Objects/obmalloc.c
Python/codecs.c
Python/marshal.c

index 14ec4ce60c3179911529a47aec18dc76657993c5..23b8e93b462982d88c3789dcc48512f324b693f0 100644 (file)
@@ -301,7 +301,7 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
     char *new_prefix;
     char *result;
     char buf[32];
-    int prefix_len;
+    Py_ssize_t prefix_len;
     int k;
 
     prefix_len = 32 * ndim + 3;
index 9b3e9ed313b24c00eee18e26fc207528f85e7adb..bf4bc4a8a24cf83f263308285896800371c5112a 100644 (file)
@@ -11,6 +11,8 @@
  *--------------------------------------------------------------------
  */
 
+#define PY_SSIZE_T_CLEAN
+
 #include "Python.h"
 #include "structmember.h"
 
@@ -185,8 +187,8 @@ typedef struct {
     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 @@ LOCAL(void)
 dealloc_extra(ElementObject* self)
 {
     ElementObjectExtra *myextra;
-    int i;
+    Py_ssize_t i;
 
     if (!self->extra)
         return;
@@ -429,9 +431,9 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds)
 }
 
 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 @@ element_resize(ElementObject* self, int extra)
             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 @@ element_resize(ElementObject* self, int extra)
          * 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 @@ element_gc_traverse(ElementObject *self, visitproc visit, void *arg)
     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 @@ element_clearmethod(ElementObject* self, PyObject* args)
 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 @@ element_copy(ElementObject* self, PyObject* args)
 static PyObject*
 element_deepcopy(ElementObject* self, PyObject* args)
 {
-    int i;
+    Py_ssize_t i;
     ElementObject* element;
     PyObject* tag;
     PyObject* attrib;
@@ -839,7 +843,7 @@ element_sizeof(PyObject* myself, PyObject* args)
 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 @@ element_extend(ElementObject* self, PyObject* args)
 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 @@ element_find(ElementObject *self, PyObject *args, PyObject *kwds)
 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 @@ element_findtext(ElementObject *self, PyObject *args, PyObject *kwds)
 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 @@ element_get(ElementObject* self, PyObject* args, PyObject* kwds)
 static PyObject*
 element_getchildren(ElementObject* self, PyObject* args)
 {
-    int i;
+    Py_ssize_t i;
     PyObject* list;
 
     /* FIXME: report as deprecated? */
@@ -1310,11 +1314,9 @@ element_getitem(PyObject* self_, Py_ssize_t index)
 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 @@ element_makeelement(PyObject* self, PyObject* args, PyObject* kw)
 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 @@ static int
 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 @@ makeuniversal(XMLParserObject* self, const char* string)
  * 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 @@ expat_set_error(enum XML_Error error_code, int line, int column, char *message)
     }
     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 @@ xmlparser_parse_whole(XMLParserObject* self, PyObject* args)
             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);
index 64dfd06dffb6d7de68092a46210b3314272bc68f..ed8ad47ffc721e354534d9a5cac20912f9921b3e 100644 (file)
@@ -159,7 +159,7 @@ Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwa
 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) {
index d5396f6f0dcd42d67bbca03e99f40b63e1e3d08b..b23ee8a66510bb835bf526f86cf78a97e27607f7 100644 (file)
@@ -21,6 +21,7 @@ Copyright (C) 1994 Steen Lumholt.
 
 */
 
+#define PY_SSIZE_T_CLEAN
 
 #include "Python.h"
 #include <ctype.h>
@@ -34,7 +35,7 @@ Copyright (C) 1994 Steen Lumholt.
 #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 @@ static PyObject *
 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 @@ SplitObj(PyObject *arg)
                 return NULL;
             }
             if (!result) {
-                int k;
+                Py_ssize_t k;
                 if (newelem == elem) {
                     Py_DECREF(newelem);
                     continue;
@@ -446,7 +447,7 @@ SplitObj(PyObject *arg)
         /* 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 @@ Tkapp_New(const char *screenName, const char *className,
     /* 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 @@ AsObj(PyObject *value)
     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 @@ AsObj(PyObject *value)
         }
         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 @@ AsObj(PyObject *value)
         }
         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 @@ AsObj(PyObject *value)
 #endif
             outbuf[i] = ch;
         }
-        result = Tcl_NewUnicodeObj(outbuf, size);
+        result = Tcl_NewUnicodeObj(outbuf, (int)size);
         PyMem_Free(outbuf);
         return result;
     }
@@ -1139,10 +1145,10 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
             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 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
 #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 @@ static PyType_Spec Tkapp_Type_spec = {
 
 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 @@ _flatten1(FlattenContext* context, PyObject* item, int depth)
 {
     /* add tuple or list to argument tuple (recursively) */
 
-    int i, size;
+    Py_ssize_t i, size;
 
     if (depth > 1000) {
         PyErr_SetString(PyExc_ValueError,
index 30b0e50534412e00ff8cd81b055acb49f5b24df5..b015974f7c30f7a4668a9c5f03e2fa05e129e359 100644 (file)
@@ -673,7 +673,7 @@ _PyBytes_Format(PyObject *format, PyObject *args)
                             "* wants int");
                         goto error;
                     }
-                    prec = PyLong_AsSsize_t(v);
+                    prec = _PyLong_AsInt(v);
                     if (prec == -1 && PyErr_Occurred())
                         goto error;
                     if (prec < 0)
index e900cc3bb8173ee97778ff9ae1d3e53b4faf79f8..7cc889f817b62859acc7f1aae997de744ca87da0 100644 (file)
@@ -1339,7 +1339,7 @@ _PyObject_Alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize)
         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;
index a5588598b31a7cc6dda7cc05374cf02119c2e100..64fc3d633166f8ec25e840690a4091153ba8c1de 100644 (file)
@@ -1006,7 +1006,7 @@ PyObject *PyCodec_NameReplaceErrors(PyObject *exc)
             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;
index c1ce2fe8d6b47035b00c2aa07caf99ac9556f611..d26a997534dca232e83052cb9f50c3e2922adfcc 100644 (file)
@@ -279,7 +279,7 @@ w_ref(PyObject *v, char *flag, WFILE *p)
             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);