truncate our llist w/ null during rewind.



git-svn-id: http://skia.googlecode.com/svn/trunk@5375 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkWriter32.cpp b/src/core/SkWriter32.cpp
index d2c8587..3ae6a07 100644
--- a/src/core/SkWriter32.cpp
+++ b/src/core/SkWriter32.cpp
@@ -161,6 +161,9 @@
 }
 
 void SkWriter32::rewindToOffset(size_t offset) {
+    if (offset >= fSize) {
+        return;
+    }
     if (0 == offset) {
         this->reset(NULL, 0);
         return;
@@ -179,19 +182,20 @@
     // Similar to peek32, except that we free up any following blocks
     Block* block = fHead;
     SkASSERT(NULL != block);
-
     while (offset >= block->fAllocatedSoFar) {
         offset -= block->fAllocatedSoFar;
         block = block->fNext;
         SkASSERT(NULL != block);
     }
 
-    fTail = block;
+    // update the size on the "last" block
     block->fAllocatedSoFar = offset;
-
-    // free up any following blocks
-    SkASSERT(block);
-    block = block->fNext;
+    // end our list
+    fTail = block;
+    Block* next = block->fNext;
+    block->fNext = NULL;
+    // free up any trailing blocks
+    block = next;
     while (block) {
         Block* next = block->fNext;
         sk_free(block);
diff --git a/tests/Writer32Test.cpp b/tests/Writer32Test.cpp
index 21c11c1..4715f7a 100644
--- a/tests/Writer32Test.cpp
+++ b/tests/Writer32Test.cpp
@@ -37,6 +37,20 @@
     REPORTER_ASSERT(reporter, sizeof(array) == writer.bytesWritten());
     array[2] = 3;
     check_contents(reporter, writer, array, sizeof(array));
+
+    // test rewinding past allocated chunks. This used to crash because we
+    // didn't truncate our link-list after freeing trailing blocks
+    {
+        SkWriter32 writer(64);
+        for (int i = 0; i < 100; ++i) {
+            writer.writeInt(i);
+        }
+        REPORTER_ASSERT(reporter, 100*4 == writer.bytesWritten());
+        for (int j = 100*4; j >= 0; j -= 16) {
+            writer.rewindToOffset(j);
+        }
+        REPORTER_ASSERT(reporter, writer.bytesWritten() < 16);
+    }
 }
 
 static void test_ptr(skiatest::Reporter* reporter) {