[Python-checkins] bpo-35436: Add missing PyErr_NoMemory() calls and other minor bug fixes. (GH-11015) (GH-11020)

Serhiy Storchaka webhook-mailer at python.org
Fri Dec 7 07:17:47 EST 2018


https://github.com/python/cpython/commit/602d307ac5e8a2da38a193dca3bdfef5994dfe67
commit: 602d307ac5e8a2da38a193dca3bdfef5994dfe67
branch: 3.7
author: Zackery Spytz <zspytz at gmail.com>
committer: Serhiy Storchaka <storchaka at gmail.com>
date: 2018-12-07T14:17:43+02:00
summary:

bpo-35436: Add missing PyErr_NoMemory() calls and other minor bug fixes. (GH-11015) (GH-11020)

(cherry picked from commit 4c49da0cb7434c676d70b9ccf38aca82ac0d64a9)

files:
A Misc/NEWS.d/next/Core and Builtins/2018-12-07-02-38-01.bpo-35436.0VW7p9.rst
M Modules/_abc.c
M Modules/_ctypes/_ctypes.c
M Modules/_ctypes/callbacks.c
M Modules/_io/winconsoleio.c
M Modules/_multiprocessing/semaphore.c
M Modules/_ssl.c
M Modules/posixmodule.c
M Objects/capsule.c
M PC/getpathp.c
M PC/launcher.c
M Parser/myreadline.c
M Parser/tokenizer.c
M Python/ast.c
M Python/marshal.c
M Python/pystrtod.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-12-07-02-38-01.bpo-35436.0VW7p9.rst b/Misc/NEWS.d/next/Core and Builtins/2018-12-07-02-38-01.bpo-35436.0VW7p9.rst
new file mode 100644
index 000000000000..542fe93a00eb
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2018-12-07-02-38-01.bpo-35436.0VW7p9.rst	
@@ -0,0 +1,2 @@
+Fix various issues with memory allocation error handling.  Patch by Zackery
+Spytz.
diff --git a/Modules/_abc.c b/Modules/_abc.c
index 9de199fa143f..36c1757b5fd3 100644
--- a/Modules/_abc.c
+++ b/Modules/_abc.c
@@ -728,6 +728,10 @@ subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
     // Weakref callback may remove entry from set.
     // So we take snapshot of registry first.
     PyObject **copy = PyMem_Malloc(sizeof(PyObject*) * registry_size);
+    if (copy == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
     PyObject *key;
     Py_ssize_t pos = 0;
     Py_hash_t hash;
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 3bb96774b0c8..c5fc811ad98e 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -305,8 +305,10 @@ _ctypes_alloc_format_string_for_type(char code, int big_endian)
     }
 
     result = PyMem_Malloc(3);
-    if (result == NULL)
+    if (result == NULL) {
+        PyErr_NoMemory();
         return NULL;
+    }
 
     result[0] = big_endian ? '>' : '<';
     result[1] = pep_code;
@@ -366,8 +368,10 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
     if (prefix)
         prefix_len += strlen(prefix);
     new_prefix = PyMem_Malloc(prefix_len);
-    if (new_prefix == NULL)
+    if (new_prefix == NULL) {
+        PyErr_NoMemory();
         return NULL;
+    }
     new_prefix[0] = '\0';
     if (prefix)
         strcpy(new_prefix, prefix);
@@ -1851,6 +1855,10 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
 #else
         suffix = PyUnicode_InternFromString("_be");
 #endif
+    if (suffix == NULL) {
+        Py_DECREF(swapped_args);
+        return NULL;
+    }
 
     newname = PyUnicode_Concat(name, suffix);
     if (newname == NULL) {
diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c
index d579291b62fe..ec9f44336e0e 100644
--- a/Modules/_ctypes/callbacks.c
+++ b/Modules/_ctypes/callbacks.c
@@ -305,7 +305,6 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
 
     p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs);
     if (p == NULL) {
-        PyErr_NoMemory();
         return NULL;
     }
 
diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c
index 4d3d695e4210..c11c1e09f4c3 100644
--- a/Modules/_io/winconsoleio.c
+++ b/Modules/_io/winconsoleio.c
@@ -815,11 +815,13 @@ _io__WindowsConsoleIO_readall_impl(winconsoleio *self)
             }
             bufsize = newsize;
 
