Skip to content

Commit 2d6bc25

Browse files
bpo-35436: Add missing PyErr_NoMemory() calls and other minor bug fixes. (GH-11015) (GH-11020) (GH-11026)
(cherry picked from commit 4c49da0) (cherry picked from commit 602d307) Co-authored-by: Zackery Spytz <[email protected]>
1 parent 19f6e83 commit 2d6bc25

File tree

14 files changed

+107
-29
lines changed

14 files changed

+107
-29
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix various issues with memory allocation error handling. Patch by Zackery
2+
Spytz.

‎Modules/_ctypes/_ctypes.c‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,10 @@ _ctypes_alloc_format_string_for_type(char code, int big_endian)
306306
}
307307

308308
result = PyMem_Malloc(3);
309-
if (result == NULL)
309+
if (result == NULL) {
310+
PyErr_NoMemory();
310311
return NULL;
312+
}
311313

312314
result[0] = big_endian ? '>' : '<';
313315
result[1] = pep_code;
@@ -367,8 +369,10 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
367369
if (prefix)
368370
prefix_len += strlen(prefix);
369371
new_prefix = PyMem_Malloc(prefix_len);
370-
if (new_prefix == NULL)
372+
if (new_prefix == NULL) {
373+
PyErr_NoMemory();
371374
return NULL;
375+
}
372376
new_prefix[0] = '\0';
373377
if (prefix)
374378
strcpy(new_prefix, prefix);
@@ -1856,6 +1860,10 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
18561860
#else
18571861
suffix = PyUnicode_InternFromString("_be");
18581862
#endif
1863+
if (suffix == NULL) {
1864+
Py_DECREF(swapped_args);
1865+
return NULL;
1866+
}
18591867

18601868
newname = PyUnicode_Concat(name, suffix);
18611869
if (newname == NULL) {

‎Modules/_ctypes/callbacks.c‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,6 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
309309

310310
p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs);
311311
if (p == NULL) {
312-
PyErr_NoMemory();
313312
return NULL;
314313
}
315314

@@ -347,7 +346,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable,
347346
assert(CThunk_CheckExact((PyObject *)p));
348347

349348
p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure),
350-
&p->pcl_exec);
349+
&p->pcl_exec);
351350
if (p->pcl_write == NULL) {
352351
PyErr_NoMemory();
353352
goto error;
@@ -397,8 +396,8 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable,
397396
result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p);
398397
#else
399398
result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn,
400-
p,
401-
p->pcl_exec);
399+
p,
400+
p->pcl_exec);
402401
#endif
403402
if (result != FFI_OK) {
404403
PyErr_Format(PyExc_RuntimeError,

‎Modules/_io/winconsoleio.c‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -832,11 +832,13 @@ _io__WindowsConsoleIO_readall_impl(winconsoleio *self)
832832
}
833833
bufsize = newsize;
834834

835-
buf = PyMem_Realloc(buf, (bufsize + 1) * sizeof(wchar_t));
836-
if (!buf) {
835+
wchar_t *tmp = PyMem_Realloc(buf,
836+
(bufsize + 1) * sizeof(wchar_t));
837+
if (tmp == NULL) {
837838
PyMem_Free(buf);
838839
return NULL;
839840
}
841+
buf = tmp;
840842
}
841843

842844
subbuf = read_console_w(self->handle, bufsize - len, &n);

‎Modules/_multiprocessing/semaphore.c‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,8 +439,9 @@ semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
439439

440440
if (!unlink) {
441441
name_copy = PyMem_Malloc(strlen(name) + 1);
442-
if (name_copy == NULL)
443-
goto failure;
442+
if (name_copy == NULL) {
443+
return PyErr_NoMemory();
444+
}
444445
strcpy(name_copy, name);
445446
}
446447

@@ -463,7 +464,9 @@ semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
463464
if (handle != SEM_FAILED)
464465
SEM_CLOSE(handle);
465466
PyMem_Free(name_copy);
466-
_PyMp_SetError(NULL, MP_STANDARD_ERROR);
467+
if (!PyErr_Occurred()) {
468+
_PyMp_SetError(NULL, MP_STANDARD_ERROR);
469+
}
467470
return NULL;
468471
}
469472

‎Modules/_ssl.c‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,11 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
685685
PySSL_BEGIN_ALLOW_THREADS
686686
self->ssl = SSL_new(ctx);
687687
PySSL_END_ALLOW_THREADS
688+
if (self->ssl == NULL) {
689+
Py_DECREF(self);
690+
_setSSLError(NULL, 0, __FILE__, __LINE__);
691+
return NULL;
692+
}
688693
SSL_set_app_data(self->ssl, self);
689694
if (sock) {
690695
SSL_set_fd(self->ssl, Py_SAFE_DOWNCAST(sock->sock_fd, SOCKET_T, int));
@@ -1040,6 +1045,10 @@ _get_peer_alt_names (X509 *certificate) {
10401045

10411046
/* get a memory buffer */
10421047
biobuf = BIO_new(BIO_s_mem());
1048+
if (biobuf == NULL) {
1049+
PyErr_SetString(PySSLErrorObject, "failed to allocate BIO");
1050+
return NULL;
1051+
}
10431052

10441053
i = -1;
10451054
while ((i = X509_get_ext_by_NID(
@@ -1415,6 +1424,10 @@ _decode_certificate(X509 *certificate) {
14151424

14161425
/* get a memory buffer */
14171426
biobuf = BIO_new(BIO_s_mem());
1427+
if (biobuf == NULL) {
1428+
PyErr_SetString(PySSLErrorObject, "failed to allocate BIO");
1429+
goto fail0;
1430+
}
14181431

14191432
(void) BIO_reset(biobuf);
14201433
serialNumber = X509_get_serialNumber(certificate);

‎Modules/posixmodule.c‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6127,8 +6127,7 @@ os_getgroups_impl(PyObject *module)
61276127
} else {
61286128
alt_grouplist = PyMem_New(gid_t, n);
61296129
if (alt_grouplist == NULL) {
6130-
errno = EINVAL;
6131-
return posix_error();
6130+
return PyErr_NoMemory();
61326131
}
61336132
}
61346133

@@ -6153,8 +6152,7 @@ os_getgroups_impl(PyObject *module)
61536152
} else {
61546153
alt_grouplist = PyMem_New(gid_t, n);
61556154
if (alt_grouplist == NULL) {
6156-
errno = EINVAL;
6157-
return posix_error();
6155+
return PyErr_NoMemory();
61586156
}
61596157
n = getgroups(n, alt_grouplist);
61606158
if (n == -1) {

‎Objects/capsule.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ PyCapsule_Import(const char *name, int no_block)
201201
char *name_dup = (char *)PyMem_MALLOC(name_length);
202202

203203
if (!name_dup) {
204-
return NULL;
204+
return PyErr_NoMemory();
205205
}
206206

207207
memcpy(name_dup, name, name_length);

‎PC/getpathp.c‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,9 @@ read_pth_file(const wchar_t *path, wchar_t *prefix, int *isolated, int *nosite)
586586
size_t prefixlen = wcslen(prefix);
587587

588588
wchar_t *buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t));
589+
if (buf == NULL) {
590+
goto error;
591+
}
589592
buf[0] = '\0';
590593

591594
while (!feof(sp_file)) {
@@ -611,17 +614,22 @@ read_pth_file(const wchar_t *path, wchar_t *prefix, int *isolated, int *nosite)
611614

612615
DWORD wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, NULL, 0);
613616
wchar_t *wline = (wchar_t*)PyMem_RawMalloc((wn + 1) * sizeof(wchar_t));
617+
if (wline == NULL) {
618+
goto error;
619+
}
614620
wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, wline, wn + 1);
615621
wline[wn] = '\0';
616622

617623
size_t usedsiz = wcslen(buf);
618624
while (usedsiz + wn + prefixlen + 4 > bufsiz) {
619625
bufsiz += MAXPATHLEN;
620-
buf = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) * sizeof(wchar_t));
621-
if (!buf) {
626+
wchar_t *tmp = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) *
627+
sizeof(wchar_t));
628+
if (tmp == NULL) {
622629
PyMem_RawFree(wline);
623630
goto error;
624631
}
632+
buf = tmp;
625633
}
626634

