changeset 15968:cdeb6eb656be classdef

Move property/method access check down to cdef_property/cdef_method classes. * libinterp/octave-value/ov-classdef.h (cdef_property::cdef_property_rep::get_value, cdef_property::cdef_property_rep::set_value): Add arguments (do_check_access and who) to control access checking and pass down to gripe utility function. (cdef_property::get_value, cdef_property::set_value): Likewise. (cdef_method::cdef_method_rep::execute): Likewise. (cdef_method::execute): Likewise. (cdef_property::check_get_access, cdef_property::check_set_access): Move implementation to cdef_property::cdef_property_rep. (cdef_property::cdef_property_rep::check_get_access, cdef_property::cdef_property_rep::check_set_access): New methods, moved from cdef_property. (cdef_method::check_access): Move implementation to cdef_method::cdef_method_rep. (cdef_method::cdef_method_rep::check_access): New method, moved from cdef_method. (cdef_property::cdef_property_rep::wrap): New method. (cdef_method::cdef_method_rep::wrap): New method. * libinterp/octave-value/ov-classdef.cc (cdef_property::cdef_property_rep::get_value, cdef_property::cdef_property_rep::set_value): Add arguments (do_check_access and who) to control access checking and pass down to gripe utility function. (cdef_property::cdef_property_rep::check_get_access, (cdef_method::cdef_method_rep::execute): Likewise. cdef_property::cdef_property_rep::check_set_access): New methods, moved from cdef_property. (cdef_method::cdef_method_rep::check_access): New method, moved from cdef_method. (class_fevalStatic, octave_classdef_superclass_ref::do_multi_index_op, cdef_object_scalar::subsref, cdef_class::cdef_class_rep::subsref_meta, cdef_class::cdef_class_rep::construct_object): Do not check access, let cdef_method::execute handle it. (class_getConstant, cdef_object_scalar::subsref, cdef_object_scalar::subsasgn, cdef_class::cdef_class_rep::subsref_meta): Do not check get/set access, let cdef_property::get_value and cdef_property::set_value handle it. (cdef_class::cdef_class_rep::delete_object): Execute "delete" method without access checking.
author Michael Goffioul <michael.goffioul@gmail.com>
date Sun, 20 Jan 2013 23:03:17 -0500
parents 24ceda35d146
children 14aa0b5a980c
files libinterp/octave-value/ov-classdef.cc libinterp/octave-value/ov-classdef.h
diffstat 2 files changed, 189 insertions(+), 143 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-classdef.cc	Sun Jan 20 14:50:04 2013 -0500
+++ b/libinterp/octave-value/ov-classdef.cc	Sun Jan 20 23:03:17 2013 -0500
@@ -471,16 +471,12 @@
 
 	      if (meth.ok ())
 		{
-		  if (meth.check_access ())
-		    {
-		      if (meth.is_static ())
-			retval = meth.execute (args.splice (0, 2), nargout);
-		      else
-			error ("fevalStatic: method `%s' is not static",
-			       meth_name.c_str ());
-		    }
-		  else
-		    gripe_method_access ("fevalStatic", meth);
+                    if (meth.is_static ())
+                      retval = meth.execute (args.splice (0, 2), nargout,
+                                             true, "fevalStatic");
+                    else
+                      error ("fevalStatic: method `%s' is not static",
+                             meth_name.c_str ());
 		}
 	      else
 		error ("fevalStatic: method not found: %s",
@@ -517,16 +513,11 @@
 
 	      if (prop.ok ())
 		{
-		  if (prop.check_get_access ())
-		    {
-		      if (prop.is_constant ())
-			retval(0) = prop.get_value ();
-		      else
-			error ("getConstant: property `%s' is not constant",
-			       prop_name.c_str ());
-		    }
-		  else
-		    gripe_property_access ("getConstant", prop);
+                  if (prop.is_constant ())
+                    retval(0) = prop.get_value (true, "getConstant");
+                  else
+                    error ("getConstant: property `%s' is not constant",
+                           prop_name.c_str ());
 		}
 	      else
 		error ("getConstant: property not found: %s",
@@ -1004,12 +995,8 @@
                           cdef_method meth = cls.find_method (meth_name, false);
 
                           if (meth.ok ())
-                            {
-                              if (meth.check_access ())
-                                retval = meth.execute (idx, nargout);
-                              else
-                                gripe_method_access (meth_name, meth);
-                            }
+                            retval = meth.execute (idx, nargout, true,
+                                                   meth_name);
                           else
                             ::error ("no method `%s' found in superclass `%s'",
                                      meth_name.c_str (), cls_name.c_str ());
@@ -1093,33 +1080,29 @@
 
 	  if (meth.ok ())
 	    {
-	      if (meth.check_access ())
-		{
-		  int _nargout = (type.length () > 2 ? 1 : nargout);
-
-		  octave_value_list args;
-
-		  skip = 1;
-
-		  if (type.length () > 1 && type[1] == '(')
-		    {
-		      std::list<octave_value_list>::const_iterator it = idx.begin ();
-
-		      args = *++it;
-
-		      skip++;
-		    }
-
-		  if (meth.is_static ())
-		    retval = meth.execute (args, _nargout);
-		  else
-		    {
-		      refcount++;
-		      retval = meth.execute (cdef_object (this), args, _nargout);
-		    }
-		}
-	      else
-		gripe_method_access ("subsref", meth);
+              int _nargout = (type.length () > 2 ? 1 : nargout);
+
+              octave_value_list args;
+
+              skip = 1;
+
+              if (type.length () > 1 && type[1] == '(')
+                {
+                  std::list<octave_value_list>::const_iterator it = idx.begin ();
+
+                  args = *++it;
+
+                  skip++;
+                }
+
+              if (meth.is_static ())
+                retval = meth.execute (args, _nargout, true, "subsref");
+              else
+                {
+                  refcount++;
+                  retval = meth.execute (cdef_object (this), args, _nargout,
+                                         true, "subsref");
+                }
 	    }
 
 	  if (skip == 0 && ! error_state)
@@ -1128,20 +1111,16 @@
 
 	      if (prop.ok ())
 		{
-		  if (prop.check_get_access ())
-		    {
-                      if (prop.is_constant ())
-                        retval(0) = prop.get_value ();
-                      else
-                        {
-                          refcount++;
-                          retval(0) = prop.get_value (cdef_object (this));
-                        }
-
-		      skip = 1;
-		    }
-		  else
-		    gripe_property_access ("subsref", prop);
+                  if (prop.is_constant ())
+                    retval(0) = prop.get_value (true, "subsref");
+                  else
+                    {
+                      refcount++;
+                      retval(0) = prop.get_value (cdef_object (this),
+                                                  true, "subsref");
+                    }
+
+                  skip = 1;
 		}
 	      else
 		error ("subsref: unknown method or property: %s", name.c_str ());
@@ -1179,19 +1158,14 @@
                 {
                   if (type.length () == 1)
                     {
-                      if (prop.check_set_access ())
-                        {
-                          refcount++;
-
-                          cdef_object obj (this);
-
-                          prop.set_value (obj, rhs);
-
-                          if (! error_state)
-                            retval = to_ov (obj);
-                        }
-                      else
-                        gripe_property_access ("subsasgn", prop, true);
+                      refcount++;
+
+                      cdef_object obj (this);
+
+                      prop.set_value (obj, rhs, true, "subsasgn");
+
+                      if (! error_state)
+                        retval = to_ov (obj);
                     }
                   else
                     {
@@ -1922,7 +1896,7 @@
 
       obj.set_class (wrap ());
 
-      it->second.execute (obj, octave_value_list (), 0);
+      it->second.execute (obj, octave_value_list (), 0, false);
 
       obj.set_class (cls);
     }
@@ -1974,22 +1948,18 @@
                 {
                   if (meth.is_static ())
                     {
-                      if (meth.check_access ())
+                      octave_value_list args;
+
+                      if (type.length () > 1 && idx.size () > 1
+                          && type[1] == '(')
                         {
-                          octave_value_list args;
-
-                          if (type.length () > 1 && idx.size () > 1
-                              && type[1] == '(')
-                            {
-                              args = *(++(idx.begin ()));
-                              skip++;
-                            }
-
-                          retval = meth.execute (args, (type.length () > skip
-                                                        ? 1 : nargout));
+                          args = *(++(idx.begin ()));
+                          skip++;
                         }
-                      else
-                        gripe_method_access ("meta.class", meth);
+
+                      retval = meth.execute (args, (type.length () > skip
+                                                    ? 1 : nargout), true,
+                                             "meta.class");
                     }
                   else
                     ::error ("method `%s' is not static", nm.c_str ());
@@ -2001,12 +1971,7 @@
                   if (prop.ok ())
                     {
                       if (prop.is_constant ())
-                        {
-                          if (prop.check_get_access ())
-                            retval(0) = prop.get_value ();
-                          else
-                            gripe_property_access ("meta.class", prop, false);
-                        }
+                        retval(0) = prop.get_value (true, "meta.class");
                       else
                         ::error ("property `%s' is not constant",
                                  nm.c_str ());
@@ -2099,28 +2064,23 @@
 
   if (ctor.ok ())
     {
-      if (ctor.check_access ())
+      octave_value_list ctor_args (args);
+      octave_value_list ctor_retval;
+
+      ctor_args.prepend (to_ov (obj));
+      ctor_retval = ctor.execute (ctor_args, 1, true, "constructor");
+
+      if (! error_state)
         {
-          octave_value_list ctor_args (args);
-          octave_value_list ctor_retval;
-
-          ctor_args.prepend (to_ov (obj));
-          ctor_retval = ctor.execute (ctor_args, 1);
-
-          if (! error_state)
+          if (ctor_retval.length () == 1)
+            obj = to_cdef (ctor_retval(0));
+          else
             {
-              if (ctor_retval.length () == 1)
-                obj = to_cdef (ctor_retval(0));
-              else
-                {
-                  ::error ("%s: invalid number of output arguments for classdef constructor",
-                           ctor_name.c_str ());
-                  return;
-                }
+              ::error ("%s: invalid number of output arguments for classdef constructor",
+                       ctor_name.c_str ());
+              return;
             }
         }
-      else
-        gripe_method_access ("constructor", ctor);
     }
 
   obj.mark_as_constructed (wrap ());
@@ -2446,10 +2406,19 @@
 }
 
 octave_value
-cdef_property::cdef_property_rep::get_value (const cdef_object& obj)
+cdef_property::cdef_property_rep::get_value (const cdef_object& obj,
+                                             bool do_check_access,
+                                             const std::string& who)
 {
   octave_value retval;
 
+  if (do_check_access && ! check_get_access ())
+    {
+      gripe_property_access (who, wrap (), false);
+
+      return retval;
+    }
+
   if (! obj.is_constructed ())
     {
       cdef_class cls (to_cdef (get ("DefiningClass")));
@@ -2483,6 +2452,20 @@
   return retval;
 }
 
+octave_value
+cdef_property::cdef_property_rep::get_value (bool do_check_access,
+                                             const std::string& who)
+{
+  if (do_check_access && ! check_get_access ())
+    {
+      gripe_property_access (who, wrap (), false);
+
+      return octave_value ();
+    }
+
+  return get ("DefaultValue");
+}
+
 bool
 cdef_property::cdef_property_rep::is_recursive_set (const cdef_object& /* obj */) const
 {
@@ -2492,8 +2475,17 @@
 
 void
 cdef_property::cdef_property_rep::set_value (cdef_object& obj,
-                                             const octave_value& val)
+                                             const octave_value& val,
+                                             bool do_check_access,
+                                             const std::string& who)
 {
+  if (do_check_access && ! check_set_access ())
+    {
+      gripe_property_access (who, wrap (), true);
+
+      return;
+    }
+
   if (! obj.is_constructed ())
     {
       cdef_class cls (to_cdef (get ("DefiningClass")));
@@ -2535,7 +2527,7 @@
 }
 
 bool
-cdef_property::check_get_access (void) const
+cdef_property::cdef_property_rep::check_get_access (void) const
 {
   cdef_class cls (to_cdef (get ("DefiningClass")));
 
@@ -2546,7 +2538,7 @@
 }
 
 bool
-cdef_property::check_set_access (void) const
+cdef_property::cdef_property_rep::check_set_access (void) const
 {
   cdef_class cls (to_cdef (get ("DefiningClass")));
 
@@ -2564,10 +2556,18 @@
 
 octave_value_list
 cdef_method::cdef_method_rep::execute (const octave_value_list& args,
-				       int nargout)
+				       int nargout, bool do_check_access,
+                                       const std::string& who)
 {
   octave_value_list retval;
 
+  if (do_check_access && ! check_access ())
+    {
+      gripe_method_access (who, wrap ());
+
+      return retval;
+    }
+
   if (! get ("Abstract").bool_value ())
     {
       check_method ();
@@ -2587,10 +2587,18 @@
 octave_value_list
 cdef_method::cdef_method_rep::execute (const cdef_object& obj,
 				       const octave_value_list& args,
-				       int nargout)
+				       int nargout, bool do_check_access,
+                                       const std::string& who)
 {
   octave_value_list retval;
 
+  if (do_check_access && ! check_access ())
+    {
+      gripe_method_access (who, wrap ());
+
+      return retval;
+    }
+
   if (! get ("Abstract").bool_value ())
     {
       check_method ();
@@ -2625,7 +2633,7 @@
 }
 
 bool
-cdef_method::check_access (void) const
+cdef_method::cdef_method_rep::check_access (void) const
 {
   cdef_class cls (to_cdef (get ("DefiningClass")));
 
--- a/libinterp/octave-value/ov-classdef.h	Sun Jan 20 14:50:04 2013 -0500
+++ b/libinterp/octave-value/ov-classdef.h	Sun Jan 20 23:03:17 2013 -0500
@@ -834,17 +834,32 @@
 
     bool is_constant (void) const { return get("Constant").bool_value (); }
 
-    octave_value get_value (void) const { return get ("DefaultValue"); }
+    octave_value get_value (bool do_check_access = true,
+                            const std::string& who = std::string ());
+
+    octave_value get_value (const cdef_object& obj,
+                            bool do_check_access = true,
+                            const std::string& who = std::string ());
 
-    octave_value get_value (const cdef_object& obj);
+    void set_value (cdef_object& obj, const octave_value& val,
+                    bool do_check_access = true,
+                    const std::string& who = std::string ());
 
-    void set_value (cdef_object& obj, const octave_value& val);
+    bool check_get_access (void) const;
+
+    bool check_set_access (void) const;
 
   private:
     cdef_property_rep (const cdef_property_rep& p)
       : handle_cdef_object (p) { }
 
     bool is_recursive_set (const cdef_object& obj) const;
+
+    cdef_property wrap (void)
+      {
+        refcount++;
+        return cdef_property (this);
+      }
   };
 
 public:
@@ -873,17 +888,24 @@
       return *this;
     }
 
-  octave_value get_value (const cdef_object& obj)
-    { return get_rep ()->get_value (obj); }
+  octave_value get_value (const cdef_object& obj, bool do_check_access = true,
+                          const std::string& who = std::string ())
+    { return get_rep ()->get_value (obj, do_check_access, who); }
 
-  octave_value get_value (void) { return get_rep ()->get_value (); }
+  octave_value get_value (bool do_check_access = true,
+                          const std::string& who = std::string ())
+    { return get_rep ()->get_value (do_check_access, who); }
 
-  void set_value (cdef_object& obj, const octave_value& val)
-    { get_rep ()->set_value (obj, val); }
+  void set_value (cdef_object& obj, const octave_value& val,
+                  bool do_check_access = true,
+                  const std::string& who = std::string ())
+    { get_rep ()->set_value (obj, val, do_check_access, who); }
 
-  bool check_get_access (void) const;
+  bool check_get_access (void) const
+    { return get_rep ()->check_get_access (); }
   
-  bool check_set_access (void) const;
+  bool check_set_access (void) const
+    { return get_rep ()->check_set_access (); }
 
   std::string get_name (void) const { return get_rep ()->get_name (); }
 
@@ -924,10 +946,16 @@
 
     void set_function (const octave_value& fcn) { function = fcn; }
 
-    octave_value_list execute (const octave_value_list& args, int nargout);
+    bool check_access (void) const;
+
+    octave_value_list execute (const octave_value_list& args, int nargout,
+                               bool do_check_access = true,
+                               const std::string& who = std::string ());
 
     octave_value_list execute (const cdef_object& obj,
-			       const octave_value_list& args, int nargout);
+			       const octave_value_list& args, int nargout,
+                               bool do_check_access = true,
+                               const std::string& who = std::string ());
 
     bool is_constructor (void) const;
 
@@ -937,6 +965,12 @@
 
     void check_method (void);
 
+    cdef_method wrap (void)
+      {
+        refcount++;
+        return cdef_method (this);
+      }
+
   private:
     octave_value function;
   };
@@ -968,15 +1002,19 @@
     }
 
   /* normal invokation */
-  octave_value_list execute (const octave_value_list& args, int nargout)
-    { return get_rep ()->execute (args, nargout); }
+  octave_value_list execute (const octave_value_list& args, int nargout,
+                             bool do_check_access = true,
+                             const std::string& who = std::string ())
+    { return get_rep ()->execute (args, nargout, do_check_access, who); }
 
   /* dot-invokation: object is pushed as 1st argument */
   octave_value_list execute (const cdef_object& obj,
-			     const octave_value_list& args, int nargout)
-    { return get_rep ()->execute (obj, args, nargout); }
+			     const octave_value_list& args, int nargout,
+                             bool do_check_access = true,
+                             const std::string& who = std::string ())
+    { return get_rep ()->execute (obj, args, nargout, do_check_access, who); }
 
-  bool check_access (void) const;
+  bool check_access (void) const { return get_rep ()->check_access (); }
   
   std::string get_name (void) const { return get_rep ()->get_name (); }