From: Serhiy Storchaka Date: Sun, 1 Apr 2018 07:26:33 +0000 (+0300) Subject: [2.7] bpo-33132: Fix reference counting issues in the compiler. (GH-6209). (GH-6322) X-Git-Tag: v2.7.15rc1~9 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=72f3e0887500e00867fa16ce5aaab12fae853b63;p=python [2.7] bpo-33132: Fix reference counting issues in the compiler. (GH-6209). (GH-6322) (cherry picked from commit a95d98607efe0c43475b354543e49bf8e240bc6f) Co-authored-by: Serhiy Storchaka --- diff --git a/Python/compile.c b/Python/compile.c index 9c9b236985..4fe69e12bf 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1075,6 +1075,15 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) return 0; \ } +/* Same as ADDOP_O, but steals a reference. */ +#define ADDOP_N(C, OP, O, TYPE) { \ + if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \ + Py_DECREF((O)); \ + return 0; \ + } \ + Py_DECREF((O)); \ +} + #define ADDOP_NAME(C, OP, O, TYPE) { \ if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \ return 0; \ @@ -1890,8 +1899,7 @@ compiler_import_as(struct compiler *c, identifier name, identifier asname) dot ? dot - src : strlen(src)); if (!attr) return 0; - ADDOP_O(c, LOAD_ATTR, attr, names); - Py_DECREF(attr); + ADDOP_N(c, LOAD_ATTR, attr, names); src = dot + 1; } } @@ -1923,8 +1931,7 @@ compiler_import(struct compiler *c, stmt_ty s) if (level == NULL) return 0; - ADDOP_O(c, LOAD_CONST, level, consts); - Py_DECREF(level); + ADDOP_N(c, LOAD_CONST, level, consts); ADDOP_O(c, LOAD_CONST, Py_None, consts); ADDOP_NAME(c, IMPORT_NAME, alias->name, names); @@ -1959,8 +1966,7 @@ compiler_from_import(struct compiler *c, stmt_ty s) { int i, n = asdl_seq_LEN(s->v.ImportFrom.names); - PyObject *names = PyTuple_New(n); - PyObject *level; + PyObject *level, *names; static PyObject *empty_string; if (!empty_string) { @@ -1969,9 +1975,6 @@ compiler_from_import(struct compiler *c, stmt_ty s) return 0; } - if (!names) - return 0; - if (s->v.ImportFrom.level == 0 && c->c_flags && !(c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT)) level = PyInt_FromLong(-1); @@ -1979,9 +1982,13 @@ compiler_from_import(struct compiler *c, stmt_ty s) level = PyInt_FromLong(s->v.ImportFrom.level); if (!level) { - Py_DECREF(names); return 0; } + ADDOP_N(c, LOAD_CONST, level, consts); + + names = PyTuple_New(n); + if (!names) + return 0; /* build up the names */ for (i = 0; i < n; i++) { @@ -1992,16 +1999,12 @@ compiler_from_import(struct compiler *c, stmt_ty s) if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module && !strcmp(PyString_AS_STRING(s->v.ImportFrom.module), "__future__")) { - Py_DECREF(level); Py_DECREF(names); return compiler_error(c, "from __future__ imports must occur " "at the beginning of the file"); } + ADDOP_N(c, LOAD_CONST, names, consts); - ADDOP_O(c, LOAD_CONST, level, consts); - Py_DECREF(level); - ADDOP_O(c, LOAD_CONST, names, consts); - Py_DECREF(names); if (s->v.ImportFrom.module) { ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); } @@ -2024,7 +2027,6 @@ compiler_from_import(struct compiler *c, stmt_ty s) store_name = alias->asname; if (!compiler_nameop(c, store_name, Store)) { - Py_DECREF(names); return 0; } } @@ -2391,8 +2393,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) "param invalid for local variable"); return 0; } - ADDOP_O(c, op, mangled, varnames); - Py_DECREF(mangled); + ADDOP_N(c, op, mangled, varnames); return 1; case OP_GLOBAL: switch (ctx) {