bpo-29849: fix a memory leak in import_from (GH-712)

This commit is contained in:
Xiang Zhang 2017-03-21 11:13:42 +08:00 committed by GitHub
parent 05f53735c8
commit 4830f581af
2 changed files with 19 additions and 10 deletions

View file

@ -10,6 +10,8 @@ What's New in Python 3.7.0 alpha 1?
Core and Builtins Core and Builtins
----------------- -----------------
- bpo-29849: Fix a memory leak when an ImportError is raised during from import.
- bpo-28856: Fix an oversight that %b format for bytes should support objects - bpo-28856: Fix an oversight that %b format for bytes should support objects
follow the buffer protocol. follow the buffer protocol.

View file

@ -5024,7 +5024,7 @@ import_from(PyObject *v, PyObject *name)
{ {
PyObject *x; PyObject *x;
_Py_IDENTIFIER(__name__); _Py_IDENTIFIER(__name__);
PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown; PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown, *errmsg;
x = PyObject_GetAttr(v, name); x = PyObject_GetAttr(v, name);
if (x != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError)) if (x != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError))
@ -5039,6 +5039,7 @@ import_from(PyObject *v, PyObject *name)
} }
fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name); fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name);
if (fullmodname == NULL) { if (fullmodname == NULL) {
Py_DECREF(pkgname);
return NULL; return NULL;
} }
x = PyDict_GetItem(PyImport_GetModuleDict(), fullmodname); x = PyDict_GetItem(PyImport_GetModuleDict(), fullmodname);
@ -5063,17 +5064,23 @@ import_from(PyObject *v, PyObject *name)
if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) { if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) {
PyErr_Clear(); PyErr_Clear();
PyErr_SetImportError( errmsg = PyUnicode_FromFormat(
PyUnicode_FromFormat("cannot import name %R from %R (unknown location)", "cannot import name %R from %R (unknown location)",
name, pkgname_or_unknown), name, pkgname_or_unknown
pkgname, NULL); );
} else { /* NULL check for errmsg done by PyErr_SetImportError. */
PyErr_SetImportError( PyErr_SetImportError(errmsg, pkgname, NULL);
PyUnicode_FromFormat("cannot import name %R from %R (%S)", }
name, pkgname_or_unknown, pkgpath), else {
pkgname, pkgpath); errmsg = PyUnicode_FromFormat(
"cannot import name %R from %R (%S)",
name, pkgname_or_unknown, pkgpath
);
/* NULL check for errmsg done by PyErr_SetImportError. */
PyErr_SetImportError(errmsg, pkgname, pkgpath);
} }
Py_XDECREF(errmsg);
Py_XDECREF(pkgname_or_unknown); Py_XDECREF(pkgname_or_unknown);
Py_XDECREF(pkgpath); Py_XDECREF(pkgpath);
return NULL; return NULL;