Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b6fc9df

Browse files
committed
Fix a lot of memory and ref leaks in error paths.
(Call symtable_exit_block or compiler_exit_scope as appropriate) Use PyMem_Free on c_future since it was allocated with PyMem_Malloc
1 parent 6576bd8 commit b6fc9df

2 files changed

Lines changed: 110 additions & 42 deletions

File tree

Python/compile.c

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ compiler_free(struct compiler *c)
302302
if (c->c_st)
303303
PySymtable_Free(c->c_st);
304304
if (c->c_future)
305-
PyObject_Free((void *)c->c_future);
305+
PyMem_Free(c->c_future);
306306
Py_DECREF(c->c_stack);
307307
}
308308

@@ -1607,6 +1607,13 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
16071607
return 0; \
16081608
}
16091609

1610+
#define ADDOP_IN_SCOPE(C, OP) { \
1611+
if (!compiler_addop((C), (OP))) { \
1612+
compiler_exit_scope(c); \
1613+
return 0; \
1614+
} \
1615+
}
1616+
16101617
#define ADDOP_O(C, OP, O, TYPE) { \
16111618
if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \
16121619
return 0; \
@@ -1641,6 +1648,13 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
16411648
return 0; \
16421649
}
16431650

1651+
#define VISIT_IN_SCOPE(C, TYPE, V) {\
1652+
if (!compiler_visit_ ## TYPE((C), (V))) { \
1653+
compiler_exit_scope(c); \
1654+
return 0; \
1655+
} \
1656+
}
1657+
16441658
#define VISIT_SLICE(C, V, CTX) {\
16451659
if (!compiler_visit_slice((C), (V), (CTX))) \
16461660
return 0; \
@@ -1656,6 +1670,18 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
16561670
} \
16571671
}
16581672

1673+
#define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \
1674+
int i; \
1675+
asdl_seq *seq = (SEQ); /* avoid variable capture */ \
1676+
for (i = 0; i < asdl_seq_LEN(seq); i++) { \
1677+
TYPE ## _ty elt = asdl_seq_GET(seq, i); \
1678+
if (!compiler_visit_ ## TYPE((C), elt)) { \
1679+
compiler_exit_scope(c); \
1680+
return 0; \
1681+
} \
1682+
} \
1683+
}
1684+
16591685
static int
16601686
compiler_isdocstring(stmt_ty s)
16611687
{
@@ -1708,15 +1734,15 @@ compiler_mod(struct compiler *c, mod_ty mod)
17081734
break;
17091735
case Interactive_kind:
17101736
c->c_interactive = 1;
1711-
VISIT_SEQ(c, stmt, mod->v.Interactive.body);
1737+
VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body);
17121738
break;
17131739
case Expression_kind:
1714-
VISIT(c, expr, mod->v.Expression.body);
1740+
VISIT_IN_SCOPE(c, expr, mod->v.Expression.body);
17151741
addNone = 0;
17161742
break;
17171743
case Suite_kind:
17181744
assert(0); /* XXX: what should we do here? */
1719-
VISIT_SEQ(c, stmt, mod->v.Suite.body);
1745+
VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Suite.body);
17201746
break;
17211747
default:
17221748
assert(0);
@@ -1890,7 +1916,7 @@ compiler_function(struct compiler *c, stmt_ty s)
18901916
if (i == 0 && s2->kind == Expr_kind &&
18911917
s2->v.Expr.value->kind == Str_kind)
18921918
continue;
1893-
VISIT(c, stmt, s2);
1919+
VISIT_IN_SCOPE(c, stmt, s2);
18941920
}
18951921
co = assemble(c, 1);
18961922
compiler_exit_scope(c);
@@ -1945,8 +1971,8 @@ compiler_class(struct compiler *c, stmt_ty s)
19451971
return 0;
19461972
}
19471973

1948-
ADDOP(c, LOAD_LOCALS);
1949-
ADDOP(c, RETURN_VALUE);
1974+
ADDOP_IN_SCOPE(c, LOAD_LOCALS);
1975+
ADDOP_IN_SCOPE(c, RETURN_VALUE);
19501976
co = assemble(c, 1);
19511977
compiler_exit_scope(c);
19521978
if (co == NULL)
@@ -1981,8 +2007,8 @@ compiler_lambda(struct compiler *c, expr_ty e)
19812007
compiler_arguments(c, args);
19822008

19832009
c->u->u_argcount = asdl_seq_LEN(args->args);
1984-
VISIT(c, expr, e->v.Lambda.body);
1985-
ADDOP(c, RETURN_VALUE);
2010+
VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
2011+
ADDOP_IN_SCOPE(c, RETURN_VALUE);
19862012
co = assemble(c, 1);
19872013
compiler_exit_scope(c);
19882014
if (co == NULL)

