changeset 9148:69e6bbfef8c2

ov-class.cc: protect against possiblly invalid octave_value -> string conversions
author John W. Eaton <jwe@octave.org>
date Wed, 22 Apr 2009 14:41:27 -0400
parents 5579998f8acf
children 7120fbbecf97
files src/ChangeLog src/ov-class.cc
diffstat 2 files changed, 130 insertions(+), 105 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Apr 22 14:33:26 2009 -0400
+++ b/src/ChangeLog	Wed Apr 22 14:41:27 2009 -0400
@@ -1,3 +1,8 @@
+2009-04-22  John W. Eaton  <jwe@octave.org>
+
+	* ov-class.cc (octave_class::dotref, octave_class::subsasgn):
+	Protect against possibly invalid octave_value -> string conversions.
+
 2009-04-22  Robert T. Short  <octave@phaselockedsystems.com>
 
 	* variables.cc (symbol_exist): Also return 1 for objects.
--- a/src/ov-class.cc	Wed Apr 22 14:33:26 2009 -0400
+++ b/src/ov-class.cc	Wed Apr 22 14:41:27 2009 -0400
@@ -93,37 +93,6 @@
     load_path::add_to_parent_map (id, parent_list);
 }
 
-octave_base_value *
-octave_class::find_parent_class (const std::string& parent_class_name)
-{
-  octave_base_value* retval = 0;
-
-  if (parent_class_name == class_name ())
-    retval = this;
-  else
-    {
-      for (std::list<std::string>::iterator pit = parent_list.begin ();
-	   pit != parent_list.end ();
-	   pit++)
-	{
-	  Octave_map::const_iterator smap = map.seek (*pit);
-
-	  const Cell& tmp = smap->second;
-
-	  octave_value vtmp = tmp(0);
-
-	  octave_base_value *obvp = vtmp.internal_rep ();
-
-	  retval = obvp->find_parent_class (parent_class_name);
-
-	  if (retval)
-	    break;
-	}
-    }
-
-  return retval;
-}
-
 static std::string
 get_current_method_class (void)
 {
@@ -139,36 +108,6 @@
   return my_dir.substr (ipos+1);
 }
 
-Cell
-octave_class::dotref (const octave_value_list& idx)
-{
-  Cell retval;
-
-  assert (idx.length () == 1);
-
-  std::string method_class = get_current_method_class ();
-
-  // Find the class in which this method resides before attempting to access
-  // the requested field.
-
-  octave_base_value *obvp = find_parent_class (method_class);
-
-  Octave_map my_map;
-
-  my_map = obvp ? obvp->map_value () : map;
-
-  std::string nm = idx(0).string_value ();
-
-  Octave_map::const_iterator p = my_map.seek (nm);
-
-  if (p != my_map.end ())
-    retval = my_map.contents (p);
-  else
-    error ("class has no member `%s'", nm.c_str ());
-
-  return retval;
-}
-
 static void
 gripe_invalid_index (void)
 {
@@ -284,6 +223,41 @@
   return retval;
 }
 
+Cell
+octave_class::dotref (const octave_value_list& idx)
+{
+  Cell retval;
+
+  assert (idx.length () == 1);
+
+  std::string method_class = get_current_method_class ();
+
+  // Find the class in which this method resides before attempting to access
+  // the requested field.
+
+  octave_base_value *obvp = find_parent_class (method_class);
+
+  Octave_map my_map;
+
+  my_map = obvp ? obvp->map_value () : map;
+
+  std::string nm = idx(0).string_value ();
+
+  if (! error_state)
+    {
+      Octave_map::const_iterator p = my_map.seek (nm);
+
+      if (p != my_map.end ())
+	retval = my_map.contents (p);
+      else
+	error ("class has no member `%s'", nm.c_str ());
+    }
+  else
+    gripe_invalid_index ();
+
+  return retval;
+}
+
 octave_value_list
 octave_class::subsref (const std::string& type,
 		       const std::list<octave_value_list>& idx,
@@ -468,33 +442,38 @@
 
 		std::string key = key_idx(0).string_value ();
 
-		octave_value u;
-
-		if (! map.contains (key))
-		  u = octave_value::empty_conv (type.substr (2), rhs);
-		else
-		  {
-		    Cell map_val = map.contents (key);
-
-		    Cell map_elt = map_val.index (idx.front (), true);
-
-		    u = numeric_conv (map_elt, type.substr (2));
-		  }
-
 		if (! error_state)
 		  {
-		    std::list<octave_value_list> next_idx (idx);
+		    octave_value u;
 
-		    // We handled two index elements, so subsasgn to
-		    // needs to skip both of them.
+		    if (! map.contains (key))
+		      u = octave_value::empty_conv (type.substr (2), rhs);
+		    else
+		      {
+			Cell map_val = map.contents (key);
+
+			Cell map_elt = map_val.index (idx.front (), true);
+
+			u = numeric_conv (map_elt, type.substr (2));
+		      }
 
-		    next_idx.erase (next_idx.begin ());
-		    next_idx.erase (next_idx.begin ());
+		    if (! error_state)
+		      {
+			std::list<octave_value_list> next_idx (idx);
+
+			// We handled two index elements, so subsasgn to
+			// needs to skip both of them.
 
-		    u.make_unique ();
+			next_idx.erase (next_idx.begin ());
+			next_idx.erase (next_idx.begin ());
+
+			u.make_unique ();
 
-		    t_rhs = u.subsasgn (type.substr (2), next_idx, rhs);
+			t_rhs = u.subsasgn (type.substr (2), next_idx, rhs);
+		      }
 		  }
+		else
+		  gripe_invalid_index_for_assignment ();
 	      }
 	    else
 	      gripe_invalid_index_for_assignment ();
