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