mirror of
https://github.com/python/cpython.git
synced 2025-11-17 01:25:57 +00:00
posix_putenv(): Constrain memory leakage when setting the same
environment variable repeatedly. I posted this to the list
some time ago, but only now got around to asking g--d- what he
thought about it.
This commit is contained in:
parent
e7f19200e8
commit
762e206706
1 changed files with 24 additions and 3 deletions
|
|
@ -2787,6 +2787,10 @@ Change or add an environment variable.";
|
||||||
int putenv( const char *str );
|
int putenv( const char *str );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Save putenv() parameters as values here, so we can collect them when they
|
||||||
|
* get re-set with another call for the same key. */
|
||||||
|
static PyObject *posix_putenv_garbage;
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_putenv(self, args)
|
posix_putenv(self, args)
|
||||||
PyObject *self;
|
PyObject *self;
|
||||||
|
|
@ -2794,6 +2798,7 @@ posix_putenv(self, args)
|
||||||
{
|
{
|
||||||
char *s1, *s2;
|
char *s1, *s2;
|
||||||
char *new;
|
char *new;
|
||||||
|
PyObject *newstr;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ss", &s1, &s2))
|
if (!PyArg_ParseTuple(args, "ss", &s1, &s2))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -2821,14 +2826,28 @@ posix_putenv(self, args)
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* XXX This leaks memory -- not easy to fix :-( */
|
/* XXX This can leak memory -- not easy to fix :-( */
|
||||||
if ((new = malloc(strlen(s1) + strlen(s2) + 2)) == NULL)
|
newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
|
||||||
return PyErr_NoMemory();
|
if (newstr == NULL)
|
||||||
|
return PyErr_NoMemory();
|
||||||
|
new = PyString_AS_STRING(newstr);
|
||||||
(void) sprintf(new, "%s=%s", s1, s2);
|
(void) sprintf(new, "%s=%s", s1, s2);
|
||||||
if (putenv(new)) {
|
if (putenv(new)) {
|
||||||
posix_error();
|
posix_error();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/* Install the first arg and newstr in posix_putenv_garbage;
|
||||||
|
* 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(posix_putenv_garbage,
|
||||||
|
PyTuple_GET_ITEM(args, 0), newstr)) {
|
||||||
|
/* really not much we can do; just leak */
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Py_DECREF(newstr);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(PYOS_OS2)
|
#if defined(PYOS_OS2)
|
||||||
}
|
}
|
||||||
|
|
@ -3500,4 +3519,6 @@ INITFUNC()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PyDict_SetItemString(d, "error", PyExc_OSError);
|
PyDict_SetItemString(d, "error", PyExc_OSError);
|
||||||
|
|
||||||
|
posix_putenv_garbage = PyDict_New();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue