Rob Shearman : ntdll: Fix the use of oldSize in RtlReAllocateHeap as both the size of the old block and the number of bytes used in the old block .

Alexandre Julliard julliard at winehq.org
Thu Feb 21 07:42:40 CST 2008


Module: wine
Branch: master
Commit: 10b38faf3adb42273084eb267fba20ab1704af27
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=10b38faf3adb42273084eb267fba20ab1704af27

Author: Rob Shearman <rob at codeweavers.com>
Date:   Wed Feb 20 12:56:59 2008 +0000

ntdll: Fix the use of oldSize in RtlReAllocateHeap as both the size of the old block and the number of bytes used in the old block.

---

 dlls/ntdll/heap.c |   28 +++++++++++++++-------------
 1 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 57ae2cb..ce95c5d 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -1323,7 +1323,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
     ARENA_INUSE *pArena;
     HEAP *heapPtr;
     SUBHEAP *subheap;
-    SIZE_T oldSize, rounded_size;
+    SIZE_T oldBlockSize, oldActualSize, rounded_size;
 
     if (!ptr) return NULL;
     if (!(heapPtr = HEAP_GetPtr( heap )))
@@ -1355,13 +1355,14 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
 
     /* Check if we need to grow the block */
 
-    oldSize = (pArena->size & ARENA_SIZE_MASK);
-    if (rounded_size > oldSize)
+    oldBlockSize = (pArena->size & ARENA_SIZE_MASK);
+    oldActualSize = (pArena->size & ARENA_SIZE_MASK) - pArena->unused_bytes;
+    if (rounded_size > oldBlockSize)
     {
-        char *pNext = (char *)(pArena + 1) + oldSize;
+        char *pNext = (char *)(pArena + 1) + oldBlockSize;
         if ((pNext < (char *)subheap->base + subheap->size) &&
             (*(DWORD *)pNext & ARENA_FLAG_FREE) &&
-            (oldSize + (*(DWORD *)pNext & ARENA_SIZE_MASK) + sizeof(ARENA_FREE) >= rounded_size))
+            (oldBlockSize + (*(DWORD *)pNext & ARENA_SIZE_MASK) + sizeof(ARENA_FREE) >= rounded_size))
         {
             /* The next block is free and large enough */
             ARENA_FREE *pFree = (ARENA_FREE *)pNext;
@@ -1378,7 +1379,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
             HEAP_ShrinkBlock( subheap, pArena, rounded_size );
             notify_alloc( pArena + 1, size, FALSE );
             /* FIXME: this is wrong as we may lose old VBits settings */
-            mark_block_initialized( pArena + 1, oldSize );
+            mark_block_initialized( pArena + 1, oldActualSize );
         }
         else  /* Do it the hard way */
         {
@@ -1403,9 +1404,10 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
                            + sizeof(ARENA_FREE) - sizeof(ARENA_INUSE);
             pInUse->magic = ARENA_INUSE_MAGIC;
             HEAP_ShrinkBlock( newsubheap, pInUse, rounded_size );
-            mark_block_initialized( pInUse + 1, oldSize );
+
+            mark_block_initialized( pInUse + 1, oldActualSize );
             notify_alloc( pInUse + 1, size, FALSE );
-            memcpy( pInUse + 1, pArena + 1, oldSize );
+            memcpy( pInUse + 1, pArena + 1, oldActualSize );
 
             /* Free the previous block */
 
@@ -1429,14 +1431,14 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
 
     /* Clear the extra bytes if needed */
 
-    if (rounded_size > oldSize)
+    if ((pArena->size & ARENA_SIZE_MASK) > oldActualSize)
     {
         if (flags & HEAP_ZERO_MEMORY)
-            clear_block( (char *)(pArena + 1) + oldSize,
-                         (pArena->size & ARENA_SIZE_MASK) - oldSize );
+            clear_block( (char *)(pArena + 1) + oldActualSize,
+                         (pArena->size & ARENA_SIZE_MASK) - oldActualSize );
         else
-            mark_block_uninitialized( (char *)(pArena + 1) + oldSize,
-                                      (pArena->size & ARENA_SIZE_MASK) - oldSize );
+            mark_block_uninitialized( (char *)(pArena + 1) + oldActualSize,
+                                      (pArena->size & ARENA_SIZE_MASK) - oldActualSize );
     }
 
     /* Return the new arena */




More information about the wine-cvs mailing list