diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-12-07 16:09:23 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-07 16:09:23 (GMT) |
commit | 2d6bc25dbc3dc5662f13917eb759f92842bf6de6 (patch) | |
tree | d1dde41b6c7e9c5dafa95703bd4f0a4ab6b2bfb7 | |
parent | 19f6e83bf03b3ce22300638906bd90dd2dd5c463 (diff) | |
download | cpython-2d6bc25dbc3dc5662f13917eb759f92842bf6de6.zip cpython-2d6bc25dbc3dc5662f13917eb759f92842bf6de6.tar.gz cpython-2d6bc25dbc3dc5662f13917eb759f92842bf6de6.tar.bz2 |
bpo-35436: Add missing PyErr_NoMemory() calls and other minor bug fixes. (GH-11015) (GH-11020) (GH-11026)
(cherry picked from commit 4c49da0cb7434c676d70b9ccf38aca82ac0d64a9)
(cherry picked from commit 602d307ac5e8a2da38a193dca3bdfef5994dfe67)
Co-authored-by: Zackery Spytz <zspytz@gmail.com>
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2018-12-07-02-38-01.bpo-35436.0VW7p9.rst | 2 | ||||
-rw-r--r-- | Modules/_ctypes/_ctypes.c | 12 | ||||
-rw-r--r-- | Modules/_ctypes/callbacks.c | 7 | ||||
-rw-r--r-- | Modules/_io/winconsoleio.c | 6 | ||||
-rw-r--r-- | Modules/_multiprocessing/semaphore.c | 9 | ||||
-rw-r--r-- | Modules/_ssl.c | 13 | ||||
-rw-r--r-- | Modules/posixmodule.c | 6 | ||||
-rw-r--r-- | Objects/capsule.c | 2 | ||||
-rw-r--r-- | PC/getpathp.c | 12 | ||||
-rw-r--r-- | Parser/myreadline.c | 43 | ||||
-rw-r--r-- | Parser/tokenizer.c | 5 | ||||
-rw-r--r-- | Python/ast.c | 7 | ||||
-rw-r--r-- | Python/marshal.c | 5 | ||||
-rw-r--r-- | Python/pystrtod.c | 7 |
14 files changed, 107 insertions, 29 deletions
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 0000000..542fe93 --- /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/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index c5b499c..24d6485 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -306,8 +306,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; @@ -367,8 +369,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); @@ -1856,6 +1860,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 b958f30..c8773a1 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -309,7 +309,6 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs) p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs); if (p == NULL) { - PyErr_NoMemory(); return NULL; } @@ -347,7 +346,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, assert(CThunk_CheckExact((PyObject *)p)); p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure), - &p->pcl_exec); + &p->pcl_exec); if (p->pcl_write == NULL) { PyErr_NoMemory(); goto error; @@ -397,8 +396,8 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p); #else result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn, - p, - p->pcl_exec); + p, + p->pcl_exec); #endif if (result != FFI_OK) { PyErr_Format(PyExc_RuntimeError, diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 979bcfc..2f36806 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -832,11 +832,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 cea962a..4ff454f 100644 --- a/Modules/_multiprocessing/semaphore.c +++ b/Modules/_multiprocessing/semaphore.c @@ -439,8 +439,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); } @@ -463,7 +464,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 2b043da..a188d6a 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -685,6 +685,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)); @@ -1040,6 +1045,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; + } i = -1; while ((i = X509_get_ext_by_NID( @@ -1415,6 +1424,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 03825c3..776a3d2 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6127,8 +6127,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(); } } @@ -6153,8 +6152,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 acd3de6..4e15b44 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 af4af76..880ea7b9 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -586,6 +586,9 @@ read_pth_file(const wchar_t *path, wchar_t *prefix, int *isolated, int *nosite) 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)) { @@ -611,17 +614,22 @@ read_pth_file(const wchar_t *path, wchar_t *prefix, int *isolated, int *nosite) 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/Parser/myreadline.c b/Parser/myreadline.c index 476af71..34a6f8b 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -162,20 +162,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'; @@ -224,8 +241,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) { @@ -249,8 +270,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) @@ -328,6 +351,10 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) #ifdef WITH_THREAD if (_PyOS_ReadlineLock == NULL) { _PyOS_ReadlineLock = PyThread_allocate_lock(); + if (_PyOS_ReadlineLock == NULL) { + PyErr_SetString(PyExc_MemoryError, "can't allocate lock"); + return NULL; + } } #endif @@ -360,8 +387,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 ab72f61..0d3ad4d 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -956,6 +956,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 51175cd..675063e 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -4104,6 +4104,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 != '_') { @@ -4338,8 +4341,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 91a57c2..dbe75e3 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -677,11 +677,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 1c63560..509048c 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; @@ -433,8 +436,8 @@ _Py_string_to_number_with_underscores( error: PyMem_Free(dup); PyErr_Format(PyExc_ValueError, - "could not convert string to %s: " - "%R", what, obj); + "could not convert string to %s: " + "%R", what, obj); return NULL; } |