mirror of
https://github.com/python/cpython.git
synced 2025-10-22 06:32:43 +00:00
Fix memory leak in the parser module: There were two leaks in
parser_tuple2st() and a failure to propogate an error in build_node_children() (masking yet another leak, of course!). This closes SF bug #485133 (confirmed by Insure++).
This commit is contained in:
parent
d761662b66
commit
8b55b2d9aa
1 changed files with 22 additions and 5 deletions
|
@ -28,6 +28,7 @@
|
||||||
#include "Python.h" /* general Python API */
|
#include "Python.h" /* general Python API */
|
||||||
#include "graminit.h" /* symbols defined in the grammar */
|
#include "graminit.h" /* symbols defined in the grammar */
|
||||||
#include "node.h" /* internal parser structure */
|
#include "node.h" /* internal parser structure */
|
||||||
|
#include "errcode.h" /* error codes for PyNode_*() */
|
||||||
#include "token.h" /* token definitions */
|
#include "token.h" /* token definitions */
|
||||||
/* ISTERMINAL() / ISNONTERMINAL() */
|
/* ISTERMINAL() / ISNONTERMINAL() */
|
||||||
#include "compile.h" /* PyNode_Compile() */
|
#include "compile.h" /* PyNode_Compile() */
|
||||||
|
@ -598,11 +599,15 @@ parser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw)
|
||||||
/* Might be an eval form. */
|
/* Might be an eval form. */
|
||||||
if (validate_expr_tree(tree))
|
if (validate_expr_tree(tree))
|
||||||
st = parser_newstobject(tree, PyST_EXPR);
|
st = parser_newstobject(tree, PyST_EXPR);
|
||||||
|
else
|
||||||
|
PyNode_Free(tree);
|
||||||
}
|
}
|
||||||
else if (start_sym == file_input) {
|
else if (start_sym == file_input) {
|
||||||
/* This looks like an exec form so far. */
|
/* This looks like an exec form so far. */
|
||||||
if (validate_file_input(tree))
|
if (validate_file_input(tree))
|
||||||
st = parser_newstobject(tree, PyST_SUITE);
|
st = parser_newstobject(tree, PyST_SUITE);
|
||||||
|
else
|
||||||
|
PyNode_Free(tree);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* This is a fragment, at best. */
|
/* This is a fragment, at best. */
|
||||||
|
@ -632,7 +637,7 @@ static node*
|
||||||
build_node_children(PyObject *tuple, node *root, int *line_num)
|
build_node_children(PyObject *tuple, node *root, int *line_num)
|
||||||
{
|
{
|
||||||
int len = PyObject_Size(tuple);
|
int len = PyObject_Size(tuple);
|
||||||
int i;
|
int i, err;
|
||||||
|
|
||||||
for (i = 1; i < len; ++i) {
|
for (i = 1; i < len; ++i) {
|
||||||
/* elem must always be a sequence, however simple */
|
/* elem must always be a sequence, however simple */
|
||||||
|
@ -713,7 +718,17 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
|
||||||
Py_XDECREF(elem);
|
Py_XDECREF(elem);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
PyNode_AddChild(root, type, strn, *line_num);
|
err = PyNode_AddChild(root, type, strn, *line_num);
|
||||||
|
if (err == E_NOMEM) {
|
||||||
|
PyMem_DEL(strn);
|
||||||
|
return (node *) PyErr_NoMemory();
|
||||||
|
}
|
||||||
|
if (err == E_OVERFLOW) {
|
||||||
|
PyMem_DEL(strn);
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"unsupported number of child nodes");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ISNONTERMINAL(type)) {
|
if (ISNONTERMINAL(type)) {
|
||||||
node* new_child = CHILD(root, i - 1);
|
node* new_child = CHILD(root, i - 1);
|
||||||
|
@ -758,9 +773,11 @@ build_node_tree(PyObject *tuple)
|
||||||
int line_num = 0;
|
int line_num = 0;
|
||||||
|
|
||||||
res = PyNode_New(num);
|
res = PyNode_New(num);
|
||||||
if (res != build_node_children(tuple, res, &line_num)) {
|
if (res != NULL) {
|
||||||
PyNode_Free(res);
|
if (res != build_node_children(tuple, res, &line_num)) {
|
||||||
res = 0;
|
PyNode_Free(res);
|
||||||
|
res = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue