[Python-checkins] bpo-46606: os.getgroups() doesn't overallocate (GH-31569)
vstinner
webhook-mailer at python.org
Sat Feb 26 18:14:36 EST 2022
https://github.com/python/cpython/commit/e02c47528b31f513d5f5d6eb91b8c9714134cea2
commit: e02c47528b31f513d5f5d6eb91b8c9714134cea2
branch: main
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2022-02-27T00:14:28+01:00
summary:
bpo-46606: os.getgroups() doesn't overallocate (GH-31569)
files:
M Modules/posixmodule.c
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index d3cfc828184e5..3431c85e2dfde 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -7623,29 +7623,19 @@ static PyObject *
os_getgroups_impl(PyObject *module)
/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
{
- /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
- * This is a helper variable to store the intermediate result when
- * that happens.
- *
- * See bpo-7900.
- */
- gid_t *grouplist = NULL;
- int n;
-
- /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
- * there are more groups than can fit in grouplist. Therefore, on OS X
- * always first call getgroups with length 0 to get the actual number
- * of groups.
- */
- n = getgroups(0, NULL);
+ // Call getgroups with length 0 to get the actual number of groups
+ int n = getgroups(0, NULL);
if (n < 0) {
return posix_error();
- } else {
- n++; // Avoid malloc(0)
- grouplist = PyMem_New(gid_t, n+1);
- if (grouplist == NULL) {
- return PyErr_NoMemory();
- }
+ }
+
+ if (n == 0) {
+ return PyList_New(0);
+ }
+
+ gid_t *grouplist = PyMem_New(gid_t, n);
+ if (grouplist == NULL) {
+ return PyErr_NoMemory();
}
n = getgroups(n, grouplist);
@@ -7655,22 +7645,25 @@ os_getgroups_impl(PyObject *module)
}
PyObject *result = PyList_New(n);
- if (result != NULL) {
- int i;
- for (i = 0; i < n; ++i) {
- PyObject *o = _PyLong_FromGid(grouplist[i]);
- if (o == NULL) {
- Py_DECREF(result);
- result = NULL;
- break;
- }
- PyList_SET_ITEM(result, i, o);
- }
+ if (result == NULL) {
+ goto error;
}
+ for (int i = 0; i < n; ++i) {
+ PyObject *group = _PyLong_FromGid(grouplist[i]);
+ if (group == NULL) {
+ goto error;
+ }
+ PyList_SET_ITEM(result, i, group);
+ }
PyMem_Free(grouplist);
return result;
+
+error:
+ PyMem_Free(grouplist);
+ Py_XDECREF(result);
+ return NULL;
}
#endif /* HAVE_GETGROUPS */
More information about the Python-checkins
mailing list