[Python-checkins] bpo-31286, bpo-30024: Fixed stack usage in absolute imports with (#3217)
Serhiy Storchaka
webhook-mailer at python.org
Tue Aug 29 08:47:47 EDT 2017
https://github.com/python/cpython/commit/265fcc5fc25d65afb33fda480c603f1e974e374e
commit: 265fcc5fc25d65afb33fda480c603f1e974e374e
branch: master
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2017-08-29T15:47:44+03:00
summary:
bpo-31286, bpo-30024: Fixed stack usage in absolute imports with (#3217)
binding a submodule to a name.
files:
M Lib/test/test_import/__init__.py
M Python/compile.c
diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index 1b04de24dd1..ddef27d9cd4 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -237,6 +237,23 @@ def test_import_name_binding(self):
import test.support as y
self.assertIs(y, test.support, y.__name__)
+ def test_issue31286(self):
+ # import in a 'finally' block resulted in SystemError
+ try:
+ x = ...
+ finally:
+ import test.support.script_helper as x
+
+ # import in a 'while' loop resulted in stack overflow
+ i = 0
+ while i < 10:
+ import test.support.script_helper as x
+ i += 1
+
+ # import in a 'for' loop resulted in segmentation fault
+ for i in range(2):
+ import test.support.script_helper as x
+
def test_failing_reload(self):
# A failing reload should leave the module object in sys.modules.
source = TESTFN + os.extsep + "py"
diff --git a/Python/compile.c b/Python/compile.c
index 78e797a2c33..e547c2fd591 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -2673,28 +2673,34 @@ compiler_import_as(struct compiler *c, identifier name, identifier asname)
If there is a dot in name, we need to split it and emit a
IMPORT_FROM for each name.
*/
- Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0,
- PyUnicode_GET_LENGTH(name), 1);
+ Py_ssize_t len = PyUnicode_GET_LENGTH(name);
+ Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1);
if (dot == -2)
return 0;
if (dot != -1) {
/* Consume the base module name to get the first attribute */
- Py_ssize_t pos = dot + 1;
- while (dot != -1) {
+ while (1) {
+ Py_ssize_t pos = dot + 1;
PyObject *attr;
- dot = PyUnicode_FindChar(name, '.', pos,
- PyUnicode_GET_LENGTH(name), 1);
+ dot = PyUnicode_FindChar(name, '.', pos, len, 1);
if (dot == -2)
return 0;
- attr = PyUnicode_Substring(name, pos,
- (dot != -1) ? dot :
- PyUnicode_GET_LENGTH(name));
+ attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len);
if (!attr)
return 0;
ADDOP_O(c, IMPORT_FROM, attr, names);
Py_DECREF(attr);
- pos = dot + 1;
+ if (dot == -1) {
+ break;
+ }
+ ADDOP(c, ROT_TWO);
+ ADDOP(c, POP_TOP);
}
+ if (!compiler_nameop(c, asname, Store)) {
+ return 0;
+ }
+ ADDOP(c, POP_TOP);
+ return 1;
}
return compiler_nameop(c, asname, Store);
}
More information about the Python-checkins
mailing list