comparison 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
comparison
equal deleted inserted replaced
17640:482222fe5b35 17641:cd5a6008ae72
2733 } 2733 }
2734 2734
2735 void 2735 void
2736 base_properties::set_parent (const octave_value& val) 2736 base_properties::set_parent (const octave_value& val)
2737 { 2737 {
2738 double tmp = val.double_value (); 2738 double hnp = val.double_value ();
2739 2739
2740 graphics_handle new_parent = octave_NaN; 2740 graphics_handle new_parent = octave_NaN;
2741 2741
2742 if (! error_state) 2742 if (! error_state)
2743 { 2743 {
2744 if (tmp == __myhandle__) 2744 if (hnp == __myhandle__)
2745 error ("set: can not set object parent to be object itself"); 2745 error ("set: can not set object parent to be object itself");
2746 else 2746 else
2747 { 2747 {
2748 new_parent = gh_manager::lookup (tmp); 2748 new_parent = gh_manager::lookup (hnp);
2749 2749
2750 if (new_parent.ok ()) 2750 if (new_parent.ok ())
2751 { 2751 {
2752 graphics_object parent_obj; 2752 // Remove child from current parent
2753 2753 graphics_object old_parent_obj;
2754 parent_obj = gh_manager::get_object (get_parent ()); 2754 old_parent_obj = gh_manager::get_object (get_parent ());
2755 2755 old_parent_obj.remove_child (__myhandle__);
2756 parent_obj.remove_child (__myhandle__); 2756
2757 2757 // Check new parent's parent is not this child to avoid recursion
2758 graphics_object new_parent_obj;
2759 new_parent_obj = gh_manager::get_object (new_parent);
2760 if (new_parent_obj.get_parent () == __myhandle__)
2761 {
2762 // new parent's parent gets child's original parent
2763 new_parent_obj.get_properties ().set_parent (get_parent ().as_octave_value ());
2764 }
2765
2766 // Set parent property to new_parent and do adoption
2758 parent = new_parent.as_octave_value (); 2767 parent = new_parent.as_octave_value ();
2759
2760 ::adopt (parent.handle_value (), __myhandle__); 2768 ::adopt (parent.handle_value (), __myhandle__);
2761 } 2769 }
2762 else 2770 else
2763 error ("set: invalid graphics handle (= %g) for parent", tmp); 2771 error ("set: invalid graphics handle (= %g) for parent", hnp);
2764 } 2772 }
2765 } 2773 }
2766 else 2774 else
2767 error ("set: expecting parent to be a graphics handle"); 2775 error ("set: expecting parent to be a graphics handle");
2768 } 2776 }