Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 37 additions & 15 deletions 52 Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -819,9 +819,19 @@ dir_fd_converter(PyObject *o, void *p)
}
}

#ifdef HAVE_PUTENV
# define PY_PUTENV_DICT
#endif

typedef struct {
PyObject *billion;
PyObject *posix_putenv_garbage;
#ifdef PY_PUTENV_DICT
/* putenv() and _wputenv() requires that the caller manages the environment
variable memory. Use a Python dictionary for that: name => env, where
env is a string like "name=value". On Windows, dict keys and values are
Unicode strings. On Unix, they are bytes strings. */
PyObject *putenv_dict;
#endif
PyObject *DirEntryType;
PyObject *ScandirIteratorType;
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Expand Down Expand Up @@ -2105,7 +2115,9 @@ static int
_posix_clear(PyObject *module)
{
Py_CLEAR(_posixstate(module)->billion);
Py_CLEAR(_posixstate(module)->posix_putenv_garbage);
#ifdef PY_PUTENV_DICT
Py_CLEAR(_posixstate(module)->putenv_dict);
#endif
Py_CLEAR(_posixstate(module)->DirEntryType);
Py_CLEAR(_posixstate(module)->ScandirIteratorType);
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Expand All @@ -2130,7 +2142,9 @@ static int
_posix_traverse(PyObject *module, visitproc visit, void *arg)
{
Py_VISIT(_posixstate(module)->billion);
Py_VISIT(_posixstate(module)->posix_putenv_garbage);
#ifdef PY_PUTENV_DICT
Py_VISIT(_posixstate(module)->putenv_dict);
#endif
Py_VISIT(_posixstate(module)->DirEntryType);
Py_VISIT(_posixstate(module)->ScandirIteratorType);
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Expand Down Expand Up @@ -10047,23 +10061,26 @@ os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
}
#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */

#ifdef HAVE_PUTENV

#ifdef PY_PUTENV_DICT
static void
posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
posix_putenv_dict_setitem(PyObject *name, PyObject *value)
{
/* Install the first arg and newstr in posix_putenv_garbage;
/* Install the first arg and newstr in putenv_dict;
* this will cause previous value to be collected. This has to
* happen after the real putenv() call because the old value
* was still accessible until then. */
if (PyDict_SetItem(_posixstate_global->posix_putenv_garbage, name, value))
if (PyDict_SetItem(_posixstate_global->putenv_dict, name, value))
/* really not much we can do; just leak */
PyErr_Clear();
else
Py_DECREF(value);
}
#endif /* PY_PUTENV_DICT */


#ifdef HAVE_PUTENV

#ifdef MS_WINDOWS
/*[clinic input]
os.putenv
Expand Down Expand Up @@ -10114,7 +10131,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
goto error;
}

posix_putenv_garbage_setitem(name, unicode);
posix_putenv_dict_setitem(name, unicode);
Py_RETURN_NONE;

error:
Expand Down Expand Up @@ -10156,7 +10173,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
return posix_error();
}

posix_putenv_garbage_setitem(name, bytes);
posix_putenv_dict_setitem(name, bytes);
Py_RETURN_NONE;
}
#endif /* MS_WINDOWS */
Expand Down Expand Up @@ -10189,18 +10206,20 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
return PyErr_SetFromWindowsErr(0);
}

/* Remove the key from posix_putenv_garbage;
#ifdef PY_PUTENV_DICT
/* Remove the key from putenv_dict;
* this will cause it to be collected. This has to
* happen after the real unsetenv() call because the
* old value was still accessible until then.
*/
if (PyDict_DelItem(_posixstate(module)->posix_putenv_garbage, name)) {
if (PyDict_DelItem(_posixstate(module)->putenv_dict, name)) {
/* really not much we can do; just leak */
if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
return NULL;
}
PyErr_Clear();
}
#endif

Py_RETURN_NONE;
}
Expand Down Expand Up @@ -10230,18 +10249,21 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
return posix_error();
#endif

/* Remove the key from posix_putenv_garbage;
#ifdef PY_PUTENV_DICT
/* Remove the key from putenv_dict;
* this will cause it to be collected. This has to
* happen after the real unsetenv() call because the
* old value was still accessible until then.
*/
if (PyDict_DelItem(_posixstate(module)->posix_putenv_garbage, name)) {
if (PyDict_DelItem(_posixstate(module)->putenv_dict, name)) {
/* really not much we can do; just leak */
if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
return NULL;
}
PyErr_Clear();
}
#endif

Py_RETURN_NONE;
}
#endif /* HAVE_UNSETENV */
Expand Down Expand Up @@ -14538,10 +14560,10 @@ INITFUNC(void)
Py_INCREF(PyExc_OSError);
PyModule_AddObject(m, "error", PyExc_OSError);

#ifdef HAVE_PUTENV
#ifdef PY_PUTENV_DICT
/* Save putenv() parameters as values here, so we can collect them when they
* get re-set with another call for the same key. */
_posixstate(m)->posix_putenv_garbage = PyDict_New();
_posixstate(m)->putenv_dict = PyDict_New();
#endif

#if defined(HAVE_WAITID) && !defined(__APPLE__)
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.