From ab849b7fac5f7a4bb301eb830fa0acc3ad18c18f Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 15 Apr 2016 17:26:37 +0300 Subject: [PATCH 1/1] Fix w32 memory-management problem when extending buffer text * src/w32heap.c (mmap_realloc): Only attempt extending a region if the following region has the same allocation base. Also, use the original allocation base and enlarged size to commit reserved memory, to ensure that the allocation base stays at its original value. This fixes several hard-to-debug problems whereby part of buffer text was overwritten with binary nulls, because mmap_realloc copied only part of buffer text when extending it. See http://lists.gnu.org/archive/html/emacs-devel/2016-04/msg00325.html and http://debbugs.gnu.org/cgi/bugreport.cgi?bug=23223#55 for two examples of the related problems. --- src/w32heap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/w32heap.c b/src/w32heap.c index df2fe0a8fa..6643b439a2 100644 --- a/src/w32heap.c +++ b/src/w32heap.c @@ -714,13 +714,12 @@ mmap_realloc (void **var, size_t nbytes) /* If there is enough room in the current reserved area, then commit more pages as needed. */ if (m2.State == MEM_RESERVE + && m2.AllocationBase == memInfo.AllocationBase && nbytes <= memInfo.RegionSize + m2.RegionSize) { void *p; - p = VirtualAlloc (*var + memInfo.RegionSize, - nbytes - memInfo.RegionSize, - MEM_COMMIT, PAGE_READWRITE); + p = VirtualAlloc (*var, nbytes, MEM_COMMIT, PAGE_READWRITE); if (!p /* && GetLastError() != ERROR_NOT_ENOUGH_MEMORY */) { DebPrint (("realloc enlarge: VirtualAlloc (%p + %I64x, %I64x) error %ld\n", @@ -728,7 +727,8 @@ mmap_realloc (void **var, size_t nbytes) (uint64_t)(nbytes - memInfo.RegionSize), GetLastError ())); DebPrint (("next region: %p %p %I64x %x\n", m2.BaseAddress, - m2.AllocationBase, m2.RegionSize, m2.AllocationProtect)); + m2.AllocationBase, (uint64_t)m2.RegionSize, + m2.AllocationProtect)); } else return *var; -- 2.39.2