@@ -509,27 +488,32 @@
 
 	    std::string key = key_idx(0).string_value ();
 
-	    octave_value u;
-
-	    if (! map.contains (key))
-	      u = octave_value::empty_conv (type.substr (1), rhs);
-	    else
-	      {
-		Cell map_val = map.contents (key);
-
-		u = numeric_conv (map_val, type.substr (1));
-	      }
-
 	    if (! error_state)
 	      {
-		std::list<octave_value_list> next_idx (idx);
+		octave_value u;
 
-		next_idx.erase (next_idx.begin ());
+		if (! map.contains (key))
+		  u = octave_value::empty_conv (type.substr (1), rhs);
+		else
+		  {
+		    Cell map_val = map.contents (key);
+
+		    u = numeric_conv (map_val, type.substr (1));
+		  }
 
-		u.make_unique ();
+		if (! error_state)
+		  {
+		    std::list<octave_value_list> next_idx (idx);
+
+		    next_idx.erase (next_idx.begin ());
 
-		t_rhs = u.subsasgn (type.substr (1), next_idx, rhs);
+		    u.make_unique ();
+
+		    t_rhs = u.subsasgn (type.substr (1), next_idx, rhs);
+		  }
 	      }
+	    else
+	      gripe_invalid_index_for_assignment ();
 	  }
 	  break;
 
@@ -616,12 +600,6 @@
 
 	case '.':
 	  {
-	    octave_value_list key_idx = idx.front ();
-
-	    assert (key_idx.length () == 1);
-
-	    std::string key = key_idx(0).string_value ();
-
 	    // Find the class in which this method resides before 
 	    // attempting to access the requested field.
 
@@ -631,12 +609,23 @@
 
 	    if (obvp)
 	      {
-		obvp->assign (key, t_rhs);
+		octave_value_list key_idx = idx.front ();
+
+		assert (key_idx.length () == 1);
+
+		std::string key = key_idx(0).string_value ();
 
 		if (! error_state)
 		  {
-		    count++;
-		    retval = octave_value (this);
+		    obvp->assign (key, t_rhs);
+
+		    if (! error_state)
+		      {
+			count++;
+			retval = octave_value (this);
+		      }
+		    else
+		      gripe_failed_assignment ();
 		  }
 		else
 		  gripe_failed_assignment ();
@@ -721,6 +710,37 @@
   return retval;
 }
 
+octave_base_value *
+octave_class::find_parent_class (const std::string& parent_class_name)
+{
+  octave_base_value* retval = 0;
+
+  if (parent_class_name == class_name ())
+    retval = this;
+  else
+    {
+      for (std::list<std::string>::iterator pit = parent_list.begin ();
+	   pit != parent_list.end ();
+	   pit++)
+	{
+	  Octave_map::const_iterator smap = map.seek (*pit);
+
+	  const Cell& tmp = smap->second;
+
+	  octave_value vtmp = tmp(0);
+
+	  octave_base_value *obvp = vtmp.internal_rep ();
+
+	  retval = obvp->find_parent_class (parent_class_name);
+
+	  if (retval)
+	    break;
+	}
+    }
+
+  return retval;
+}
+
 void
 octave_class::print (std::ostream& os, bool) const
 {