Dylan Smith : richedit: Fixed Valgrind error related to undoing.

Alexandre Julliard julliard at winehq.org
Mon Jul 7 09:19:23 CDT 2008


Module: wine
Branch: master
Commit: ebded1636b850c3e1f1ef253ebaba6b9f11652da
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ebded1636b850c3e1f1ef253ebaba6b9f11652da

Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date:   Sun Jul  6 15:27:40 2008 -0400

richedit: Fixed Valgrind error related to undoing.

The error was a memory access of a freed object.  In ME_AddUndoItem I
checked the top of the undo stack to end a coalescing undo transaction,
assuming that this should be either a valid undo item, or NULL, instead
it was already freed.

---

 dlls/riched20/undo.c |   37 +++++++++++++++++++------------------
 1 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/dlls/riched20/undo.c b/dlls/riched20/undo.c
index a0fd646..bf992ab 100644
--- a/dlls/riched20/undo.c
+++ b/dlls/riched20/undo.c
@@ -55,13 +55,7 @@ ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_Disp
     return NULL;
   else
   {
-    ME_DisplayItem *pItem;
-    if (editor->pUndoStack
-        && editor->pUndoStack->type == diUndoPotentialEndTransaction)
-    {
-        editor->pUndoStack->type = diUndoEndTransaction;
-    }
-    pItem = (ME_DisplayItem *)ALLOC_OBJ(ME_UndoItem);
+    ME_DisplayItem *pItem = (ME_DisplayItem *)ALLOC_OBJ(ME_UndoItem);
     ((ME_UndoItem *)pItem)->nCR = ((ME_UndoItem *)pItem)->nLF = -1;
     switch(type)
     {
@@ -109,6 +103,11 @@ ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_Disp
     pItem->prev = NULL;
     if (editor->nUndoMode == umAddToUndo || editor->nUndoMode == umAddBackToUndo)
     {
+      if (editor->pUndoStack
+          && editor->pUndoStack->type == diUndoPotentialEndTransaction)
+      {
+          editor->pUndoStack->type = diUndoEndTransaction;
+      }
       if (editor->nUndoMode == umAddToUndo)
         TRACE("Pushing id=%s to undo stack, deleting redo stack\n", ME_GetDITypeName(type));
       else
@@ -355,17 +354,18 @@ BOOL ME_Undo(ME_TextEditor *editor) {
   editor->nUndoMode = umAddToRedo;
   p = editor->pUndoStack->next;
   ME_DestroyDisplayItem(editor->pUndoStack);
+  editor->pUndoStack = p;
   do {
-    ME_DisplayItem *pp = p;
+    p->prev = NULL;
     ME_PlayUndoItem(editor, p);
-    p = p->next;
-    ME_DestroyDisplayItem(pp);
+    editor->pUndoStack = p->next;
+    ME_DestroyDisplayItem(p);
+    p = editor->pUndoStack;
   } while(p && p->type != diUndoEndTransaction);
-  ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
-  editor->pUndoStack = p;
-  editor->nUndoStackSize--;
   if (p)
     p->prev = NULL;
+  ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
+  editor->nUndoStackSize--;
   editor->nUndoMode = nMode;
   ME_UpdateRepaint(editor);
   return TRUE;
@@ -389,16 +389,17 @@ BOOL ME_Redo(ME_TextEditor *editor) {
   editor->nUndoMode = umAddBackToUndo;
   p = editor->pRedoStack->next;
   ME_DestroyDisplayItem(editor->pRedoStack);
+  editor->pRedoStack = p;
   do {
-    ME_DisplayItem *pp = p;
+    p->prev = NULL;
     ME_PlayUndoItem(editor, p);
-    p = p->next;
-    ME_DestroyDisplayItem(pp);
+    editor->pRedoStack = p->next;
+    ME_DestroyDisplayItem(p);
+    p = editor->pRedoStack;
   } while(p && p->type != diUndoEndTransaction);
-  ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
-  editor->pRedoStack = p;
   if (p)
     p->prev = NULL;
+  ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
   editor->nUndoMode = nMode;
   ME_UpdateRepaint(editor);
   return TRUE;




More information about the wine-cvs mailing list