bpo-40014: Fix os.getgrouplist() on macOS (GH-19118)
On macOS, getgrouplist() returns a non-zero value without setting
errno if the group list is too small. Double the list size and call
it again in this case.
(cherry picked from commit 8ec7370c89aa522602eb9604086ce9f09770953d)
Co-authored-by: Victor Stinner <vstinner@python.org>
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 2f791d1..be7ebb6 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -6914,10 +6914,29 @@
if (groups == NULL)
return PyErr_NoMemory();
+#ifdef __APPLE__
+ while (getgrouplist(user, basegid, groups, &ngroups)) {
+ /* On macOS, getgrouplist() returns a non-zero value without setting
+ errno if the group list is too small. Double the list size and call
+ it again in this case. */
+ PyMem_Free(groups);
+
+ if (ngroups > INT_MAX / 2) {
+ return PyErr_NoMemory();
+ }
+ ngroups *= 2;
+
+ groups = PyMem_New(int, ngroups);
+ if (groups == NULL) {
+ return PyErr_NoMemory();
+ }
+ }
+#else
if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
PyMem_Del(groups);
return posix_error();
}
+#endif
#ifdef _Py_MEMORY_SANITIZER
/* Clang memory sanitizer libc intercepts don't know getgrouplist. */