@@ -7623,21 +7623,15 @@ static PyObject *
7623
7623
os_getgroups_impl (PyObject * module )
7624
7624
/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
7625
7625
{
7626
- PyObject * result = NULL ;
7627
- gid_t grouplist [MAX_GROUPS ];
7628
-
7629
7626
/* On MacOSX getgroups(2) can return more than MAX_GROUPS results
7630
7627
* This is a helper variable to store the intermediate result when
7631
7628
* that happens.
7632
7629
*
7633
- * To keep the code readable the OSX behaviour is unconditional,
7634
- * according to the POSIX spec this should be safe on all unix-y
7635
- * systems.
7630
+ * See bpo-7900.
7636
7631
*/
7637
- gid_t * alt_grouplist = grouplist ;
7632
+ gid_t * grouplist = NULL ;
7638
7633
int n ;
7639
7634
7640
- #ifdef __APPLE__
7641
7635
/* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7642
7636
* there are more groups than can fit in grouplist. Therefore, on OS X
7643
7637
* always first call getgroups with length 0 to get the actual number
@@ -7646,56 +7640,25 @@ os_getgroups_impl(PyObject *module)
7646
7640
n = getgroups (0 , NULL );
7647
7641
if (n < 0 ) {
7648
7642
return posix_error ();
7649
- } else if (n <= MAX_GROUPS ) {
7650
- /* groups will fit in existing array */
7651
- alt_grouplist = grouplist ;
7652
7643
} else {
7653
- alt_grouplist = PyMem_New (gid_t , n );
7654
- if (alt_grouplist == NULL ) {
7644
+ n ++ ; // Avoid malloc(0)
7645
+ grouplist = PyMem_New (gid_t , n + 1 );
7646
+ if (grouplist == NULL ) {
7655
7647
return PyErr_NoMemory ();
7656
7648
}
7657
7649
}
7658
7650
7659
- n = getgroups (n , alt_grouplist );
7651
+ n = getgroups (n , grouplist );
7660
7652
if (n == -1 ) {
7661
- if (alt_grouplist != grouplist ) {
7662
- PyMem_Free (alt_grouplist );
7663
- }
7653
+ PyMem_Free (grouplist );
7664
7654
return posix_error ();
7665
7655
}
7666
- #else
7667
- n = getgroups (MAX_GROUPS , grouplist );
7668
- if (n < 0 ) {
7669
- if (errno == EINVAL ) {
7670
- n = getgroups (0 , NULL );
7671
- if (n == -1 ) {
7672
- return posix_error ();
7673
- }
7674
- if (n == 0 ) {
7675
- /* Avoid malloc(0) */
7676
- alt_grouplist = grouplist ;
7677
- } else {
7678
- alt_grouplist = PyMem_New (gid_t , n );
7679
- if (alt_grouplist == NULL ) {
7680
- return PyErr_NoMemory ();
7681
- }
7682
- n = getgroups (n , alt_grouplist );
7683
- if (n == -1 ) {
7684
- PyMem_Free (alt_grouplist );
7685
- return posix_error ();
7686
- }
7687
- }
7688
- } else {
7689
- return posix_error ();
7690
- }
7691
- }
7692
- #endif
7693
7656
7694
- result = PyList_New (n );
7657
+ PyObject * result = PyList_New (n );
7695
7658
if (result != NULL ) {
7696
7659
int i ;
7697
7660
for (i = 0 ; i < n ; ++ i ) {
7698
- PyObject * o = _PyLong_FromGid (alt_grouplist [i ]);
7661
+ PyObject * o = _PyLong_FromGid (grouplist [i ]);
7699
7662
if (o == NULL ) {
7700
7663
Py_DECREF (result );
7701
7664
result = NULL ;
@@ -7705,9 +7668,7 @@ os_getgroups_impl(PyObject *module)
7705
7668
}
7706
7669
}
7707
7670
7708
- if (alt_grouplist != grouplist ) {
7709
- PyMem_Free (alt_grouplist );
7710
- }
7671
+ PyMem_Free (grouplist );
7711
7672
7712
7673
return result ;
7713
7674
}
@@ -8212,42 +8173,48 @@ static PyObject *
8212
8173
os_setgroups (PyObject * module , PyObject * groups )
8213
8174
/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
8214
8175
{
8215
- Py_ssize_t i , len ;
8216
- gid_t grouplist [MAX_GROUPS ];
8217
-
8218
8176
if (!PySequence_Check (groups )) {
8219
8177
PyErr_SetString (PyExc_TypeError , "setgroups argument must be a sequence" );
8220
8178
return NULL ;
8221
8179
}
8222
- len = PySequence_Size (groups );
8180
+ Py_ssize_t len = PySequence_Size (groups );
8223
8181
if (len < 0 ) {
8224
8182
return NULL ;
8225
8183
}
8226
8184
if (len > MAX_GROUPS ) {
8227
8185
PyErr_SetString (PyExc_ValueError , "too many groups" );
8228
8186
return NULL ;
8229
8187
}
8230
- for (i = 0 ; i < len ; i ++ ) {
8188
+
8189
+ gid_t * grouplist = PyMem_New (gid_t , len + 1 ); // Avoid malloc(0)
8190
+ for (Py_ssize_t i = 0 ; i < len ; i ++ ) {
8231
8191
PyObject * elem ;
8232
8192
elem = PySequence_GetItem (groups , i );
8233
- if (!elem )
8193
+ if (!elem ) {
8194
+ PyMem_Free (grouplist );
8234
8195
return NULL ;
8196
+ }
8235
8197
if (!PyLong_Check (elem )) {
8236
8198
PyErr_SetString (PyExc_TypeError ,
8237
8199
"groups must be integers" );
8238
8200
Py_DECREF (elem );
8201
+ PyMem_Free (grouplist );
8239
8202
return NULL ;
8240
8203
} else {
8241
8204
if (!_Py_Gid_Converter (elem , & grouplist [i ])) {
8242
8205
Py_DECREF (elem );
8206
+ PyMem_Free (grouplist );
8243
8207
return NULL ;
8244
8208
}
8245
8209
}
8246
8210
Py_DECREF (elem );
8247
8211
}
8248
8212
8249
- if (setgroups (len , grouplist ) < 0 )
8213
+ if (setgroups (len , grouplist ) < 0 ) {
8214
+ PyMem_Free (grouplist );
8250
8215
return posix_error ();
8216
+ }
8217
+ PyMem_Free (grouplist );
8251
8218
Py_RETURN_NONE ;
8252
8219
}
8253
8220
#endif /* HAVE_SETGROUPS */
0 commit comments