diff --git a/src/ChangeLog b/src/ChangeLog
index dcfdf9b406c5cc780c0689f6392c1985301fdf6d..a06c09837c5fdeede4d268659d1865100d8e0a04 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2010-10-21  Larry Jones  <lawrence.jones@siemens.com>
+
+	* rcs.c (apply_rcs_changes): Correct deltatext position sanity
+	checks.  Keep lines in sync so that linevector_free() doesn't
+	try to free garbage.
+
 2010-04-08  Larry Jones  <lawrence.jones@siemens.com>
 
 	* myndbm.c (mydbm_load_file): Initialize line_size.
diff --git a/src/rcs.c b/src/rcs.c
index a23403e4cfff98f1e185d0fa9c2cd5c972b18b9e..b68d9f1bce9d528f7f5ac98923dfedc43676ffd2 100644
--- a/src/rcs.c
+++ b/src/rcs.c
@@ -7467,7 +7467,7 @@ apply_rcs_changes (struct linevector *orig_lines, const char *diffbuf,
     struct deltafrag *dfhead;
     struct deltafrag **dftail;
     struct deltafrag *df;
-    unsigned long numlines, lastmodline, offset;
+    unsigned long numlines, offset;
     struct linevector lines;
     int err;
 
@@ -7541,12 +7541,12 @@ apply_rcs_changes (struct linevector *orig_lines, const char *diffbuf,
 
     /* 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 = xnmalloc (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 */
@@ -7555,25 +7555,24 @@ apply_rcs_changes (struct linevector *orig_lines, const char *diffbuf,
     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)
@@ -7585,7 +7584,12 @@ apply_rcs_changes (struct linevector *orig_lines, const char *diffbuf,
 		    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;
@@ -7610,8 +7614,7 @@ apply_rcs_changes (struct linevector *orig_lines, const char *diffbuf,
 			    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;
@@ -7625,11 +7628,11 @@ apply_rcs_changes (struct linevector *orig_lines, const char *diffbuf,
 		    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;
 		}
 
@@ -7640,14 +7643,20 @@ apply_rcs_changes (struct linevector *orig_lines, const char *diffbuf,
 		    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;
 	    }
 	}
@@ -7667,21 +7676,20 @@ apply_rcs_changes (struct linevector *orig_lines, const char *diffbuf,
     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;