-            buf = PyMem_Realloc(buf, (bufsize + 1) * sizeof(wchar_t));
-            if (!buf) {
+            wchar_t *tmp = PyMem_Realloc(buf,
+                                         (bufsize + 1) * sizeof(wchar_t));
+            if (tmp == NULL) {
                 PyMem_Free(buf);
                 return NULL;
             }
+            buf = tmp;
         }
 
         subbuf = read_console_w(self->handle, bufsize - len, &n);
diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c
index 0092b1393464..0cc46b53222e 100644
--- a/Modules/_multiprocessing/semaphore.c
+++ b/Modules/_multiprocessing/semaphore.c
@@ -449,8 +449,9 @@ semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
     if (!unlink) {
         name_copy = PyMem_Malloc(strlen(name) + 1);
-        if (name_copy == NULL)
-            goto failure;
+        if (name_copy == NULL) {
+            return PyErr_NoMemory();
+        }
         strcpy(name_copy, name);
     }
 
@@ -473,7 +474,9 @@ semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     if (handle != SEM_FAILED)
         SEM_CLOSE(handle);
     PyMem_Free(name_copy);
-    _PyMp_SetError(NULL, MP_STANDARD_ERROR);
+    if (!PyErr_Occurred()) {
+        _PyMp_SetError(NULL, MP_STANDARD_ERROR);
+    }
     return NULL;
 }
 
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index f9d1b8c30877..310b38bf11f4 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -912,6 +912,11 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
     PySSL_BEGIN_ALLOW_THREADS
     self->ssl = SSL_new(ctx);
     PySSL_END_ALLOW_THREADS
+    if (self->ssl == NULL) {
+        Py_DECREF(self);
+        _setSSLError(NULL, 0, __FILE__, __LINE__);
+        return NULL;
+    }
     SSL_set_app_data(self->ssl, self);
     if (sock) {
         SSL_set_fd(self->ssl, Py_SAFE_DOWNCAST(sock->sock_fd, SOCKET_T, int));
@@ -1241,6 +1246,10 @@ _get_peer_alt_names (X509 *certificate) {
 
     /* get a memory buffer */
     biobuf = BIO_new(BIO_s_mem());
+    if (biobuf == NULL) {
+        PyErr_SetString(PySSLErrorObject, "failed to allocate BIO");
+        return NULL;
+    }
 
     names = (GENERAL_NAMES *)X509_get_ext_d2i(
         certificate, NID_subject_alt_name, NULL, NULL);
@@ -1593,6 +1602,10 @@ _decode_certificate(X509 *certificate) {
 
     /* get a memory buffer */
     biobuf = BIO_new(BIO_s_mem());
+    if (biobuf == NULL) {
+        PyErr_SetString(PySSLErrorObject, "failed to allocate BIO");
+        goto fail0;
+    }
 
     (void) BIO_reset(biobuf);
     serialNumber = X509_get_serialNumber(certificate);
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index cab30c21025c..5403660ba45e 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -6229,8 +6229,7 @@ os_getgroups_impl(PyObject *module)
     } else {
         alt_grouplist = PyMem_New(gid_t, n);
         if (alt_grouplist == NULL) {
-            errno = EINVAL;
-            return posix_error();
+            return PyErr_NoMemory();
         }
     }
 
@@ -6255,8 +6254,7 @@ os_getgroups_impl(PyObject *module)
             } else {
                 alt_grouplist = PyMem_New(gid_t, n);
                 if (alt_grouplist == NULL) {
-                    errno = EINVAL;
-                    return posix_error();
+                    return PyErr_NoMemory();
                 }
                 n = getgroups(n, alt_grouplist);
                 if (n == -1) {
diff --git a/Objects/capsule.c b/Objects/capsule.c
index acd3de637dd5..4e15b440b170 100644
--- a/Objects/capsule.c
+++ b/Objects/capsule.c
@@ -201,7 +201,7 @@ PyCapsule_Import(const char *name, int no_block)
     char *name_dup = (char *)PyMem_MALLOC(name_length);
 
     if (!name_dup) {
-        return NULL;
+        return PyErr_NoMemory();
     }
 
     memcpy(name_dup, name, name_length);
diff --git a/PC/getpathp.c b/PC/getpathp.c
index 4075463f2260..1b553d53affa 100644
--- a/PC/getpathp.c
+++ b/PC/getpathp.c
@@ -576,6 +576,9 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path,
     size_t prefixlen = wcslen(prefix);
 
     wchar_t *buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t));
+    if (buf == NULL) {
+        goto error;
+    }
     buf[0] = '\0';
 
     while (!feof(sp_file)) {
@@ -603,17 +606,22 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path,
 
         DWORD wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, NULL, 0);
         wchar_t *wline = (wchar_t*)PyMem_RawMalloc((wn + 1) * sizeof(wchar_t));
+        if (wline == NULL) {
+            goto error;
+        }
         wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, wline, wn + 1);
         wline[wn] = '\0';
 
         size_t usedsiz = wcslen(buf);
         while (usedsiz + wn + prefixlen + 4 > bufsiz) {
             bufsiz += MAXPATHLEN;
-            buf = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) * sizeof(wchar_t));
-            if (!buf) {
+            wchar_t *tmp = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) *
+                                                            sizeof(wchar_t));
+            if (tmp == NULL) {
                 PyMem_RawFree(wline);
                 goto error;
             }
+            buf = tmp;
         }
 
         if (usedsiz) {
diff --git a/PC/launcher.c b/PC/launcher.c
index 0242f2639119..4c620dab7c09 100644
--- a/PC/launcher.c
+++ b/PC/launcher.c
@@ -1763,6 +1763,9 @@ process(int argc, wchar_t ** argv)
         }
         cch += (DWORD)wcslen(PYTHON_EXECUTABLE) + 1 + 1; /* include sep and null */
         executable = (wchar_t *)malloc(cch * sizeof(wchar_t));
+        if (executable == NULL) {
+            error(RC_NO_MEMORY, L"A memory allocation failed");
+        }
         cch_actual = MultiByteToWideChar(CP_UTF8, 0, start, len, executable, cch);
         if (!cch_actual) {
             error(RC_BAD_VENV_CFG, L"Cannot decode home path in '%ls'",
diff --git a/Parser/myreadline.c b/Parser/myreadline.c
index edb291a6691a..58dc0f75fe24 100644
--- a/Parser/myreadline.c
+++ b/Parser/myreadline.c
@@ -153,20 +153,37 @@ _PyOS_WindowsConsoleReadline(HANDLE hStdIn)
             wbuf = (wchar_t*)PyMem_RawMalloc(wbuflen * sizeof(wchar_t));
             if (wbuf)
                 wcscpy_s(wbuf, wbuflen, wbuf_local);
+            else {
+                PyErr_NoMemory();
+                goto exit;
+            }
+        }
+        else {
+            wchar_t *tmp = PyMem_RawRealloc(wbuf, wbuflen * sizeof(wchar_t));
+            if (tmp == NULL) {
+                PyErr_NoMemory();
+                goto exit;
+            }
+            wbuf = tmp;
         }
-        else
-            wbuf = (wchar_t*)PyMem_RawRealloc(wbuf, wbuflen * sizeof(wchar_t));
     }
 
     if (wbuf[0] == '\x1a') {
         buf = PyMem_RawMalloc(1);
         if (buf)
             buf[0] = '\0';
+        else {
+            PyErr_NoMemory();
+        }
         goto exit;
     }
 
     u8len = WideCharToMultiByte(CP_UTF8, 0, wbuf, total_read, NULL, 0, NULL, NULL);
     buf = PyMem_RawMalloc(u8len + 1);
+    if (buf == NULL) {
+        PyErr_NoMemory();
+        goto exit;
+    }
     u8len = WideCharToMultiByte(CP_UTF8, 0, wbuf, total_read, buf, u8len, NULL, NULL);
     buf[u8len] = '\0';
 
@@ -211,8 +228,12 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
                     int wlen;
                     wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1,
                             NULL, 0);