Python/symtable.c

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ PySTEntry_New(struct symtable *st, identifier name, _Py_block_ty block,
1616
void *key, int lineno)
1717
{
1818
PySTEntryObject *ste = NULL;
19-
PyObject *k, *v;
19+
PyObject *k;
2020

2121
k = PyLong_FromVoidPtr(key);
2222
if (k == NULL)
@@ -29,21 +29,22 @@ PySTEntry_New(struct symtable *st, identifier name, _Py_block_ty block,
2929

3030
ste->ste_name = name;
3131
Py_INCREF(name);
32-
33-
v = PyDict_New();
34-
if (v == NULL)
32+
33+
ste->ste_symbols = NULL;
34+
ste->ste_varnames = NULL;
35+
ste->ste_children = NULL;
36+
37+
ste->ste_symbols = PyDict_New();
38+
if (ste->ste_symbols == NULL)
3539
goto fail;
36-
ste->ste_symbols = v;
3740

38-
v = PyList_New(0);
39-
if (v == NULL)
41+
ste->ste_varnames = PyList_New(0);
42+
if (ste->ste_varnames == NULL)
4043
goto fail;
41-
ste->ste_varnames = v;
4244

43-
v = PyList_New(0);
44-
if (v == NULL)
45+
ste->ste_children = PyList_New(0);
46+
if (ste->ste_children == NULL)
4547
goto fail;
46-
ste->ste_children = v;
4748

4849
ste->ste_type = block;
4950
ste->ste_unoptimized = 0;
@@ -187,6 +188,8 @@ symtable_new(void)
187188
return NULL;
188189

189190
st->st_filename = NULL;
191+
st->st_symbols = NULL;
192+
190193
if ((st->st_stack = PyList_New(0)) == NULL)
191194
goto fail;
192195
if ((st->st_symbols = PyDict_New()) == NULL)
@@ -236,13 +239,18 @@ PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
236239
case Suite_kind:
237240
PyErr_SetString(PyExc_RuntimeError,
238241
"this compiler does not handle Suites");
239-
return NULL;
242+
goto error;
240243
}
241-
if (!symtable_exit_block(st, (void *)mod))
244+
if (!symtable_exit_block(st, (void *)mod)) {
245+
PySymtable_Free(st);
242246
return NULL;
247+
}
243248
if (symtable_analyze(st))
244249
return st;
250+
PySymtable_Free(st);
251+
return NULL;
245252
error:
253+
(void) symtable_exit_block(st, (void *)mod);
246254
PySymtable_Free(st);
247255
return NULL;
248256
}
@@ -266,15 +274,15 @@ PySymtable_Lookup(struct symtable *st, void *key)
266274
v = PyDict_GetItem(st->st_symbols, k);
267275
if (v) {
268276
assert(PySTEntry_Check(v));
269-
Py_DECREF(k);
270277
Py_INCREF(v);
271-
return (PySTEntryObject *)v;
272278
}
273279
else {
274280
PyErr_SetString(PyExc_KeyError,
275281
"unknown symbol table entry");
276-
return NULL;
277282
}
283+
284+
Py_DECREF(k);
285+
return (PySTEntryObject *)v;
278286
}
279287

280288
int
@@ -329,8 +337,11 @@ PyST_GetScope(PySTEntryObject *ste, PyObject *name)
329337
PyObject *o = PyInt_FromLong(I); \
330338
if (!o) \
331339
return 0; \
332-
if (PyDict_SetItem((DICT), (NAME), o) < 0) \
340+
if (PyDict_SetItem((DICT), (NAME), o) < 0) { \
341+
Py_DECREF(o); \
333342
return 0; \
343+
} \
344+
Py_DECREF(o); \
334345
}
335346

