File tree Expand file tree Collapse file tree 1 file changed +19
-4
lines changed
Expand file tree Collapse file tree 1 file changed +19
-4
lines changed Original file line number Diff line number Diff line change 99
1010#include "Python.h"
1111#include "posixmodule.h"
12+ #include "listobject.h" // PyList_Size/PyList_GetItem
1213
1314#include <errno.h> // ERANGE
1415#include <pwd.h> // getpwuid()
@@ -306,23 +307,37 @@ pwd_getpwall_impl(PyObject *module)
306307 static PyMutex getpwall_mutex = {0 };
307308 PyMutex_Lock (& getpwall_mutex );
308309#endif
310+ int failure = 0 ;
311+ PyObject * orphan = NULL ;
309312 setpwent ();
310-
311313 while ((p = getpwent ()) != NULL ) {
314+ /* NOTE: Ref counts are not decremented here, as we cannot allow
315+ * re-entrancy while holding the mutex. */
312316 PyObject * v = mkpwent (module , p );
313317 if (v == NULL || PyList_Append (d , v ) != 0 ) {
314- Py_XDECREF ( v ) ;
315- Py_CLEAR ( d ) ;
318+ orphan = v ;
319+ failure = 1 ;
316320 goto done ;
317321 }
318- Py_DECREF (v );
319322 }
320323
321324done :
322325 endpwent ();
323326#ifdef Py_GIL_DISABLED
324327 PyMutex_Unlock (& getpwall_mutex );
325328#endif
329+ /* Deferred decref on entries created above and added to the list */
330+ Py_ssize_t n = PyList_Size (d );
331+ for (Py_ssize_t i = 0 ; i < n ; ++ i ) {
332+ PyObject * entry = PyList_GetItem (d , i );
333+ Py_DECREF (entry );
334+ }
335+ if (failure ) {
336+ /* If there was a failure we might have created an entry but not added
337+ * it: dec-ref that, if it exists, before clearing the list. */
338+ Py_XDECREF (orphan );
339+ Py_CLEAR (d );
340+ }
326341 return d ;
327342}
328343#endif
You can’t perform that action at this time.
0 commit comments