summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiang Zhang <angwerzx@126.com>2017-03-21 03:13:42 (GMT)
committerGitHub <noreply@github.com>2017-03-21 03:13:42 (GMT)
commit4830f581af57dd305c02c1fd72299ecb5b090eca (patch)
treef2a13400bc9de4e5e24293ad5e388dca4eef959c
parent05f53735c8912f8df1077e897f052571e13c3496 (diff)
downloadcpython-4830f581af57dd305c02c1fd72299ecb5b090eca.zip
cpython-4830f581af57dd305c02c1fd72299ecb5b090eca.tar.gz
cpython-4830f581af57dd305c02c1fd72299ecb5b090eca.tar.bz2
bpo-29849: fix a memory leak in import_from (GH-712)
-rw-r--r--Misc/NEWS2
-rw-r--r--Python/ceval.c27
2 files changed, 19 insertions, 10 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index d8ea4c9..b86e5c9 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ What's New in Python 3.7.0 alpha 1?
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
follow the buffer protocol.
diff --git a/Python/ceval.c b/Python/ceval.c
index 8ee58f5..fd60b73 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -5024,7 +5024,7 @@ import_from(PyObject *v, PyObject *name)
{
PyObject *x;
_Py_IDENTIFIER(__name__);
- PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown;
+ PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown, *errmsg;
x = PyObject_GetAttr(v, name);
if (x != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError))
@@ -5039,6 +5039,7 @@ import_from(PyObject *v, PyObject *name)
}
fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name);
if (fullmodname == NULL) {
+ Py_DECREF(pkgname);
return NULL;
}
x = PyDict_GetItem(PyImport_GetModuleDict(), fullmodname);
@@ -5063,17 +5064,23 @@ import_from(PyObject *v, PyObject *name)
if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) {
PyErr_Clear();
- PyErr_SetImportError(
- PyUnicode_FromFormat("cannot import name %R from %R (unknown location)",
- name, pkgname_or_unknown),
- pkgname, NULL);
- } else {
- PyErr_SetImportError(
- PyUnicode_FromFormat("cannot import name %R from %R (%S)",
- name, pkgname_or_unknown, pkgpath),
- pkgname, pkgpath);
+ errmsg = PyUnicode_FromFormat(
+ "cannot import name %R from %R (unknown location)",
+ name, pkgname_or_unknown
+ );
+ /* NULL check for errmsg done by PyErr_SetImportError. */
+ PyErr_SetImportError(errmsg, pkgname, NULL);
+ }
+ else {
+ 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(pkgpath);
return NULL;