GNU bug report logs - #31888
27.0.50; Segmentation fault in replace-buffer-contents

Previous Next

Package: emacs;

Reported by: MichaƂ Kondraciuk <k.michal <at> zoho.com>

Date: Mon, 18 Jun 2018 21:00:04 UTC

Severity: normal

Found in version 27.0.50

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
Cc: acm <at> muc.de, k.michal <at> zoho.com, joaotavora <at> gmail.com, 31888 <at> debbugs.gnu.org
Subject: bug#31888: 27.0.50; Segmentation fault in replace-buffer-contents
Date: Sat, 30 Jun 2018 10:44:06 +0300
> From: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
> Cc: joaotavora <at> gmail.com, 31888 <at> debbugs.gnu.org, k.michal <at> zoho.com, acm <at> muc.de
> Date: Fri, 29 Jun 2018 16:40:15 -0400
> 
> IIUC replace-buffer-contents is meant to be used in cases where there's
> a good probability that the old and new contents are almost identical,
> save for a few details here and there.
> 
> So, it may very well be the case that out of the 1MB that is covered by
> BEGV..ZV only 10bytes in the middle were deleted/inserted/modified, in
> which case running a-c-f on those 10bytes will likely lead to
> a significantly more efficient recomputation for things like font-lock.
> 
> This refinement is not indispensable, but we make this effort in pretty
> much every other similar circumstance.  It's usually fairly easy/cheap
> to provide those tighter bounds.

Sigh.  Does the below look reasonable?

diff --git a/src/editfns.c b/src/editfns.c
index 4d3c838..9002211 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3238,9 +3238,21 @@ differences between the two buffers.  */)
      Instead, we announce a single modification for the entire
      modified region.  But don't do that if the caller inhibited
      modification hooks, because then they don't want that.  */
+  ptrdiff_t from, to;
   if (!inhibit_modification_hooks)
     {
-      prepare_to_modify_buffer (BEGV, ZV, NULL);
+      ptrdiff_t k, l;
+
+      /* Find the first character position to be changed.  */
+      for (k = 0; k < size_a && !bit_is_set (ctx.deletions, k); k++)
+	;
+      from = BEGV + k;
+
+      /* Find the last character position to be changed.  */
+      for (l = size_a; l > 0 && !bit_is_set (ctx.deletions, l - 1); l--)
+	;
+      to = BEGV + l;
+      prepare_to_modify_buffer (from, to, NULL);
       specbind (Qinhibit_modification_hooks, Qt);
       modification_hooks_inhibited = true;
     }
@@ -3293,8 +3305,9 @@ differences between the two buffers.  */)
 
   if (modification_hooks_inhibited)
     {
-      signal_after_change (BEGV, size_a, ZV - BEGV);
-      update_compositions (BEGV, ZV, CHECK_BORDER);
+      ptrdiff_t updated_to = to + ZV - BEGV - size_a;
+      signal_after_change (from, to - from, updated_to - from);
+      update_compositions (from, updated_to, CHECK_INSIDE);
     }
 
   return Qnil;




This bug report was last modified 6 years and 325 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.