From 40e63d4d1a928f10b44d3df4732579e8c298ea2f Mon Sep 17 00:00:00 2001
From: Joerg Wunsch <j@uriah.heep.sax.de>
Date: Tue, 29 Jul 2008 08:39:15 +0000
Subject: [PATCH] * stk500v2.c (stk600_xprog_paged_write): Fix a fatal
 miscalculation of the number of bytes to be written which caused a malloc
 chunk corruption.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@778 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 avrdude/ChangeLog  |  6 ++++++
 avrdude/stk500v2.c | 18 ++++++++++++++----
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog
index 77176cbe..56113a6e 100644
--- a/avrdude/ChangeLog
+++ b/avrdude/ChangeLog
@@ -1,3 +1,9 @@
+2008-07-29  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	* stk500v2.c (stk600_xprog_paged_write): Fix a fatal miscalculation
+	of the number of bytes to be written which caused a malloc chunk
+	corruption.
+
 2008-07-27  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	First implementation of ATxmega support.  By now, only the
diff --git a/avrdude/stk500v2.c b/avrdude/stk500v2.c
index f4d1fa3d..d2ef6473 100644
--- a/avrdude/stk500v2.c
+++ b/avrdude/stk500v2.c
@@ -3187,6 +3187,7 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     unsigned int offset;
     unsigned char memtype;
     int n_bytes_orig = n_bytes;
+    size_t writesize;
 
     /*
      * The XPROG read command supports at most 256 bytes in one
@@ -3249,7 +3250,12 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 	    }
 	    unsigned int chunk;
 	    for (chunk = 0; chunk < page_size; chunk += 256) {
-		memset(b + 9, 0xff, 256);
+                if (n_bytes < 256) {
+                    memset(b + 9 + n_bytes, 0xff, 256 - n_bytes);
+                    writesize = n_bytes;
+                } else {
+                    writesize = 256;
+                }
 		b[0] = XPRG_CMD_WRITE_MEM;
 		b[1] = memtype;
 		if (chunk + 256 == page_size) {
@@ -3263,7 +3269,7 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 		b[6] = addr;
 		b[7] = 1;
 		b[8] = 0;
-		memcpy(b + 9, mem->buf + offset, n_bytes);
+		memcpy(b + 9, mem->buf + offset, writesize);
 		if (stk600_xprog_command(pgm, b, 256 + 9, 2) < 0) {
 		    fprintf(stderr,
 			    "%s: stk600_xprog_paged_write(): XPRG_CMD_WRITE_MEM failed\n",
@@ -3278,12 +3284,16 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 		n_bytes -= 256;
 	    }
 	} else {
-	    if (n_bytes < page_size)
+	    if (n_bytes < page_size) {
 		/*
 		 * This can easily happen if the input file was not a
 		 * multiple of the page size.
 		 */
 		memset(b + 9 + n_bytes, 0xff, page_size - n_bytes);
+                writesize = n_bytes;
+            } else {
+                writesize = page_size;
+            }
 	    b[0] = XPRG_CMD_WRITE_MEM;
 	    b[1] = memtype;
 	    b[2] = 3;		/* erase page | write page */
@@ -3293,7 +3303,7 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 	    b[6] = addr;
 	    b[7] = page_size >> 8;
 	    b[8] = page_size;
-	    memcpy(b + 9, mem->buf + offset, n_bytes);
+	    memcpy(b + 9, mem->buf + offset, writesize);
 	    if (stk600_xprog_command(pgm, b, page_size + 9, 2) < 0) {
 		fprintf(stderr,
 			"%s: stk600_xprog_paged_write(): XPRG_CMD_WRITE_MEM failed\n",