336347
/* Decide on scope of name, given flags.
@@ -536,6 +547,7 @@ update_symbols(PyObject *symbols, PyObject *scope,
536547
Py_DECREF(free_value);
537548
return 0;
538549
}
550+
Py_DECREF(o);
539551
}
540552
/* else it's not free, probably a cell */
541553
continue;
@@ -663,7 +675,7 @@ symtable_analyze(struct symtable *st)
663675
return 0;
664676
global = PyDict_New();
665677
if (!global) {
666-
Py_DECREF(global);
678+
Py_DECREF(free);
667679
return 0;
668680
}
669681
r = analyze_block(st->st_top, NULL, free, global);
@@ -820,7 +832,13 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag)
820832
#define VISIT(ST, TYPE, V) \
821833
if (!symtable_visit_ ## TYPE((ST), (V))) \
822834
return 0;
823-
835+
836+
#define VISIT_IN_BLOCK(ST, TYPE, V, S) \
837+
if (!symtable_visit_ ## TYPE((ST), (V))) { \
838+
symtable_exit_block((ST), (S)); \
839+
return 0; \
840+
}
841+
824842
#define VISIT_SEQ(ST, TYPE, SEQ) { \
825843
int i; \
826844
asdl_seq *seq = (SEQ); /* avoid variable capture */ \
@@ -830,7 +848,19 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag)
830848
return 0; \
831849
} \
832850
}
833-
851+
852+
#define VISIT_SEQ_IN_BLOCK(ST, TYPE, SEQ, S) { \
853+
int i; \
854+
asdl_seq *seq = (SEQ); /* avoid variable capture */ \
855+
for (i = 0; i < asdl_seq_LEN(seq); i++) { \
856+
TYPE ## _ty elt = asdl_seq_GET(seq, i); \
857+
if (!symtable_visit_ ## TYPE((ST), elt)) { \
858+
symtable_exit_block((ST), (S)); \
859+
return 0; \
860+
} \
861+
} \
862+
}
863+
834864
#define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \
835865
int i; \
836866
asdl_seq *seq = (SEQ); /* avoid variable capture */ \
@@ -840,7 +870,19 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag)
840870
return 0; \
841871
} \
842872
}
843-
873+
874+
#define VISIT_SEQ_TAIL_IN_BLOCK(ST, TYPE, SEQ, START, S) { \
875+
int i; \
876+
asdl_seq *seq = (SEQ); /* avoid variable capture */ \
877+
for (i = (START); i < asdl_seq_LEN(seq); i++) { \
878+
TYPE ## _ty elt = asdl_seq_GET(seq, i); \
879+
if (!symtable_visit_ ## TYPE((ST), elt)) { \
880+
symtable_exit_block((ST), (S)); \
881+
return 0; \
882+
} \
883+
} \
884+
}
885+
844886
static int
845887
symtable_visit_stmt(struct symtable *st, stmt_ty s)
846888
{
@@ -855,8 +897,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
855897
if (!symtable_enter_block(st, s->v.FunctionDef.name,
856898
FunctionBlock, (void *)s, s->lineno))
857899
return 0;
858-
VISIT(st, arguments, s->v.FunctionDef.args);
859-
VISIT_SEQ(st, stmt, s->v.FunctionDef.body);
900+
VISIT_IN_BLOCK(st, arguments, s->v.FunctionDef.args, s);
901+
VISIT_SEQ_IN_BLOCK(st, stmt, s->v.FunctionDef.body, s);
860902
if (!symtable_exit_block(st, s))
861903
return 0;
862904
break;
@@ -870,7 +912,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
870912
return 0;
871913
tmp = st->st_private;
872914
st->st_private = s->v.ClassDef.name;
873-
VISIT_SEQ(st, stmt, s->v.ClassDef.body);
915+
VISIT_SEQ_IN_BLOCK(st, stmt, s->v.ClassDef.body, s);
874916
st->st_private = tmp;
875917
if (!symtable_exit_block(st, s))
876918
return 0;
@@ -977,7 +1019,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
9771019
if (cur < 0)
9781020
return 0;
9791021
if (cur & (DEF_LOCAL | USE)) {
980-
char buf[1000];
1022+
char buf[256];
9811023
if (cur & DEF_LOCAL)
9821024
PyOS_snprintf(buf, sizeof(buf),
9831025
GLOBAL_AFTER_ASSIGN,
@@ -991,9 +1033,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
9911033
}
9921034
if (!symtable_add_def(st, name, DEF_GLOBAL))
9931035
return 0;
994-
9951036
}
996-
9971037
break;
9981038
}
9991039
case Expr_kind:
@@ -1031,8 +1071,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
10311071
if (!symtable_enter_block(st, GET_IDENTIFIER(lambda),
10321072
FunctionBlock, (void *)e, 0))
10331073
return 0;
1034-
VISIT(st, arguments, e->v.Lambda.args);
1035-
VISIT(st, expr, e->v.Lambda.body);
1074+
VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e);
1075+
VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e);
10361076
if (!symtable_exit_block(st, (void *)e))
10371077
return 0;
10381078
break;
@@ -1302,12 +1342,14 @@ symtable_visit_genexp(struct symtable *st, expr_ty e)
13021342
st->st_cur->ste_generator = 1;
13031343
/* Outermost iter is received as an argument */
13041344
if (!symtable_implicit_arg(st, 0)) {
1345+
symtable_exit_block(st, (void *)e);
13051346
return 0;
13061347
}
1307-
VISIT(st, expr, outermost->target);
1308-
VISIT_SEQ(st, expr, outermost->ifs);
1309-
VISIT_SEQ_TAIL(st, comprehension, e->v.GeneratorExp.generators, 1);
1310-
VISIT(st, expr, e->v.GeneratorExp.elt);
1348+
VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e);
1349+
VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e);
1350+
VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension,
1351+
e->v.GeneratorExp.generators, 1, (void*)e);
1352+
VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e);
13111353
if (!symtable_exit_block(st, (void *)e))
13121354
return 0;
13131355
return 1;

0 commit comments

Comments
 (0)