* insdel.c (replace_range): Fix buf overflow when insbytes < outgoing.
[bpt/emacs.git] / src / insdel.c
index 82dce13..ca53177 100644 (file)
@@ -20,6 +20,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <setjmp.h>
+
+#include <intprops.h>
+
 #include "lisp.h"
 #include "intervals.h"
 #include "buffer.h"
@@ -388,6 +391,12 @@ adjust_markers_for_replace (EMACS_INT from, EMACS_INT from_byte,
 }
 
 \f
+void
+buffer_overflow (void)
+{
+  error ("Maximum buffer size exceeded");
+}
+
 /* Make the gap NBYTES_ADDED bytes longer.  */
 
 static void
@@ -404,12 +413,8 @@ make_gap_larger (EMACS_INT nbytes_added)
   { EMACS_INT total_size = Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added;
     if (total_size < 0
        /* Don't allow a buffer size that won't fit in a Lisp integer.  */
-       || total_size != XINT (make_number (total_size))
-       /* Don't allow a buffer size that won't fit in an int
-          even if it will fit in a Lisp integer.
-          That won't work because so many places still use `int'.  */
-       || total_size != (EMACS_INT) (int) total_size)
-      error ("Buffer exceeds maximum size");
+       || total_size != XINT (make_number (total_size)))
+      buffer_overflow ();
   }
 
   enlarge_buffer_text (current_buffer, nbytes_added);
@@ -442,6 +447,7 @@ make_gap_larger (EMACS_INT nbytes_added)
   Vinhibit_quit = tem;
 }
 
+#if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
 
 /* Make the gap NBYTES_REMOVED bytes shorter.  */
 
@@ -501,6 +507,8 @@ make_gap_smaller (EMACS_INT nbytes_removed)
   Vinhibit_quit = tem;
 }
 
+#endif /* USE_MMAP_FOR_BUFFERS || REL_ALLOC || DOUG_LEA_MALLOC */
+
 void
 make_gap (EMACS_INT nbytes_added)
 {
@@ -568,32 +576,6 @@ copy_text (const unsigned char *from_addr, unsigned char *to_addr,
       return to_addr - initial_to_addr;
     }
 }
-
-/* Return the number of bytes it would take
-   to convert some single-byte text to multibyte.
-   The single-byte text consists of NBYTES bytes at PTR.  */
-
-EMACS_INT
-count_size_as_multibyte (const unsigned char *ptr, EMACS_INT nbytes)
-{
-  EMACS_INT i;
-  EMACS_INT outgoing_nbytes = 0;
-
-  for (i = 0; i < nbytes; i++)
-    {
-      unsigned int c = *ptr++;
-
-      if (ASCII_CHAR_P (c))
-       outgoing_nbytes++;
-      else
-       {
-         c = BYTE8_TO_CHAR (c);
-         outgoing_nbytes += CHAR_BYTES (c);
-       }
-    }
-
-  return outgoing_nbytes;
-}
 \f
 /* Insert a string of specified length before point.
    This function judges multibyteness based on
@@ -1129,7 +1111,7 @@ insert_from_buffer_1 (struct buffer *buf,
   /* Make sure point-max won't overflow after this insertion.  */
   XSETINT (temp, outgoing_nbytes + Z);
   if (outgoing_nbytes + Z != XINT (temp))
-    error ("Maximum buffer size exceeded");
+    buffer_overflow ();
 
   /* Do this before moving and increasing the gap,
      because the before-change hooks might move the gap
@@ -1372,9 +1354,9 @@ replace_range (EMACS_INT from, EMACS_INT to, Lisp_Object new,
       = count_size_as_multibyte (SDATA (new), insbytes);
 
   /* Make sure point-max won't overflow after this insertion.  */
-  XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
-  if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
-    error ("Maximum buffer size exceeded");
+  XSETINT (temp, Z_BYTE - nbytes_del + outgoing_insbytes);
+  if (Z_BYTE - nbytes_del + outgoing_insbytes != XINT (temp))
+    buffer_overflow ();
 
   GCPRO1 (new);
 
@@ -1407,8 +1389,8 @@ replace_range (EMACS_INT from, EMACS_INT to, Lisp_Object new,
   if (Z - GPT < END_UNCHANGED)
     END_UNCHANGED = Z - GPT;
 
-  if (GAP_SIZE < insbytes)
-    make_gap (insbytes - GAP_SIZE);
+  if (GAP_SIZE < outgoing_insbytes)
+    make_gap (outgoing_insbytes - GAP_SIZE);
 
   /* Copy the string text into the buffer, perhaps converting
      between single-byte and multibyte.  */
@@ -1519,7 +1501,7 @@ replace_range_2 (EMACS_INT from, EMACS_INT from_byte,
   /* Make sure point-max won't overflow after this insertion.  */
   XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
   if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
-    error ("Maximum buffer size exceeded");
+    buffer_overflow ();
 
   /* Make sure the gap is somewhere in or next to what we are deleting.  */
   if (from > GPT)