@@ -107,7 +107,7 @@ static PyObject *
107107sys_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