627635
if (usedsiz) {

‎Parser/myreadline.c‎

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,20 +162,37 @@ _PyOS_WindowsConsoleReadline(HANDLE hStdIn)
162162
wbuf = (wchar_t*)PyMem_RawMalloc(wbuflen * sizeof(wchar_t));
163163
if (wbuf)
164164
wcscpy_s(wbuf, wbuflen, wbuf_local);
165+
else {
166+
PyErr_NoMemory();
167+
goto exit;
168+
}
169+
}
170+
else {
171+
wchar_t *tmp = PyMem_RawRealloc(wbuf, wbuflen * sizeof(wchar_t));
172+
if (tmp == NULL) {
173+
PyErr_NoMemory();
174+
goto exit;
175+
}
176+
wbuf = tmp;
165177
}
166-
else
167-
wbuf = (wchar_t*)PyMem_RawRealloc(wbuf, wbuflen * sizeof(wchar_t));
168178
}
169179

170180
if (wbuf[0] == '\x1a') {
171181
buf = PyMem_RawMalloc(1);
172182
if (buf)
173183
buf[0] = '\0';
184+
else {
185+
PyErr_NoMemory();
186+
}
174187
goto exit;
175188
}
176189

177190
u8len = WideCharToMultiByte(CP_UTF8, 0, wbuf, total_read, NULL, 0, NULL, NULL);
178191
buf = PyMem_RawMalloc(u8len + 1);
192+
if (buf == NULL) {
193+
PyErr_NoMemory();
194+
goto exit;
195+
}
179196
u8len = WideCharToMultiByte(CP_UTF8, 0, wbuf, total_read, buf, u8len, NULL, NULL);
180197
buf[u8len] = '\0';
181198

@@ -224,8 +241,12 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
224241
int wlen;
225242
wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1,
226243
NULL, 0);
227-
if (wlen &&
228-
(wbuf = PyMem_RawMalloc(wlen * sizeof(wchar_t)))) {
244+
if (wlen) {
245+
wbuf = PyMem_RawMalloc(wlen * sizeof(wchar_t));
246+
if (wbuf == NULL) {
247+
PyErr_NoMemory();
248+
return NULL;
249+
}
229250
wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1,
230251
wbuf, wlen);
231252
if (wlen) {
@@ -249,8 +270,10 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
249270

250271
n = 100;
251272
p = (char *)PyMem_RawMalloc(n);
252-
if (p == NULL)
273+
if (p == NULL) {
274+
PyErr_NoMemory();
253275
return NULL;
276+
}
254277

255278
fflush(sys_stdout);
256279
if (prompt)
@@ -328,6 +351,10 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
328351
#ifdef WITH_THREAD
329352
if (_PyOS_ReadlineLock == NULL) {
330353
_PyOS_ReadlineLock = PyThread_allocate_lock();
354+
if (_PyOS_ReadlineLock == NULL) {
355+
PyErr_SetString(PyExc_MemoryError, "can't allocate lock");
356+
return NULL;
357+
}
331358
}
332359
#endif
333360

@@ -360,8 +387,12 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
360387

361388
len = strlen(rv) + 1;
362389
res = PyMem_Malloc(len);
363-
if (res != NULL)
390+
if (res != NULL) {
364391
memcpy(res, rv, len);
392+
}
393+
else {
394+
PyErr_NoMemory();
395+
}
365396
PyMem_RawFree(rv);
366397

367398
return res;

0 commit comments

Comments
 (0)