Code

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 3811a228aebbd6ce018cef41600b22b491acdcd9..24f84d43b07de5a1f3006bd148c1c02e30c3fc08 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;
 }