Code

Fix memory corruption bug in tree_read when sorting the entries
authorJonas Fonseca <fonseca@diku.dk>
Thu, 15 Jan 2009 14:14:54 +0000 (15:14 +0100)
committerJonas Fonseca <fonseca@diku.dk>
Thu, 15 Jan 2009 15:04:06 +0000 (16:04 +0100)
Triggered by defining ITEM_CHUNK_SIZE to 1.

NEWS
tig.c

diff --git a/NEWS b/NEWS
index 79fe7f2818b3e809c8345c61f92e5cb59cf0b820..4f41bd2ac00344c3da4b14a4c17a74a060119deb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,13 @@
 Release notes
 =============
 
+tig master
+----------
+
+Bug fixes:
+
+ - Tree view: fix memory corruption bug when updating.
+
 tig-0.13
 --------
 
diff --git a/tig.c b/tig.c
index 725bc2eda7da956e0f2d04cf4fa61f628661982b..3df53a49f97591db0634bb1ea6f45ab8bb31858b 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -3614,7 +3614,7 @@ static bool
 tree_read(struct view *view, char *text)
 {
        size_t textlen = text ? strlen(text) : 0;
-       unsigned long pos;
+       size_t pos;
        enum line_type type;
 
        if (!text)
@@ -3645,8 +3645,12 @@ tree_read(struct view *view, char *text)
                        return FALSE;
        }
 
+       if (!add_line_text(view, text, type))
+               return FALSE;
+       text = view->line[view->lines - 1].data;
+
        /* Skip "Directory ..." and ".." line. */
-       for (pos = 1 + !!*opt_path; pos < view->lines; pos++) {
+       for (pos = 1 + !!*opt_path; pos < view->lines - 1; pos++) {
                struct line *line = &view->line[pos];
                const char *path1 = tree_path(line);
                char *path2 = text + SIZEOF_TREE_ATTR;
@@ -3655,24 +3659,16 @@ tree_read(struct view *view, char *text)
                if (cmp <= 0)
                        continue;
 
-               text = strdup(text);
-               if (!text)
-                       return FALSE;
-
-               if (view->lines > pos)
+               if (view->lines - 1 > pos)
                        memmove(&view->line[pos + 1], &view->line[pos],
-                               (view->lines - pos) * sizeof(*line));
+                               (view->lines - 1 - pos) * sizeof(*line));
 
                line = &view->line[pos];
                line->data = text;
                line->type = type;
-               view->lines++;
                return TRUE;
        }
 
-       if (!add_line_text(view, text, type))
-               return FALSE;
-
        if (tree_lineno > view->lineno) {
                view->lineno = tree_lineno;
                tree_lineno = 0;