diff --git a/src/cut.c b/src/cut.c
index b56f6d4653711a9fc147472515d6c7f91c8a5a84..5a2ed54060713f8219c82ce0da6a532baaa32b23 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -113,7 +113,7 @@ void cut_to_eof(void)
  * position to the end of the file into the cutbuffer. */
 void do_cut_text(
 #ifndef NANO_TINY
-	bool copy_text, bool cut_till_end
+	bool copy_text, bool cut_till_end, bool undoing
 #else
 	void
 #endif
@@ -204,7 +204,7 @@ void do_cut_text(
 	 * disturbing the text. */
 	if (!old_no_newlines)
 	    UNSET(NO_NEWLINES);
-    } else
+    } else if (!undoing)
 	update_undo(CUT, openfile);
 #endif
 	/* Leave the text in the cutbuffer, and mark the file as
@@ -226,7 +226,7 @@ void do_cut_text_void(void)
     add_undo(CUT, openfile);
     do_cut_text(
 #ifndef NANO_TINY
-	FALSE, FALSE
+	FALSE, FALSE, FALSE
 #endif
 	);
 }
@@ -236,14 +236,14 @@ void do_cut_text_void(void)
  * back into the filestruct afterward. */
 void do_copy_text(void)
 {
-    do_cut_text(TRUE, FALSE);
+    do_cut_text(TRUE, FALSE, FALSE);
 }
 
 /* Cut from the current cursor position to the end of the file. */
 void do_cut_till_end(void)
 {
     add_undo(CUTTOEND, openfile);
-    do_cut_text(FALSE, TRUE);
+    do_cut_text(FALSE, TRUE, FALSE);
 }
 #endif /* !NANO_TINY */
 
diff --git a/src/proto.h b/src/proto.h
index 2d8c34cf7b0ac13af50de6908e3a661767096bd0..0c8d3575b4740302861befaccd3637dc2130d72b 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -239,7 +239,7 @@ void cut_to_eof(void);
 #endif
 void do_cut_text(
 #ifndef NANO_TINY
-	bool copy_text, bool cut_till_end
+	bool copy_text, bool cut_till_end, bool undoing
 #else
 	void
 #endif
diff --git a/src/text.c b/src/text.c
index 2c908f6099a863c1ea683b8e6a00b853019ce66b..a70e10a20e372787beb91742c5e01ded4a0d802f 100644
--- a/src/text.c
+++ b/src/text.c
@@ -554,7 +554,7 @@ void do_redo(void)
 	    openfile->mark_begin = t;
 	}
 	openfile->mark_begin_x = u->mark_begin_x;
-	do_cut_text(FALSE, u->to_end);
+	do_cut_text(FALSE, u->to_end, TRUE);
 	openfile->mark_set = FALSE;
         openfile->mark_begin = NULL;
         openfile->mark_begin_x = 0;
@@ -734,11 +734,17 @@ void add_undo(undo_type current_action, openfilestruct *fs)
     char *data;
 
     /* Blow away the old undo stack if we are starting from the middle */
-    while (fs->undotop != fs->current_undo) {
-	undo *tmp = fs->undotop;
+    while (fs->undotop != NULL && fs->undotop != fs->current_undo) {
+	undo *u2 = fs->undotop;
 	fs->undotop = fs->undotop->next;
-	free(tmp->strdata);
-	free(tmp);
+	if (u2->strdata != NULL)
+	    free(u2->strdata);
+	while (u2->cutbuffer != NULL) {
+	    filestruct *f2 = u2->cutbuffer->next;
+	    u2->cutbuffer = u2->cutbuffer->next;
+	    free(f2);
+	}
+	free(u2);
     }
 
     u->type = current_action;
@@ -747,6 +753,10 @@ void add_undo(undo_type current_action, openfilestruct *fs)
     u->next = fs->undotop;
     fs->undotop = u;
     fs->current_undo = u;
+    u->strdata = NULL;
+    u->cutbuffer = NULL;
+    u->cutbottom  = NULL;
+    u->xflags = 0;
 
     switch (u->type) {
     /* We need to start copying data into the undo buffer or we wont be able
@@ -808,11 +818,17 @@ void update_undo(undo_type action, openfilestruct *fs)
     char *data;
     int len = 0;
 
+
+#ifdef DEBUG
+        fprintf(stderr, "action = %d, fs->last_action = %d,  openfile->current->lineno = %d, fs->current_undo->lineno = %d\n", 
+		action, fs->last_action, openfile->current->lineno,  fs->current_undo->lineno);
+#endif
+
     /* Change to an add if we're not using the same undo struct
        that we should be using */
     if (action != fs->last_action
 	|| (action != CUT && action != CUTTOEND
-	    && openfile->current->lineno != fs->undotop->lineno)) {
+	    && openfile->current->lineno != fs->current_undo->lineno)) {
         add_undo(action, fs);
 	return;
     }