Skip to content

Commit f60bf0e

Browse files
bpo-22689: Copy the result of getenv() in sys_breakpointhook(). (GH-8194)
1 parent b796e7d commit f60bf0e

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

Python/sysmodule.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ static PyObject *
107107
sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
108108
{
109109
assert(!PyErr_Occurred());
110-
const char *envar = Py_GETENV("PYTHONBREAKPOINT");
110+
char *envar = Py_GETENV("PYTHONBREAKPOINT");
111111

112112
if (envar == NULL || strlen(envar) == 0) {
113113
envar = "pdb.set_trace";
@@ -116,6 +116,15 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
116116
/* The breakpoint is explicitly no-op'd. */
117117
Py_RETURN_NONE;
118118
}
119+
/* According to POSIX the string returned by getenv() might be invalidated
120+
* or the string content might be overwritten by a subsequent call to
121+
* getenv(). Since importing a module can performs the getenv() calls,
122+
* we need to save a copy of envar. */
123+
envar = _PyMem_RawStrdup(envar);
124+
if (envar == NULL) {
125+
PyErr_NoMemory();
126+
return NULL;
127+
}
119128
const char *last_dot = strrchr(envar, '.');
120129
const char *attrname = NULL;
121130
PyObject *modulepath = NULL;
@@ -131,12 +140,14 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
131140
attrname = last_dot + 1;
132141
}
133142
if (modulepath == NULL) {
143+
PyMem_RawFree(envar);
134144
return NULL;
135145
}
136146

137147
PyObject *fromlist = Py_BuildValue("(s)", attrname);
138148
if (fromlist == NULL) {
139149
Py_DECREF(modulepath);
150+
PyMem_RawFree(envar);
140151
return NULL;
141152
}
142153
PyObject *module = PyImport_ImportModuleLevelObject(
@@ -154,6 +165,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
154165
if (hook == NULL) {
155166
goto error;
156167
}
168+
PyMem_RawFree(envar);
157169
PyObject *retval = _PyObject_FastCallKeywords(hook, args, nargs, keywords);
158170
Py_DECREF(hook);
159171
return retval;
@@ -164,6 +176,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
164176
int status = PyErr_WarnFormat(
165177
PyExc_RuntimeWarning, 0,
166178
"Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar);
179+
PyMem_RawFree(envar);
167180
if (status < 0) {
168181
/* Printing the warning raised an exception. */
169182
return NULL;

0 commit comments

Comments
 (0)