Skip to content

Commit 4c49da0

Browse files
ZackerySpytzserhiy-storchaka
authored andcommitted
bpo-35436: Add missing PyErr_NoMemory() calls and other minor bug fixes. (GH-11015)
Set MemoryError when appropriate, add missing failure checks, and fix some potential leaks.
1 parent 3a521f0 commit 4c49da0

File tree

17 files changed

+113
-27
lines changed

17 files changed

+113
-27
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/_abc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,10 @@ subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
728728
// Weakref callback may remove entry from set.
729729
// So we take snapshot of registry first.
730730
PyObject **copy = PyMem_Malloc(sizeof(PyObject*) * registry_size);
731+
if (copy == NULL) {
732+
PyErr_NoMemory();
733+
return -1;
734+
}
731735
PyObject *key;
732736
Py_ssize_t pos = 0;
733737
Py_hash_t hash;

Modules/_ctypes/_ctypes.c

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

307307
result = PyMem_Malloc(3);
308-
if (result == NULL)
308+
if (result == NULL) {
309+
PyErr_NoMemory();
309310
return NULL;
311+
}
310312

311313
result[0] = big_endian ? '>' : '<';
312314
result[1] = pep_code;
@@ -366,8 +368,10 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
366368
if (prefix)
367369
prefix_len += strlen(prefix);
368370
new_prefix = PyMem_Malloc(prefix_len);
369-
if (new_prefix == NULL)
371+
if (new_prefix == NULL) {
372+
PyErr_NoMemory();
370373
return NULL;
374+
}
371375
new_prefix[0] = '\0';
372376
if (prefix)
373377
strcpy(new_prefix, prefix);
@@ -1899,6 +1903,10 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
18991903
#else
19001904
suffix = PyUnicode_InternFromString("_be");
19011905
#endif
1906+
if (suffix == NULL) {
1907+
Py_DECREF(swapped_args);
1908+
return NULL;
1909+
}
19021910

19031911
newname = PyUnicode_Concat(name, suffix);
19041912
if (newname == NULL) {

Modules/_ctypes/callbacks.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
310310

311311
p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs);
312312
if (p == NULL) {
313-
PyErr_NoMemory();
314313
return NULL;
315314
}
316315

Modules/_io/winconsoleio.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -816,11 +816,13 @@ _io__WindowsConsoleIO_readall_impl(winconsoleio *self)
816816
}
817817
bufsize = newsize;
818818

819-
buf = PyMem_Realloc(buf, (bufsize + 1) * sizeof(wchar_t));
820-
if (!buf) {
819+
wchar_t *tmp = PyMem_Realloc(buf,
820+
(bufsize + 1) * sizeof(wchar_t));
821+
if (tmp == NULL) {
821822
PyMem_Free(buf);
822823
return NULL;
823824
}
825+
buf = tmp;
824826
}
825827

826828
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
@@ -449,8 +449,9 @@ semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
449449

450450
if (!unlink) {
451451
name_copy = PyMem_Malloc(strlen(name) + 1);
452-
if (name_copy == NULL)
453-
goto failure;
452+
if (name_copy == NULL) {
453+
return PyErr_NoMemory();
454+
}
454455
strcpy(name_copy, name);
455456
}
456457

@@ -473,7 +474,9 @@ semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
473474
if (handle != SEM_FAILED)
474475
SEM_CLOSE(handle);
475476
PyMem_Free(name_copy);
476-
_PyMp_SetError(NULL, MP_STANDARD_ERROR);
477+
if (!PyErr_Occurred()) {
478+
_PyMp_SetError(NULL, MP_STANDARD_ERROR);
479+
}
477480
return NULL;
478481
}
479482

Modules/_ssl.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,11 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
911911
PySSL_BEGIN_ALLOW_THREADS
912912
self->ssl = SSL_new(ctx);
913913
PySSL_END_ALLOW_THREADS
914+
if (self->ssl == NULL) {
915+
Py_DECREF(self);
916+
_setSSLError(NULL, 0, __FILE__, __LINE__);
917+
return NULL;
918+
}
914919
SSL_set_app_data(self->ssl, self);
915920
if (sock) {
916921
SSL_set_fd(self->ssl, Py_SAFE_DOWNCAST(sock->sock_fd, SOCKET_T, int));
@@ -1240,6 +1245,10 @@ _get_peer_alt_names (X509 *certificate) {
12401245

12411246
/* get a memory buffer */
12421247
biobuf = BIO_new(BIO_s_mem());
1248+
if (biobuf == NULL) {
1249+
PyErr_SetString(PySSLErrorObject, "failed to allocate BIO");
1250+
return NULL;
1251+
}
12431252

12441253
names = (GENERAL_NAMES *)X509_get_ext_d2i(
12451254
certificate, NID_subject_alt_name, NULL, NULL);
@@ -1592,6 +1601,10 @@ _decode_certificate(X509 *certificate) {
15921601

15931602
/* get a memory buffer */
15941603
biobuf = BIO_new(BIO_s_mem());
1604+
if (biobuf == NULL) {
1605+
PyErr_SetString(PySSLErrorObject, "failed to allocate BIO");
1606+
goto fail0;
1607+
}
15951608

15961609
(void) BIO_reset(biobuf);
15971610
serialNumber = X509_get_serialNumber(certificate);

Modules/mathmodule.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,7 +2142,7 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q)
21422142
if (n > NUM_STACK_ELEMS) {
21432143
diffs = (double *) PyObject_Malloc(n * sizeof(double));
21442144
if (diffs == NULL) {
2145-
return NULL;
2145+
return PyErr_NoMemory();
21462146
}
21472147
}
21482148
for (i=0 ; i<n ; i++) {
@@ -2199,8 +2199,9 @@ math_hypot(PyObject *self, PyObject *args)
21992199
n = PyTuple_GET_SIZE(args);
22002200
if (n > NUM_STACK_ELEMS) {
22012201
coordinates = (double *) PyObject_Malloc(n * sizeof(double));
2202-
if (coordinates == NULL)
2203-
return NULL;
2202+
if (coordinates == NULL) {
2203+
return PyErr_NoMemory();
2204+
}
22042205
}
22052206
for (i=0 ; i<n ; i++) {
22062207
item = PyTuple_GET_ITEM(args, i);

Modules/posixmodule.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6651,8 +6651,7 @@ os_getgroups_impl(PyObject *module)
66516651
} else {
66526652
alt_grouplist = PyMem_New(gid_t, n);
66536653
if (alt_grouplist == NULL) {
6654-
errno = EINVAL;
6655-
return posix_error();
6654+
return PyErr_NoMemory();
66566655
}
66576656
}
66586657

@@ -6677,8 +6676,7 @@ os_getgroups_impl(PyObject *module)
66776676
} else {
66786677
alt_grouplist = PyMem_New(gid_t, n);
66796678
if (alt_grouplist == NULL) {
6680-
errno = EINVAL;
6681-
return posix_error();
6679+
return PyErr_NoMemory();
66826680
}
66836681
n = getgroups(n, alt_grouplist);
66846682
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);

0 commit comments

Comments
 (0)