aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2016-04-15 17:26:37 +0300
committerEli Zaretskii2016-04-15 17:26:37 +0300
commitab849b7fac5f7a4bb301eb830fa0acc3ad18c18f (patch)
tree22f4b149211add67e3baf27f62f73bf2890bbf29
parent1b98a68b660501c44d3a142a12ee35e3c215b05a (diff)
downloademacs-ab849b7fac5f7a4bb301eb830fa0acc3ad18c18f.tar.gz
emacs-ab849b7fac5f7a4bb301eb830fa0acc3ad18c18f.zip
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.
-rw-r--r--src/w32heap.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/src/w32heap.c b/src/w32heap.c
index df2fe0a8fa3..6643b439a26 100644
--- a/src/w32heap.c
+++ b/src/w32heap.c
@@ -714,13 +714,12 @@ mmap_realloc (void **var, size_t nbytes)
714 /* If there is enough room in the current reserved area, then 714 /* If there is enough room in the current reserved area, then
715 commit more pages as needed. */ 715 commit more pages as needed. */
716 if (m2.State == MEM_RESERVE 716 if (m2.State == MEM_RESERVE
717 && m2.AllocationBase == memInfo.AllocationBase
717 && nbytes <= memInfo.RegionSize + m2.RegionSize) 718 && nbytes <= memInfo.RegionSize + m2.RegionSize)
718 { 719 {
719 void *p; 720 void *p;
720 721
721 p = VirtualAlloc (*var + memInfo.RegionSize, 722 p = VirtualAlloc (*var, nbytes, MEM_COMMIT, PAGE_READWRITE);
722 nbytes - memInfo.RegionSize,
723 MEM_COMMIT, PAGE_READWRITE);
724 if (!p /* && GetLastError() != ERROR_NOT_ENOUGH_MEMORY */) 723 if (!p /* && GetLastError() != ERROR_NOT_ENOUGH_MEMORY */)
725 { 724 {
726 DebPrint (("realloc enlarge: VirtualAlloc (%p + %I64x, %I64x) error %ld\n", 725 DebPrint (("realloc enlarge: VirtualAlloc (%p + %I64x, %I64x) error %ld\n",
@@ -728,7 +727,8 @@ mmap_realloc (void **var, size_t nbytes)
728 (uint64_t)(nbytes - memInfo.RegionSize), 727 (uint64_t)(nbytes - memInfo.RegionSize),
729 GetLastError ())); 728 GetLastError ()));
730 DebPrint (("next region: %p %p %I64x %x\n", m2.BaseAddress, 729 DebPrint (("next region: %p %p %I64x %x\n", m2.BaseAddress,
731 m2.AllocationBase, m2.RegionSize, m2.AllocationProtect)); 730 m2.AllocationBase, (uint64_t)m2.RegionSize,
731 m2.AllocationProtect));
732 } 732 }
733 else 733 else
734 return *var; 734 return *var;