Mercurial > hg > octave-nkf
diff libinterp/corefcn/graphics.cc @ 17641:cd5a6008ae72
Fix recursion segfault when setting axis parent to be child hggroup (bug #37927).
* libinterp/corefcn/graphics.cc(set_parent): Check that new parent's parent is
not object which is being reparented to avoid recursion. When condition occurs
use object's current parent as parent property for new parent. If this sounds
convoluted, it's because it is.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 11 Oct 2013 21:21:50 -0700 |
parents | 94dd9bba06a0 |
children | 57750dc54ab6 |
line wrap: on
line diff
--- a/libinterp/corefcn/graphics.cc +++ b/libinterp/corefcn/graphics.cc @@ -2735,32 +2735,40 @@ void base_properties::set_parent (const octave_value& val) { - double tmp = val.double_value (); + double hnp = val.double_value (); graphics_handle new_parent = octave_NaN; if (! error_state) { - if (tmp == __myhandle__) + if (hnp == __myhandle__) error ("set: can not set object parent to be object itself"); else { - new_parent = gh_manager::lookup (tmp); + new_parent = gh_manager::lookup (hnp); if (new_parent.ok ()) { - graphics_object parent_obj; - - parent_obj = gh_manager::get_object (get_parent ()); - - parent_obj.remove_child (__myhandle__); - + // Remove child from current parent + graphics_object old_parent_obj; + old_parent_obj = gh_manager::get_object (get_parent ()); + old_parent_obj.remove_child (__myhandle__); + + // Check new parent's parent is not this child to avoid recursion + graphics_object new_parent_obj; + new_parent_obj = gh_manager::get_object (new_parent); + if (new_parent_obj.get_parent () == __myhandle__) + { + // new parent's parent gets child's original parent + new_parent_obj.get_properties ().set_parent (get_parent ().as_octave_value ()); + } + + // Set parent property to new_parent and do adoption parent = new_parent.as_octave_value (); - ::adopt (parent.handle_value (), __myhandle__); } else - error ("set: invalid graphics handle (= %g) for parent", tmp); + error ("set: invalid graphics handle (= %g) for parent", hnp); } } else