bpo-22689: Copy the result of getenv() in sys_breakpointhook(). (GH-8194)

This commit is contained in:
Serhiy Storchaka 2018-07-09 21:46:51 +03:00 committed by GitHub
parent b796e7dcdc
commit f60bf0e168
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 14 additions and 1 deletions

View File

@ -107,7 +107,7 @@ static PyObject *
sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
{ {
assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
const char *envar = Py_GETENV("PYTHONBREAKPOINT"); char *envar = Py_GETENV("PYTHONBREAKPOINT");
if (envar == NULL || strlen(envar) == 0) { if (envar == NULL || strlen(envar) == 0) {
envar = "pdb.set_trace"; envar = "pdb.set_trace";
@ -116,6 +116,15 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
/* The breakpoint is explicitly no-op'd. */ /* The breakpoint is explicitly no-op'd. */
Py_RETURN_NONE; Py_RETURN_NONE;
} }
/* According to POSIX the string returned by getenv() might be invalidated
* or the string content might be overwritten by a subsequent call to
* getenv(). Since importing a module can performs the getenv() calls,
* we need to save a copy of envar. */
envar = _PyMem_RawStrdup(envar);
if (envar == NULL) {
PyErr_NoMemory();
return NULL;
}
const char *last_dot = strrchr(envar, '.'); const char *last_dot = strrchr(envar, '.');
const char *attrname = NULL; const char *attrname = NULL;
PyObject *modulepath = NULL; PyObject *modulepath = NULL;
@ -131,12 +140,14 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
attrname = last_dot + 1; attrname = last_dot + 1;
} }
if (modulepath == NULL) { if (modulepath == NULL) {
PyMem_RawFree(envar);
return NULL; return NULL;
} }
PyObject *fromlist = Py_BuildValue("(s)", attrname); PyObject *fromlist = Py_BuildValue("(s)", attrname);
if (fromlist == NULL) { if (fromlist == NULL) {
Py_DECREF(modulepath); Py_DECREF(modulepath);
PyMem_RawFree(envar);
return NULL; return NULL;
} }
PyObject *module = PyImport_ImportModuleLevelObject( PyObject *module = PyImport_ImportModuleLevelObject(
@ -154,6 +165,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
if (hook == NULL) { if (hook == NULL) {
goto error; goto error;
} }
PyMem_RawFree(envar);
PyObject *retval = _PyObject_FastCallKeywords(hook, args, nargs, keywords); PyObject *retval = _PyObject_FastCallKeywords(hook, args, nargs, keywords);
Py_DECREF(hook); Py_DECREF(hook);
return retval; return retval;
@ -164,6 +176,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
int status = PyErr_WarnFormat( int status = PyErr_WarnFormat(
PyExc_RuntimeWarning, 0, PyExc_RuntimeWarning, 0,
"Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar); "Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar);
PyMem_RawFree(envar);
if (status < 0) { if (status < 0) {
/* Printing the warning raised an exception. */ /* Printing the warning raised an exception. */
return NULL; return NULL;