]> git.neil.brown.name Git - wiggle.git/commitdiff
vpatch: fix various reference errors found by valgrind.
authorNeilBrown <neilb@suse.de>
Tue, 12 Feb 2013 03:47:51 +0000 (14:47 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 12 Feb 2013 03:47:51 +0000 (14:47 +1100)
We sometimes fall of the end, or the start, of various arrays,
or use variables we haven't initialised.

Reported-by: Paul Wise <pabs3@bonedaddy.net>
Signed-off-by: NeilBrown <neilb@suse.de>
load.c
vpatch.c

diff --git a/load.c b/load.c
index 90ca1af8addb33e318af833574cd81a1b1f47735..2dfa846beadd0ee891db712ab8e12d643bd901a7 100644 (file)
--- a/load.c
+++ b/load.c
@@ -111,10 +111,12 @@ struct stream load_segment(FILE *f,
 {
        struct stream s;
        s.len = end - start;
-       s.body = xmalloc(s.len);
+       s.body = xmalloc(s.len+1);
        fseek(f, start, 0);
        if (fread(s.body, 1, s.len, f) != (size_t)s.len)
                die();
+       /* ensure string is 'nul' terminated - for sscanf */
+       s.body[s.len] = 0;
        return s;
 }
 
index 3bdf46dd580c57d577c31802ca641513b55eecbd..5a947dc524865987738aa2857306ab5eb4424a78 100644 (file)
--- a/vpatch.c
+++ b/vpatch.c
@@ -408,7 +408,7 @@ static struct elmnt next_melmnt(struct mp *pos,
                                struct merge *m)
 {
        pos->o++;
-       while (1) {
+       while (pos->m < 0 || m[pos->m].type != End) {
                int l = 0; /* Length remaining in current merge section */
                if (pos->m >= 0)
                        switch (pos->s) {
@@ -460,7 +460,8 @@ static struct elmnt prev_melmnt(struct mp *pos,
                                struct merge *m)
 {
        if (pos->s == 0) {
-               if (ends_mline(fm.list[m[pos->m].a + pos->o]))
+               if (m[pos->m].a + pos->o < fm.elcnt &&
+                   ends_mline(fm.list[m[pos->m].a + pos->o]))
                        pos->lineno--;
                if (pos->lineno & 1)
                        pos->lineno--;
@@ -509,12 +510,16 @@ static struct elmnt prev_melmnt(struct mp *pos,
  */
 static int visible(int mode, struct merge *m, struct mpos *pos)
 {
-       enum mergetype type = m[pos->p.m].type;
+       enum mergetype type;
        int stream = pos->p.s;
        unsigned int ignore;
 
        if (mode == 0)
                return -1;
+       if (pos->p.m < 0)
+               type = End;
+       else
+               type = m[pos->p.m].type;
        /* mode can be any combination of ORIG RESULT BEFORE AFTER */
        switch (type) {
        case End: /* The END is always visible */
@@ -603,6 +608,8 @@ static int check_line(struct mpos pos, struct file fm, struct file fb,
        struct elmnt e;
        int unmatched = 0;
 
+       if (pos.p.m < 0)
+               return 0;
        do {
                if (m[pos.p.m].type == Changed && !m[pos.p.m].ignored)
                        rv |= CHANGES;
@@ -626,7 +633,10 @@ static int check_line(struct mpos pos, struct file fm, struct file fb,
                                rv |= WIGGLED;
                } else if (m[pos.p.m].type == Unmatched)
                        unmatched = 1;
+
                if (m[pos.p.m].in_conflict &&
+                   ((m[pos.p.m].type == Changed && !m[pos.p.m].ignored) ||
+                    m[pos.p.m].type == Unchanged) &&
                    (pos.p.o < m[pos.p.m].lo ||
                     pos.p.o > m[pos.p.m].hi))
                        rv |= CONFLICTED | CHANGES;
@@ -2671,7 +2681,8 @@ static void main_window(struct plist *pl, int *np, FILE *f, int reverse,
                                sprintf(saveall_buf, saveall_msg,
                                        cnt, cnt == 1 ? "" : "s", cnt+any);
                                ans = help_window(saveall_query, NULL, 1);
-                       }
+                       } else
+                               ans = 0;
                        if (ans < 0)
                                break;
                        if (ans) {