Index: trunk/src/kernel32/os2heap.cpp
===================================================================
--- trunk/src/kernel32/os2heap.cpp	(revision 7727)
+++ trunk/src/kernel32/os2heap.cpp	(revision 7728)
@@ -1,8 +1,8 @@
-/* $Id: os2heap.cpp,v 1.31 2001-11-16 14:52:55 phaller Exp $ */
+/* $Id: os2heap.cpp,v 1.32 2002-01-06 16:48:47 sandervl Exp $ */
 
 /*
  * Heap class for OS/2
  *
- * Copyright 1998 Sander van Leeuwen
+ * Copyright 1998-2002 Sander van Leeuwen <sandervl@xs4all.nl>
  *
  *
@@ -10,4 +10,10 @@
  *       WINE controls depend on this, even though it apparently
  *       doesn't work like this in Windows.
+ * NOTE: Round up size to next 8 bytes boundary
+ *       When reallocating memory block, don't use different
+ *       memory block unless new size is larger than old size
+ *       (rounded up to next 8 bytes boundary)
+ *       (Verified this behaviour in NT4 (Global/Heap(Re)Alloc); 
+ *        fixes crashes in Opera 5.12 which relies on this 'feature')
  *
  * Project Odin Software License can be found in LICENSE.TXT
@@ -150,7 +156,12 @@
  HEAPELEM *lpHeapObj;
  LPVOID    lpMem;
+ DWORD     dwAllocBytes;
 
 //  dprintf(("OS2Heap::Alloc\n"));
-  lpMem = _umalloc(uheap, dwBytes + HEAP_OVERHEAD);
+
+  //size must be multiple of 8 bytes
+  dwAllocBytes = HEAP_ALIGN(dwBytes);
+
+  lpMem = _umalloc(uheap, dwAllocBytes + HEAP_OVERHEAD);
   if(lpMem == NULL) {
       dprintf(("OS2Heap::Alloc, lpMem == NULL"));
@@ -158,16 +169,18 @@
   }
   if(dwFlags & HEAP_ZERO_MEMORY) {
-      memset(lpMem, 0, dwBytes+HEAP_OVERHEAD);
+      memset(lpMem, 0, dwAllocBytes+HEAP_OVERHEAD);
   }
   
 #ifdef DEBUG
-  totalAlloc += dwBytes;
+  totalAlloc += dwAllocBytes;
 #endif
   
   //align at 8 byte boundary
-  lpHeapObj = (HEAPELEM *)(((ULONG)lpMem+7) & ~7);
-  lpHeapObj->lpMem = lpMem;
+  lpHeapObj          = (HEAPELEM *)HEAP_ALIGN(lpMem);
+  lpHeapObj->lpMem   = lpMem;
   lpHeapObj->magic   = MAGIC_NR_HEAP;
-
+  lpHeapObj->orgsize = dwBytes;	//original size
+  lpHeapObj->cursize = dwBytes;	//original size
+ 
   return(LPVOID)(lpHeapObj+1);
 }
@@ -194,6 +207,5 @@
     	return -1;
   }
-
-  return(_msize(helem->lpMem) - HEAP_OVERHEAD);
+  return helem->cursize;  //return current size of memory block
 }
 //******************************************************************************
@@ -203,5 +215,5 @@
   HEAPELEM *helem = GET_HEAPOBJ(lpMem);
   LPVOID lpNewMem;
-  int    i, oldSize;
+  int    i, maxSize;
 
   if (dwBytes == 0) return NULL;         // intercept stupid parameters
@@ -218,11 +230,13 @@
   }
 
-  oldSize = Size(0,lpMem);
-  if (oldSize >= dwBytes) {
-       dprintf(("ReAlloc with smaller size than original (%d); return old pointer", oldSize));
+  maxSize = HEAP_ALIGN(helem->orgsize); 
+  if (dwBytes <= maxSize) {
+       dprintf(("ReAlloc with smaller size than original (%d); return old pointer", maxSize));
+       //update current size so HeapSize will return the right value
+       helem->cursize = dwBytes;  
        return lpMem; // if reallocation with same size don't do anything
   }
   lpNewMem = Alloc(dwFlags, dwBytes);
-  memcpy(lpNewMem, lpMem, dwBytes < oldSize ? dwBytes : oldSize);
+  memcpy(lpNewMem, lpMem, dwBytes < maxSize ? dwBytes : maxSize);
   Free(0, lpMem);
 
Index: trunk/src/kernel32/os2heap.h
===================================================================
--- trunk/src/kernel32/os2heap.h	(revision 7727)
+++ trunk/src/kernel32/os2heap.h	(revision 7728)
@@ -1,3 +1,3 @@
-/* $Id: os2heap.h,v 1.10 2001-11-16 14:52:56 phaller Exp $ */
+/* $Id: os2heap.h,v 1.11 2002-01-06 16:48:47 sandervl Exp $ */
 
 /*
@@ -19,12 +19,18 @@
 
 #define MAGIC_NR_HEAP  0x87654321
-//must be a multiple of 8 bytes (alignment)
+//must be a multiple of 8 bytes (alignment)!!
 typedef struct _tagHEAPELEM {
   DWORD  magic;     //magic number
   LPVOID lpMem;     //pointer returned by malloc
+  DWORD  cursize;   //current size (HeapReAlloc changes this)
+  DWORD  orgsize;   //size used to allocate this memory block
 } HEAPELEM;
 
-//+8 to make sure we can align the pointer at 8 byte boundary
-#define HEAP_OVERHEAD (sizeof(HEAPELEM)+8)
+#define HEAP_ALIGNMENT		8
+#define HEAP_ALIGNMENT_MASK	(~7)
+
+#define HEAP_OVERHEAD (sizeof(HEAPELEM))
+
+#define HEAP_ALIGN(a)     (((DWORD)a+HEAP_ALIGNMENT-1) & HEAP_ALIGNMENT_MASK)
 
 #define GET_HEAPOBJ(ptr) (HEAPELEM *)((char *)ptr - sizeof(HEAPELEM));
