Mercurial > octave
changeset 23654:da89ce0d49eb
avoid possible memory leak in parser
* parse.h, oct-parse.in.yy (base_parser::validate_param_list):
New function, adapted from tree_parameter_list::validate.
* pt-misc.h, pt-misc.cc (tree_parameter_list::validate): Delete.
(tree_parameter_list::mark_varargs,
tree_parameter_list::mark_varargs_only): Now public.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 20 Jun 2017 09:28:48 -0400 |
parents | 3bb0a937c071 |
children | bbcc1e08aaed |
files | libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse.h libinterp/parse-tree/pt-misc.cc libinterp/parse-tree/pt-misc.h |
diffstat | 4 files changed, 72 insertions(+), 63 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.in.yy Tue Jun 20 06:57:59 2017 -0400 +++ b/libinterp/parse-tree/oct-parse.in.yy Tue Jun 20 09:28:48 2017 -0400 @@ -1332,7 +1332,8 @@ | param_list2 { $1->mark_as_formal_parameters (); - if ($1->validate (octave::tree_parameter_list::in)) + + if (parser.validate_param_list ($1, octave::tree_parameter_list::in)) { lexer.mark_as_variables ($1->variable_names ()); $$ = $1; @@ -1380,7 +1381,7 @@ // a single identifier, we still need to validate it // to check for varargin or varargout. - if (tmp->validate (octave::tree_parameter_list::out)) + if (parser.validate_param_list (tmp, octave::tree_parameter_list::out)) $$ = tmp; else { @@ -1395,7 +1396,7 @@ // Check for duplicate parameter names, varargin, // or varargout. - if ($2->validate (octave::tree_parameter_list::out)) + if (parser.validate_param_list ($2, octave::tree_parameter_list::out)) $$ = $2; else { @@ -3907,6 +3908,67 @@ } bool + base_parser::validate_param_list (tree_parameter_list *lst, + tree_parameter_list::in_or_out type) + { + std::set<std::string> dict; + + for (tree_decl_elt *elt : *lst) + { + tree_identifier *id = elt->ident (); + + if (id) + { + std::string name = id->name (); + + if (id->is_black_hole ()) + { + if (type != tree_parameter_list::in) + { + bison_error ("invalid use of ~ in output list"); + return false; + } + } + else if (dict.find (name) != dict.end ()) + { + bison_error ("'" + name + + "' appears more than once in parameter list"); + return false; + } + else + dict.insert (name); + } + } + + std::string va_type = (type == tree_parameter_list::in + ? "varargin" : "varargout"); + + size_t len = lst->length (); + + if (len > 0) + { + tree_decl_elt *elt = lst->back (); + + tree_identifier *id = elt->ident (); + + if (id && id->name () == va_type) + { + if (len == 1) + lst->mark_varargs_only (); + else + lst->mark_varargs (); + + tree_parameter_list::iterator p = lst->end (); + --p; + delete *p; + lst->erase (p); + } + } + + return true; + } + + bool base_parser::validate_array_list (tree_expression *e) { bool retval = true;
--- a/libinterp/parse-tree/parse.h Tue Jun 20 06:57:59 2017 -0400 +++ b/libinterp/parse-tree/parse.h Tue Jun 20 09:28:48 2017 -0400 @@ -35,6 +35,7 @@ #include "lex.h" #include "symtab.h" +#include "pt-misc.h" #include "token.h" class octave_comment_list; @@ -358,6 +359,9 @@ tree_decl_command * make_decl_command (int tok, token *tok_val, tree_decl_init_list *lst); + // Validate an function parameter list. + bool validate_param_list (tree_parameter_list *lst, + tree_parameter_list::in_or_out type); // Validate matrix or cell bool validate_array_list (tree_expression *e);
--- a/libinterp/parse-tree/pt-misc.cc Tue Jun 20 06:57:59 2017 -0400 +++ b/libinterp/parse-tree/pt-misc.cc Tue Jun 20 09:28:48 2017 -0400 @@ -57,61 +57,6 @@ elt->mark_as_formal_parameter (); } - bool - tree_parameter_list::validate (in_or_out type) - { - bool retval = true; - - std::set<std::string> dict; - - for (tree_decl_elt *elt : *this) - { - tree_identifier *id = elt->ident (); - - if (id) - { - std::string name = id->name (); - - if (id->is_black_hole ()) - { - if (type != in) - error ("invalid use of ~ in output list"); - } - else if (dict.find (name) != dict.end ()) - error ("'%s' appears more than once in parameter list", - name.c_str ()); - else - dict.insert (name); - } - } - - std::string va_type = (type == in ? "varargin" : "varargout"); - - size_t len = length (); - - if (len > 0) - { - tree_decl_elt *elt = back (); - - tree_identifier *id = elt->ident (); - - if (id && id->name () == va_type) - { - if (len == 1) - mark_varargs_only (); - else - mark_varargs (); - - iterator p = end (); - --p; - delete *p; - erase (p); - } - } - - return retval; - } - std::list<std::string> tree_parameter_list::variable_names (void) const {
--- a/libinterp/parse-tree/pt-misc.h Tue Jun 20 06:57:59 2017 -0400 +++ b/libinterp/parse-tree/pt-misc.h Tue Jun 20 09:28:48 2017 -0400 @@ -68,7 +68,9 @@ void mark_as_formal_parameters (void); - bool validate (in_or_out type); + void mark_varargs (void) { marked_for_varargs = 1; } + + void mark_varargs_only (void) { marked_for_varargs = -1; } bool takes_varargs (void) const { return marked_for_varargs != 0; } @@ -88,10 +90,6 @@ private: int marked_for_varargs; - - void mark_varargs (void) { marked_for_varargs = 1; } - - void mark_varargs_only (void) { marked_for_varargs = -1; } }; // Return lists. Used to hold the right hand sides of multiple