changeset 23850:4b0e0cae49db

disallow dynamic variable creation in static scopes (bug #51698) * error.cc (Fwarning): Use force_assign to set value of .saved_warning_states. variable. * ov-usr-fcn.cc (octave_user_function::bind_automatic_var): Use force_assign to set value of .saved_warning_states. and .ignored. variables. * symtab.cc (symbol_table::scope::update_nest): Also mark the scope of nested functions as static. * symtab.h (symbol_table::scope::is_static, symbol_table::scope::mark_static): New functions. * oct-parse.in.yy (base_parser::make_anon_fcn_handle): Mark anonymous function scope as static. * nest.tst: Update tests.
author John W. Eaton <jwe@octave.org>
date Wed, 09 Aug 2017 13:11:54 -0400
parents d139435d9193
children e43e95392c29
files libinterp/corefcn/error.cc libinterp/corefcn/symtab.cc libinterp/corefcn/symtab.h libinterp/octave-value/ov-usr-fcn.cc libinterp/parse-tree/oct-parse.in.yy test/nest/nest.tst
diffstat 6 files changed, 21 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/error.cc	Wed Aug 09 10:12:58 2017 -0700
+++ b/libinterp/corefcn/error.cc	Wed Aug 09 13:11:54 2017 -0400
@@ -1570,7 +1570,7 @@
               m.contents ("identifier") = ids;
               m.contents ("state") = states;
 
-              scope->assign (".saved_warning_states.", m);
+              scope->force_assign (".saved_warning_states.", m);
 
               // Now ignore the "local" argument and continue to
               // handle the current setting.
--- a/libinterp/corefcn/symtab.cc	Wed Aug 09 10:12:58 2017 -0700
+++ b/libinterp/corefcn/symtab.cc	Wed Aug 09 13:11:54 2017 -0400
@@ -1828,10 +1828,15 @@
             else
               ours.set_curr_fcn (m_fcn);
           }
+
+        // The scopes of nested functions are static.
+        m_is_static = true;
       }
     else if (m_children.size ())
       {
+        // Parents of nested functions have static scopes.
         m_is_static = true;
+
         for (auto& nm_sr : m_symbols)
           nm_sr.second.set_curr_fcn (m_fcn);
       }
--- a/libinterp/corefcn/symtab.h	Wed Aug 09 10:12:58 2017 -0700
+++ b/libinterp/corefcn/symtab.h	Wed Aug 09 13:11:54 2017 -0400
@@ -1588,6 +1588,10 @@
 
       void mark_nested (void) { m_is_nested = true; }
 
+      bool is_static (void) const { return m_is_static; }
+
+      void mark_static (void) { m_is_static = true; }
+
       scope * parent_scope (void) const { return m_parent; }
 
       scope * dup (void) const
--- a/libinterp/octave-value/ov-usr-fcn.cc	Wed Aug 09 10:12:58 2017 -0700
+++ b/libinterp/octave-value/ov-usr-fcn.cc	Wed Aug 09 13:11:54 2017 -0400
@@ -807,7 +807,7 @@
   m_scope->mark_automatic (".nargin.");
   m_scope->mark_automatic (".nargout.");
 
-  m_scope->assign (".saved_warning_states.");
+  m_scope->force_assign (".saved_warning_states.", octave_value ());
 
   m_scope->mark_automatic (".saved_warning_states.");
   m_scope->mark_automatic (".saved_warning_states.");
@@ -817,7 +817,7 @@
 
   Matrix ignored_fcn_outputs = tw.ignored_fcn_outputs ();
 
-  m_scope->assign (".ignored.", ignored_fcn_outputs);
+  m_scope->force_assign (".ignored.", ignored_fcn_outputs);
 
   m_scope->mark_hidden (".ignored.");
   m_scope->mark_automatic (".ignored.");
--- a/libinterp/parse-tree/oct-parse.in.yy	Wed Aug 09 10:12:58 2017 -0700
+++ b/libinterp/parse-tree/oct-parse.in.yy	Wed Aug 09 13:11:54 2017 -0400
@@ -2420,11 +2420,13 @@
 
     expr->set_print_flag (false);
 
+    fcn_scope->mark_static ();
+
     tree_anon_fcn_handle *retval
       = new tree_anon_fcn_handle (param_list, expr, fcn_scope,
                                   parent_scope, l, c);
 
-// FIXME: Stash the filename.  This does not work and produces
+    // FIXME: Stash the filename.  This does not work and produces
     // errors when executed.
     //retval->stash_file_name (m_lexer.fcn_file_name);
 
--- a/test/nest/nest.tst	Wed Aug 09 10:12:58 2017 -0700
+++ b/test/nest/nest.tst	Wed Aug 09 13:11:54 2017 -0400
@@ -48,8 +48,12 @@
 %! scope3;
 
 %!assert (nest_eval ("x = 5;", "x = 6;"), 6)
-%!assert (nest_eval ("x = 5;", "y = 6;"), 5)
-%!assert (nest_eval ("x = -5; x = abs (x);", "y = 6;"), 5)
+
+%!error <can not add variable "y" to a static workspace>
+%! nest_eval ("x = 5;", "y = 6;");
+
+%!error <can not add variable "y" to a static workspace>
+%! nest_eval ("x = -5; x = abs (x);", "y = 6;")
 
 %!test
 %! f = no_closure (0);