[nemiver] Fix memory corruption in SourceEditor



commit 390ecd06b145de519b6255645a7e8a3f0ac60265
Author: Dodji Seketeli <dodji seketeli org>
Date:   Sun Apr 24 22:29:57 2011 +0200

    Fix memory corruption in SourceEditor
    
    	* src/uicommon/nmv-source-editor.cc
    	(SourceEditor::clear_decorations): Don't erase members of a map
    	while iterating over it.

 src/uicommon/nmv-source-editor.cc |   27 +++++++++++++++++++++++----
 1 files changed, 23 insertions(+), 4 deletions(-)
---
diff --git a/src/uicommon/nmv-source-editor.cc b/src/uicommon/nmv-source-editor.cc
index e696476..160af92 100644
--- a/src/uicommon/nmv-source-editor.cc
+++ b/src/uicommon/nmv-source-editor.cc
@@ -940,21 +940,40 @@ SourceEditor::remove_visual_breakpoint_from_line (int a_line)
     return true;
 }
 
+/// Clear decorations from the source editor.  Decorations are
+/// basically the "where-marker" and the breakpoint markers.
 void
 SourceEditor::clear_decorations ()
 {
     std::map<int, Glib::RefPtr<gtksourceview::SourceMark> > *markers;
     if ((markers = m_priv->get_markers ()) == 0)
         return;
-    std::map<int, Glib::RefPtr<gtksourceview::SourceMark> >::iterator it;
+    typedef std::map<int, Glib::RefPtr<gtksourceview::SourceMark> >::iterator
+      SourceMarkMapIter;
 
-    // Clear breakpoint markers
-    for (it = markers->begin (); it != markers->end (); ++it) {
+    SourceMarkMapIter it;
+
+    std::list<SourceMarkMapIter> marks_to_erase;
+
+    // Clear breakpoint markers and erase them from the hash map that
+    // indexes them.
+    for (SourceMarkMapIter it = markers->begin ();
+	 it != markers->end ();
+	 ++it) {
         if (!it->second->get_deleted ()) {
             source_view ().get_source_buffer ()->delete_mark (it->second);
-            markers->erase (it);
+	    // We cannot erase it from its map while walking the map
+	    // at the same time.  So let's record that we want to
+	    // erase it for now.
+	    marks_to_erase.push_front (it);
         }
     }
+    // Now erase all the map members that got marked to be erased in
+    // the loop above.
+    for (std::list<SourceMarkMapIter>::iterator it = marks_to_erase.begin ();
+	 it != marks_to_erase.begin ();
+	 ++it)
+      markers->erase (*it);
 
     unset_where_marker ();
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]