# HG changeset patch # User John W. Eaton # Date 1240425687 14400 # Node ID 69e6bbfef8c2ebbb125fe1e21832cb302bb14075 # Parent 5579998f8acfa700f062269e75ec21106192d488 ov-class.cc: protect against possiblly invalid octave_value -> string conversions diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2009-04-22 John W. Eaton + + * ov-class.cc (octave_class::dotref, octave_class::subsasgn): + Protect against possibly invalid octave_value -> string conversions. + 2009-04-22 Robert T. Short * variables.cc (symbol_exist): Also return 1 for objects. diff --git a/src/ov-class.cc b/src/ov-class.cc --- a/src/ov-class.cc +++ b/src/ov-class.cc @@ -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::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& 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 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 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 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 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::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 {