--- src/rcs.c 2008/05/07 15:34:16 1.262.4.65 +++ src/rcs.c 2010/10/21 13:24:15 1.262.4.66 @@ -7128,7 +7128,7 @@ struct deltafrag *dfhead; struct deltafrag **dftail; struct deltafrag *df; - unsigned long numlines, lastmodline, offset; + unsigned long numlines, offset; struct linevector lines; int err; @@ -7202,12 +7202,12 @@ /* New temp data structure to hold new org before copy back into original structure. */ - lines.nlines = lines.lines_alloced = numlines; + lines.lines_alloced = numlines; lines.vector = xmalloc (numlines * sizeof *lines.vector); /* We changed the list order to first to last -- so the list never gets larger than the size numlines. */ - lastmodline = 0; + lines.nlines = 0; /* offset created when adding/removing lines between new and original structure */ @@ -7216,25 +7216,24 @@ for (df = dfhead; df != NULL; ) { unsigned int ln; - unsigned long deltaend; + unsigned long newpos = df->pos - offset; - if (df->pos > orig_lines->nlines) + if (newpos < lines.nlines || newpos > numlines) err = 1; /* On error, just free the rest of the list. */ if (!err) { - /* Here we need to get to the line where the next insert will + /* Here we need to get to the line where the next change will begin, which is DF->pos in ORIG_LINES. We will fill up to DF->pos - OFFSET in LINES with original items. */ - for (deltaend = df->pos - offset; - lastmodline < deltaend; - lastmodline++) + while (lines.nlines < newpos) { /* we need to copy from the orig structure into new one */ - lines.vector[lastmodline] = - orig_lines->vector[lastmodline + offset]; - lines.vector[lastmodline]->refcount++; + lines.vector[lines.nlines] = + orig_lines->vector[lines.nlines + offset]; + lines.vector[lines.nlines]->refcount++; + lines.nlines++; } switch (df->type) @@ -7246,7 +7245,12 @@ struct line *q; int nextline_newline; size_t nextline_len; - + + if (newpos + df->nlines > numlines) + { + err = 1; + break; + } textend = df->new_lines + df->len; nextline_newline = 0; nextline_text = df->new_lines; @@ -7271,8 +7275,7 @@ q->has_newline = nextline_newline; q->refcount = 1; memcpy (q->text, nextline_text, nextline_len); - lines.vector[lastmodline++] = q; - offset--; + lines.vector[lines.nlines++] = q; nextline_text = (char *)p + 1; nextline_newline = 0; @@ -7286,11 +7289,11 @@ q->has_newline = nextline_newline; q->refcount = 1; memcpy (q->text, nextline_text, nextline_len); - lines.vector[lastmodline++] = q; + lines.vector[lines.nlines++] = q; /* For each line we add the offset between the #'s decreases. */ - offset--; + offset -= df->nlines; break; } @@ -7301,14 +7304,20 @@ if (df->pos + df->nlines > orig_lines->nlines) err = 1; else if (delvers) + { for (ln = df->pos; ln < df->pos + df->nlines; ++ln) + { if (orig_lines->vector[ln]->refcount > 1) + { /* Annotate needs this but, since the original * vector is disposed of before returning from * this function, we only need keep track if * there are multiple references. */ orig_lines->vector[ln]->vers = delvers; + } + } + } break; } } @@ -7328,21 +7337,20 @@ else { /* add the rest of the remaining lines to the data vector */ - for (; lastmodline < numlines; lastmodline++) + while (lines.nlines < numlines) { /* we need to copy from the orig structure into new one */ - lines.vector[lastmodline] = orig_lines->vector[lastmodline + lines.vector[lines.nlines] = orig_lines->vector[lines.nlines + offset]; - lines.vector[lastmodline]->refcount++; + lines.vector[lines.nlines]->refcount++; + lines.nlines++; } /* Move the lines vector to the original structure for output, * first deleting the old. */ linevector_free (orig_lines); - orig_lines->vector = lines.vector; - orig_lines->lines_alloced = numlines; - orig_lines->nlines = lines.nlines; + *orig_lines = lines; } return !err;