-                    if (wlen &&
-                        (wbuf = PyMem_RawMalloc(wlen * sizeof(wchar_t)))) {
+                    if (wlen) {
+                        wbuf = PyMem_RawMalloc(wlen * sizeof(wchar_t));
+                        if (wbuf == NULL) {
+                            PyErr_NoMemory();
+                            return NULL;
+                        }
                         wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1,
                                 wbuf, wlen);
                         if (wlen) {
@@ -236,8 +257,10 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
 
     n = 100;
     p = (char *)PyMem_RawMalloc(n);
-    if (p == NULL)
+    if (p == NULL) {
+        PyErr_NoMemory();
         return NULL;
+    }
 
     fflush(sys_stdout);
     if (prompt)
@@ -314,6 +337,10 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
 
     if (_PyOS_ReadlineLock == NULL) {
         _PyOS_ReadlineLock = PyThread_allocate_lock();
+        if (_PyOS_ReadlineLock == NULL) {
+            PyErr_SetString(PyExc_MemoryError, "can't allocate lock");
+            return NULL;
+        }
     }
 
     _PyOS_ReadlineTState = PyThreadState_GET();
@@ -341,8 +368,12 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
 
     len = strlen(rv) + 1;
     res = PyMem_Malloc(len);
-    if (res != NULL)
+    if (res != NULL) {
         memcpy(res, rv, len);
+    }
+    else {
+        PyErr_NoMemory();
+    }
     PyMem_RawFree(rv);
 
     return res;
diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c
index fbc98880c9a5..1a36f1c3840a 100644
--- a/Parser/tokenizer.c
+++ b/Parser/tokenizer.c
@@ -953,6 +953,11 @@ tok_nextc(struct tok_state *tok)
                 buflen = PyBytes_GET_SIZE(u);
                 buf = PyBytes_AS_STRING(u);
                 newtok = PyMem_MALLOC(buflen+1);
+                if (newtok == NULL) {
+                    Py_DECREF(u);
+                    tok->done = E_NOMEM;
+                    return EOF;
+                }
                 strcpy(newtok, buf);
                 Py_DECREF(u);
             }
diff --git a/Python/ast.c b/Python/ast.c
index 07227c238ef4..1e182c7d782a 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -4092,6 +4092,9 @@ parsenumber(struct compiling *c, const char *s)
     }
     /* Create a duplicate without underscores. */
     dup = PyMem_Malloc(strlen(s) + 1);
+    if (dup == NULL) {
+        return PyErr_NoMemory();
+    }
     end = dup;
     for (; *s; s++) {
         if (*s != '_') {
@@ -4326,8 +4329,10 @@ fstring_compile_expr(const char *expr_start, const char *expr_end,
     len = expr_end - expr_start;
     /* Allocate 3 extra bytes: open paren, close paren, null byte. */
     str = PyMem_RawMalloc(len + 3);
-    if (str == NULL)
+    if (str == NULL) {
+        PyErr_NoMemory();
         return NULL;
+    }
 
     str[0] = '(';
     memcpy(str+1, expr_start, len);
diff --git a/Python/marshal.c b/Python/marshal.c
index 6d06266c6a8e..7d60614e712a 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -689,11 +689,12 @@ r_string(Py_ssize_t n, RFILE *p)
         p->buf_size = n;
     }
     else if (p->buf_size < n) {
-        p->buf = PyMem_REALLOC(p->buf, n);
-        if (p->buf == NULL) {
+        char *tmp = PyMem_REALLOC(p->buf, n);
+        if (tmp == NULL) {
             PyErr_NoMemory();
             return NULL;
         }
+        p->buf = tmp;
         p->buf_size = n;
     }
 
diff --git a/Python/pystrtod.c b/Python/pystrtod.c
index 461e8dcb5e0c..fea7e45c3b62 100644
--- a/Python/pystrtod.c
+++ b/Python/pystrtod.c
@@ -398,6 +398,9 @@ _Py_string_to_number_with_underscores(
     }
 
     dup = PyMem_Malloc(orig_len + 1);
+    if (dup == NULL) {
+        return PyErr_NoMemory();
+    }
     end = dup;
     prev = '\0';
     last = s + orig_len;



More information about the Python-checkins mailing list