Mercurial > octave
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 } |