Module: wine Branch: master Commit: 10b38faf3adb42273084eb267fba20ab1704af27 URL: http://source.winehq.org/git/wine.git/?a=commit;h=10b38faf3adb42273084eb267f...
Author: Rob Shearman rob@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 */