Fix out-of-range lineno when reloading the status view
authorJonas Fonseca <fonseca@diku.dk>
Sun, 23 Sep 2007 21:00:45 +0000 (23:00 +0200)
committerJonas Fonseca <fonseca@diku.dk>
Sun, 23 Sep 2007 21:00:45 +0000 (23:00 +0200)
Reproducable when standing on the last line of the status view with no
staged files and pressing 'u' twice. The first will make the current
line point outside the range of lines in the view, making the second
update read garbage memory and calling die because of an unknown status
line ID.

Restore previous line number if possible else move make the current
line index be that of the last line in the updated view.

tig.c

diff --git a/tig.c b/tig.c
index 3811a22..24f84d4 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -3052,12 +3052,14 @@ status_open(struct view *view)
        struct stat statbuf;
        char exclude[SIZEOF_STR];
        char cmd[SIZEOF_STR];
+       unsigned long prev_lineno = view->lineno;
        size_t i;
 
+
        for (i = 0; i < view->lines; i++)
                free(view->line[i].data);
        free(view->line);
-       view->lines = view->line_size = 0;
+       view->lines = view->line_size = view->lineno = 0;
        view->line = NULL;
 
        if (!realloc_lines(view, view->line_size + 6))
@@ -3081,6 +3083,13 @@ status_open(struct view *view)
            !status_run(view, cmd, FALSE, LINE_STAT_UNTRACKED))
                return FALSE;
 
+       /* If all went well restore the previous line number to stay in
+        * the context. */
+       if (prev_lineno < view->lines)
+               view->lineno = prev_lineno;
+       else
+               view->lineno = view->lines - 1;
+
        return TRUE;
 }