FIX #1736, and probably #2169, #2240
authorSimon Marlow <marlowsd@gmail.com>
Mon, 7 Jul 2008 09:58:36 +0000 (09:58 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Mon, 7 Jul 2008 09:58:36 +0000 (09:58 +0000)
appendStringBuffer was completely bogus - the arguments to copyArray
were the wrong way around, which meant that corruption was very likely
to occur by overwriting the end of the buffer in the first argument.

This definitely fixes #1736.  The other two bugs, #2169 and #2240 are
harder to reproduce, but we can see how they could occur: in the case
of #2169, the options parser is seeing the contents of an old buffer,
and in the case of #2240, appendStringBuffer is corrupting an
interface file in memory, since strng buffers and interface files are
both allocated in the pinned region of memory.

compiler/utils/StringBuffer.lhs

index a89c0d2..d51c800 100644 (file)
@@ -125,12 +125,14 @@ appendStringBuffers sb1 sb2
          withForeignPtr newBuf $ \ptr ->
           withForeignPtr (buf sb1) $ \sb1Ptr ->
            withForeignPtr (buf sb2) $ \sb2Ptr ->
-             do copyArray (sb1Ptr `advancePtr` cur sb1) ptr (calcLen sb1)
-                copyArray (sb2Ptr `advancePtr` cur sb2) (ptr `advancePtr` cur sb1) (calcLen sb2)
+             do copyArray ptr (sb1Ptr `advancePtr` cur sb1) sb1_len
+                copyArray (ptr `advancePtr` sb1_len) (sb2Ptr `advancePtr` cur sb2) sb2_len
                 pokeArray (ptr `advancePtr` size) [0,0,0]
                 return (StringBuffer newBuf size 0)
-    where calcLen sb = len sb - cur sb
-          size = calcLen sb1 + calcLen sb2
+    where sb1_len = calcLen sb1
+          sb2_len = calcLen sb2
+          calcLen sb = len sb - cur sb
+          size =  sb1_len + sb2_len
 
 stringToStringBuffer :: String -> IO StringBuffer
 stringToStringBuffer str = do