diff --git a/ChangeLog b/ChangeLog index 6f7b1c38..09314153 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-07-27 Chris Allegretta + * text.c (undo_cut, redo_cut): Don't actually try and undo/redo an empty cut, i.e. the magicline. + Fixes crash on cutting last line discovered by Eitan Adler . + 2009-07-11 Chris Allegretta * nano-regress: Small tweaks * Change undo code to off unless unabled via a command line option (-u/--undo). Until this code diff --git a/src/text.c b/src/text.c index 6c6e64a0..a225eaa1 100644 --- a/src/text.c +++ b/src/text.c @@ -360,21 +360,25 @@ void do_unindent(void) /* undo a cut, or re-do an uncut */ void undo_cut(undo *u) { - cutbuffer = copy_filestruct(u->cutbuffer); + /* If we cut the magicline may was well not crash :/ */ + if (!u->cutbuffer) + return; - /* Compute cutbottom for the uncut using out copy */ - for (cutbottom = cutbuffer; cutbottom->next != NULL; cutbottom = cutbottom->next) - ; + cutbuffer = copy_filestruct(u->cutbuffer); - /* Get to where we need to uncut from */ - if (u->mark_set && u->mark_begin_lineno < u->lineno) - do_gotolinecolumn(u->mark_begin_lineno, u->mark_begin_x+1, FALSE, FALSE, FALSE, FALSE); - else - do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE); + /* Compute cutbottom for the uncut using out copy */ + for (cutbottom = cutbuffer; cutbottom->next != NULL; cutbottom = cutbottom->next) + ; - copy_from_filestruct(cutbuffer, cutbottom); - free_filestruct(cutbuffer); - cutbuffer = NULL; + /* Get to where we need to uncut from */ + if (u->mark_set && u->mark_begin_lineno < u->lineno) + do_gotolinecolumn(u->mark_begin_lineno, u->mark_begin_x+1, FALSE, FALSE, FALSE, FALSE); + else + do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE); + + copy_from_filestruct(cutbuffer, cutbottom); + free_filestruct(cutbuffer); + cutbuffer = NULL; } @@ -383,40 +387,44 @@ void redo_cut(undo *u) { int i; filestruct *t, *c; - do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE); - openfile->mark_set = u->mark_set; - if (cutbuffer) - free(cutbuffer); - cutbuffer = NULL; + /* If we cut the magicline may was well not crash :/ */ + if (!u->cutbuffer) + return; - /* Move ahead the same # lines we had if a marked cut */ - if (u->mark_set) { - for (i = 1, t = openfile->fileage; i != u->mark_begin_lineno; i++) - t = t->next; - openfile->mark_begin = t; - } else if (!u->to_end) { - /* Here we have a regular old potentially multi-line ^K cut. We'll - need to trick nano into thinking it's a marked cut to cut more - than one line again */ - for (c = u->cutbuffer, t = openfile->current; c->next != NULL && t->next != NULL; ) { + do_gotolinecolumn(u->lineno, u->begin+1, FALSE, FALSE, FALSE, FALSE); + openfile->mark_set = u->mark_set; + if (cutbuffer) + free(cutbuffer); + cutbuffer = NULL; + + /* Move ahead the same # lines we had if a marked cut */ + if (u->mark_set) { + for (i = 1, t = openfile->fileage; i != u->mark_begin_lineno; i++) + t = t->next; + openfile->mark_begin = t; + } else if (!u->to_end) { + /* Here we have a regular old potentially multi-line ^K cut. We'll + need to trick nano into thinking it's a marked cut to cut more + than one line again */ + for (c = u->cutbuffer, t = openfile->current; c->next != NULL && t->next != NULL; ) { #ifdef DEBUG - fprintf(stderr, "Advancing, lineno = %d, data = \"%s\"\n", t->lineno, t->data); + fprintf(stderr, "Advancing, lineno = %d, data = \"%s\"\n", t->lineno, t->data); #endif - c = c->next; - t = t->next; - } - openfile->mark_begin = t; - openfile->mark_begin_x = 0; - openfile->mark_set = TRUE; - } + c = c->next; + t = t->next; + } + openfile->mark_begin = t; + openfile->mark_begin_x = 0; + openfile->mark_set = TRUE; + } - openfile->mark_begin_x = u->mark_begin_x; - do_cut_text(FALSE, u->to_end, TRUE); - openfile->mark_set = FALSE; - openfile->mark_begin = NULL; - openfile->mark_begin_x = 0; - edit_refresh_needed = TRUE; + openfile->mark_begin_x = u->mark_begin_x; + do_cut_text(FALSE, u->to_end, TRUE); + openfile->mark_set = FALSE; + openfile->mark_begin = NULL; + openfile->mark_begin_x = 0; + edit_refresh_needed = TRUE; } /* Undo the last thing(s) we did */