emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r104686: Merge: Integer and buffer ov


From: Paul Eggert
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r104686: Merge: Integer and buffer overflow fixes.
Date: Thu, 23 Jun 2011 00:51:45 -0700
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 104686 [merge]
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Thu 2011-06-23 00:51:45 -0700
message:
  Merge: Integer and buffer overflow fixes.
modified:
  src/ChangeLog
  src/image.c
  src/keyboard.h
  src/lisp.h
  src/lread.c
  src/macros.c
  src/minibuf.c
  src/print.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-06-23 03:35:05 +0000
+++ b/src/ChangeLog     2011-06-23 07:37:31 +0000
@@ -1,3 +1,49 @@
+2011-06-23  Paul Eggert  <address@hidden>
+
+       Integer and buffer overflow fixes (Bug#8873).
+
+       * print.c (printchar, strout): Check for string overflow.
+       (PRINTPREPARE, printchar, strout):
+       Don't set size unless allocation succeeds.
+
+       * minibuf.c (read_minibuf_noninteractive): Use ptrdiff_t, not int,
+       for sizes.  Check for string overflow more accurately.
+       Simplify newline removal at end; this suppresses a GCC 4.6.0 warning.
+
+       * macros.c: Integer and buffer overflow fixes.
+       * keyboard.h (struct keyboard.kbd_macro_bufsize):
+       * macros.c (Fstart_kbd_macro, store_kbd_macro_char):
+       Use ptrdiff_t, not int, for sizes.
+       Don't increment bufsize until after realloc succeeds.
+       Check for size-calculation overflow.
+       (Fstart_kbd_macro): Use EMACS_INT, not int, for XINT result.
+
+       * lisp.h (DEFVAR_KBOARD): Use offsetof instead of char * finagling.
+
+       * lread.c: Integer overflow fixes.
+       (read_integer): Radix is now EMACS_INT, not int,
+       to improve quality of diagnostics for out-of-range radices.
+       Calculate buffer size correctly for out-of-range radices.
+       (read1): Check for integer overflow in radices, and in
+       read-circle numbers.
+       (read_escape): Avoid int overflow.
+       (Fload, openp, read_buffer_size, read1)
+       (substitute_object_recurse, read_vector, read_list, map_obarray):
+       Use ptrdiff_t, not int, for sizes.
+       (read1): Use EMACS_INT, not int, for sizes.
+       Check for size overflow.
+
+       * image.c (cache_image): Check for size arithmetic overflow.
+
+       * lread.c: Integer overflow issues.
+       (saved_doc_string_size, saved_doc_string_length)
+       (prev_saved_doc_string_size, prev_saved_doc_string_length):
+       Now ptrdiff_t, not int.
+       (read1): Don't assume doc string length fits in int.  Check for
+       out-of-range doc string lengths.
+       (read_list): Don't assume file position fits in int.
+       (read_escape): Check for hex character overflow.
+
 2011-06-22  Leo Liu  <address@hidden>
 
        * minibuf.c (Fcompleting_read_default, Vcompleting_read_function):

=== modified file 'src/image.c'
--- a/src/image.c       2011-06-22 16:01:00 +0000
+++ b/src/image.c       2011-06-23 00:46:41 +0000
@@ -1836,6 +1836,8 @@
   /* If no free slot found, maybe enlarge c->images.  */
   if (i == c->used && c->used == c->size)
     {
+      if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size)
+       memory_full (SIZE_MAX);
       c->size *= 2;
       c->images = (struct image **) xrealloc (c->images,
                                              c->size * sizeof *c->images);

=== modified file 'src/keyboard.h'
--- a/src/keyboard.h    2011-06-11 21:31:32 +0000
+++ b/src/keyboard.h    2011-06-23 06:31:41 +0000
@@ -123,7 +123,7 @@
     Lisp_Object *kbd_macro_end;
 
     /* Allocated size of kbd_macro_buffer.  */
-    int kbd_macro_bufsize;
+    ptrdiff_t kbd_macro_bufsize;
 
     /* Last anonymous kbd macro defined.  */
     Lisp_Object KBOARD_INTERNAL_FIELD (Vlast_kbd_macro);

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2011-06-22 06:16:16 +0000
+++ b/src/lisp.h        2011-06-23 05:35:51 +0000
@@ -1980,10 +1980,7 @@
 #define DEFVAR_KBOARD(lname, vname, doc)                       \
   do {                                                         \
     static struct Lisp_Kboard_Objfwd ko_fwd;                   \
-    defvar_kboard (&ko_fwd,                                    \
-                  lname,                                       \
-                  (int)((char *)(&current_kboard->vname ## _)  \
-                        - (char *)current_kboard));            \
+    defvar_kboard (&ko_fwd, lname, offsetof (KBOARD, vname ## _)); \
   } while (0)
 
 

=== modified file 'src/lread.c'
--- a/src/lread.c       2011-06-20 06:11:36 +0000
+++ b/src/lread.c       2011-06-23 05:41:40 +0000
@@ -120,9 +120,9 @@
 /* This contains the last string skipped with address@hidden  */
 static char *saved_doc_string;
 /* Length of buffer allocated in saved_doc_string.  */
-static int saved_doc_string_size;
+static ptrdiff_t saved_doc_string_size;
 /* Length of actual data in saved_doc_string.  */
-static int saved_doc_string_length;
+static ptrdiff_t saved_doc_string_length;
 /* This is the file position that string came from.  */
 static file_offset saved_doc_string_position;
 
@@ -131,9 +131,9 @@
    is put in saved_doc_string.  */
 static char *prev_saved_doc_string;
 /* Length of buffer allocated in prev_saved_doc_string.  */
-static int prev_saved_doc_string_size;
+static ptrdiff_t prev_saved_doc_string_size;
 /* Length of actual data in prev_saved_doc_string.  */
-static int prev_saved_doc_string_length;
+static ptrdiff_t prev_saved_doc_string_length;
 /* This is the file position that string came from.  */
 static file_offset prev_saved_doc_string_position;
 
@@ -1069,9 +1069,9 @@
 
   /* Avoid weird lossage with null string as arg,
      since it would try to load a directory as a Lisp file */
-  if (SCHARS (file) > 0)
+  if (SBYTES (file) > 0)
     {
-      int size = SBYTES (file);
+      ptrdiff_t size = SBYTES (file);
 
       found = Qnil;
       GCPRO2 (file, found);
@@ -1472,7 +1472,7 @@
       for (tail = NILP (suffixes) ? Fcons (empty_unibyte_string, Qnil) : 
suffixes;
           CONSP (tail); tail = XCDR (tail))
        {
-         int lsuffix = SBYTES (XCAR (tail));
+         ptrdiff_t lsuffix = SBYTES (XCAR (tail));
          Lisp_Object handler;
          int exists;
 
@@ -2037,7 +2037,7 @@
            Fmake_string (make_number (1), make_number (c)));
 }
 
-static int read_buffer_size;
+static ptrdiff_t read_buffer_size;
 static char *read_buffer;
 
 /* Read a \-escape sequence, assuming we already read the `\'.
@@ -2208,7 +2208,9 @@
                UNREAD (c);
                break;
              }
-           count++;
+           if (MAX_CHAR < i)
+             error ("Hex character out of range: \\x%x...", i);
+           count += count < 3;
          }
 
        if (count < 3 && i >= 0x80)
@@ -2236,10 +2238,7 @@
            else if (c >= 'a' && c <= 'f')  i = (i << 4) + (c - 'a') + 10;
             else if (c >= 'A' && c <= 'F')  i = (i << 4) + (c - 'A') + 10;
            else
-             {
-               error ("Non-hex digit used for Unicode escape");
-               break;
-             }
+             error ("Non-hex digit used for Unicode escape");
          }
        if (i > 0x10FFFF)
          error ("Non-Unicode character: 0x%x", i);
@@ -2278,10 +2277,12 @@
    range.  */
 
 static Lisp_Object
-read_integer (Lisp_Object readcharfun, int radix)
+read_integer (Lisp_Object readcharfun, EMACS_INT radix)
 {
-  /* Room for sign, leading 0, other digits, trailing null byte.  */
-  char buf[1 + 1 + sizeof (uintmax_t) * CHAR_BIT + 1];
+  /* Room for sign, leading 0, other digits, trailing null byte.
+     Also, room for invalid syntax diagnostic.  */
+  char buf[max (1 + 1 + sizeof (uintmax_t) * CHAR_BIT + 1,
+               sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT))];
 
   int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete.  */
 
@@ -2333,7 +2334,7 @@
 
   if (! valid)
     {
-      sprintf (buf, "integer, radix %d", radix);
+      sprintf (buf, "integer, radix %"pI"d", radix);
       invalid_syntax (buf);
     }
 
@@ -2471,7 +2472,7 @@
              if (c == '[')
                {
                  Lisp_Object tmp;
-                 int depth, size;
+                 EMACS_INT depth, size;
 
                  tmp = read_vector (readcharfun, 0);
                  if (!INTEGERP (AREF (tmp, 0)))
@@ -2497,7 +2498,7 @@
          if (c == '"')
            {
              Lisp_Object tmp, val;
-             int size_in_chars
+             EMACS_INT size_in_chars
                = ((XFASTINT (length) + BOOL_VECTOR_BITS_PER_CHAR - 1)
                   / BOOL_VECTOR_BITS_PER_CHAR);
 
@@ -2569,13 +2570,16 @@
         and function definitions.  */
       if (c == '@')
        {
-         int i, nskip = 0;
+         enum { extra = 100 };
+         ptrdiff_t i, nskip = 0;
 
          load_each_byte = 1;
          /* Read a decimal integer.  */
          while ((c = READCHAR) >= 0
                 && c >= '0' && c <= '9')
            {
+             if ((STRING_BYTES_BOUND - extra) / 10 <= nskip)
+               string_overflow ();
              nskip *= 10;
              nskip += c - '0';
            }
@@ -2594,9 +2598,9 @@
                 with prev_saved_doc_string, so we save two strings.  */
              {
                char *temp = saved_doc_string;
-               int temp_size = saved_doc_string_size;
+               ptrdiff_t temp_size = saved_doc_string_size;
                file_offset temp_pos = saved_doc_string_position;
-               int temp_len = saved_doc_string_length;
+               ptrdiff_t temp_len = saved_doc_string_length;
 
                saved_doc_string = prev_saved_doc_string;
                saved_doc_string_size = prev_saved_doc_string_size;
@@ -2611,12 +2615,12 @@
 
              if (saved_doc_string_size == 0)
                {
-                 saved_doc_string_size = nskip + 100;
+                 saved_doc_string_size = nskip + extra;
                  saved_doc_string = (char *) xmalloc (saved_doc_string_size);
                }
              if (nskip > saved_doc_string_size)
                {
-                 saved_doc_string_size = nskip + 100;
+                 saved_doc_string_size = nskip + extra;
                  saved_doc_string = (char *) xrealloc (saved_doc_string,
                                                        saved_doc_string_size);
                }
@@ -2661,49 +2665,60 @@
       /* Reader forms that can reuse previously read objects.  */
       if (c >= '0' && c <= '9')
        {
-         int n = 0;
+         EMACS_INT n = 0;
          Lisp_Object tem;
 
          /* Read a non-negative integer.  */
          while (c >= '0' && c <= '9')
            {
-             n *= 10;
-             n += c - '0';
+             if (MOST_POSITIVE_FIXNUM / 10 < n
+                 || MOST_POSITIVE_FIXNUM < n * 10 + c - '0')
+               n = MOST_POSITIVE_FIXNUM + 1;
+             else
+               n = n * 10 + c - '0';
              c = READCHAR;
            }
-         /* #n=object returns object, but associates it with n for #n#.  */
-         if (c == '=' && !NILP (Vread_circle))
-           {
-             /* Make a placeholder for #n# to use temporarily */
-             Lisp_Object placeholder;
-             Lisp_Object cell;
-
-             placeholder = Fcons (Qnil, Qnil);
-             cell = Fcons (make_number (n), placeholder);
-             read_objects = Fcons (cell, read_objects);
-
-             /* Read the object itself. */
-             tem = read0 (readcharfun);
-
-             /* Now put it everywhere the placeholder was... */
-             substitute_object_in_subtree (tem, placeholder);
-
-             /* ...and #n# will use the real value from now on.  */
-             Fsetcdr (cell, tem);
-
-             return tem;
-           }
-         /* #n# returns a previously read object.  */
-         if (c == '#' && !NILP (Vread_circle))
-           {
-             tem = Fassq (make_number (n), read_objects);
-             if (CONSP (tem))
-               return XCDR (tem);
-             /* Fall through to error message.  */
-           }
-         else if (c == 'r' ||  c == 'R')
-           return read_integer (readcharfun, n);
-
+
+         if (n <= MOST_POSITIVE_FIXNUM)
+           {
+             if (c == 'r' || c == 'R')
+               return read_integer (readcharfun, n);
+
+             if (! NILP (Vread_circle))
+               {
+                 /* #n=object returns object, but associates it with
+                      n for #n#.  */
+                 if (c == '=')
+                   {
+                     /* Make a placeholder for #n# to use temporarily */
+                     Lisp_Object placeholder;
+                     Lisp_Object cell;
+
+                     placeholder = Fcons (Qnil, Qnil);
+                     cell = Fcons (make_number (n), placeholder);
+                     read_objects = Fcons (cell, read_objects);
+
+                     /* Read the object itself. */
+                     tem = read0 (readcharfun);
+
+                     /* Now put it everywhere the placeholder was... */
+                     substitute_object_in_subtree (tem, placeholder);
+
+                     /* ...and #n# will use the real value from now on.  */
+                     Fsetcdr (cell, tem);
+
+                     return tem;
+                   }
+
+                 /* #n# returns a previously read object.  */
+                 if (c == '#')
+                   {
+                     tem = Fassq (make_number (n), read_objects);
+                     if (CONSP (tem))
+                       return XCDR (tem);
+                   }
+               }
+           }
          /* Fall through to error message.  */
        }
       else if (c == 'x' || c == 'X')
@@ -2846,14 +2861,16 @@
           a single-byte character.  */
        int force_singlebyte = 0;
        int cancel = 0;
-       int nchars = 0;
+       ptrdiff_t nchars = 0;
 
        while ((ch = READCHAR) >= 0
               && ch != '\"')
          {
            if (end - p < MAX_MULTIBYTE_LENGTH)
              {
-               int offset = p - read_buffer;
+               ptrdiff_t offset = p - read_buffer;
+               if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
+                 memory_full (SIZE_MAX);
                read_buffer = (char *) xrealloc (read_buffer,
                                                 read_buffer_size *= 2);
                p = read_buffer + offset;
@@ -2996,7 +3013,9 @@
            {
              if (end - p < MAX_MULTIBYTE_LENGTH)
                {
-                 int offset = p - read_buffer;
+                 ptrdiff_t offset = p - read_buffer;
+                 if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
+                   memory_full (SIZE_MAX);
                  read_buffer = (char *) xrealloc (read_buffer,
                                                   read_buffer_size *= 2);
                  p = read_buffer + offset;
@@ -3023,7 +3042,9 @@
 
          if (p == end)
            {
-             int offset = p - read_buffer;
+             ptrdiff_t offset = p - read_buffer;
+             if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
+               memory_full (SIZE_MAX);
              read_buffer = (char *) xrealloc (read_buffer,
                                               read_buffer_size *= 2);
              p = read_buffer + offset;
@@ -3135,7 +3156,7 @@
     {
     case Lisp_Vectorlike:
       {
-       int i, length = 0;
+       ptrdiff_t i, length = 0;
        if (BOOL_VECTOR_P (subtree))
          return subtree;               /* No sub-objects anyway.  */
        else if (CHAR_TABLE_P (subtree) || SUB_CHAR_TABLE_P (subtree)
@@ -3358,8 +3379,7 @@
 static Lisp_Object
 read_vector (Lisp_Object readcharfun, int bytecodeflag)
 {
-  register int i;
-  register int size;
+  ptrdiff_t i, size;
   register Lisp_Object *ptr;
   register Lisp_Object tem, item, vector;
   register struct Lisp_Cons *otem;
@@ -3528,15 +3548,15 @@
                         doc string, caller must make it
                         multibyte.  */
 
-                     int pos = XINT (XCDR (val));
+                     EMACS_INT pos = XINT (XCDR (val));
                      /* Position is negative for user variables.  */
                      if (pos < 0) pos = -pos;
                      if (pos >= saved_doc_string_position
                          && pos < (saved_doc_string_position
                                    + saved_doc_string_length))
                        {
-                         int start = pos - saved_doc_string_position;
-                         int from, to;
+                         ptrdiff_t start = pos - saved_doc_string_position;
+                         ptrdiff_t from, to;
 
                          /* Process quoting with ^A,
                             and find the end of the string,
@@ -3567,8 +3587,9 @@
                               && pos < (prev_saved_doc_string_position
                                         + prev_saved_doc_string_length))
                        {
-                         int start = pos - prev_saved_doc_string_position;
-                         int from, to;
+                         ptrdiff_t start =
+                           pos - prev_saved_doc_string_position;
+                         ptrdiff_t from, to;
 
                          /* Process quoting with ^A,
                             and find the end of the string,
@@ -3891,7 +3912,7 @@
 void
 map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), 
Lisp_Object arg)
 {
-  register int i;
+  ptrdiff_t i;
   register Lisp_Object tail;
   CHECK_VECTOR (obarray);
   for (i = ASIZE (obarray) - 1; i >= 0; i--)
@@ -3991,7 +4012,7 @@
 #endif /* NOTDEF */
 
 /* Define an "integer variable"; a symbol whose value is forwarded to a
-   C variable of type int.  Sample call (munged w "xx" to fool make-docfile):
+   C variable of type EMACS_INT.  Sample call (with "xx" to fool make-docfile):
    DEFxxVAR_INT ("emacs-priority", &emacs_priority, "Documentation");  */
 void
 defvar_int (struct Lisp_Intfwd *i_fwd,

=== modified file 'src/macros.c'
--- a/src/macros.c      2011-04-14 05:04:02 +0000
+++ b/src/macros.c      2011-06-23 06:31:41 +0000
@@ -71,10 +71,10 @@
     {
       if (current_kboard->kbd_macro_bufsize > 200)
        {
+         current_kboard->kbd_macro_buffer
+           = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
+                                      30 * sizeof (Lisp_Object));
          current_kboard->kbd_macro_bufsize = 30;
-         current_kboard->kbd_macro_buffer
-           = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
-                                      30 * sizeof (Lisp_Object));
        }
       current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
       current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
@@ -82,7 +82,8 @@
     }
   else
     {
-      int i, len;
+      ptrdiff_t i;
+      EMACS_INT len;
       int cvt;
 
       /* Check the type of last-kbd-macro in case Lisp code changed it.  */
@@ -94,10 +95,13 @@
         has put another macro there.  */
       if (current_kboard->kbd_macro_bufsize < len + 30)
        {
+         if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object) - 30
+             < current_kboard->kbd_macro_bufsize)
+           memory_full (SIZE_MAX);
+         current_kboard->kbd_macro_buffer
+           = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
+                                      (len + 30) * sizeof (Lisp_Object));
          current_kboard->kbd_macro_bufsize = len + 30;
-         current_kboard->kbd_macro_buffer
-           = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
-                                      (len + 30) * sizeof (Lisp_Object));
        }
 
       /* Must convert meta modifier when copying string to vector.  */
@@ -191,14 +195,17 @@
     {
       if (kb->kbd_macro_ptr - kb->kbd_macro_buffer == kb->kbd_macro_bufsize)
        {
-         int ptr_offset, end_offset, nbytes;
+         ptrdiff_t ptr_offset, end_offset, nbytes;
 
          ptr_offset = kb->kbd_macro_ptr - kb->kbd_macro_buffer;
          end_offset = kb->kbd_macro_end - kb->kbd_macro_buffer;
-         kb->kbd_macro_bufsize *= 2;
-         nbytes = kb->kbd_macro_bufsize * sizeof *kb->kbd_macro_buffer;
+         if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *kb->kbd_macro_buffer / 2
+             < kb->kbd_macro_bufsize)
+           memory_full (SIZE_MAX);
+         nbytes = kb->kbd_macro_bufsize * 2 * sizeof *kb->kbd_macro_buffer;
          kb->kbd_macro_buffer
            = (Lisp_Object *) xrealloc (kb->kbd_macro_buffer, nbytes);
+         kb->kbd_macro_bufsize *= 2;
          kb->kbd_macro_ptr = kb->kbd_macro_buffer + ptr_offset;
          kb->kbd_macro_end = kb->kbd_macro_buffer + end_offset;
        }

=== modified file 'src/minibuf.c'
--- a/src/minibuf.c     2011-06-23 03:35:05 +0000
+++ b/src/minibuf.c     2011-06-23 07:37:31 +0000
@@ -236,7 +236,7 @@
                             Lisp_Object defalt,
                             int allow_props, int inherit_input_method)
 {
-  size_t size, len;
+  ptrdiff_t size, len;
   char *line, *s;
   Lisp_Object val;
 
@@ -246,12 +246,12 @@
   val = Qnil;
   size = 100;
   len = 0;
-  line = (char *) xmalloc (size * sizeof *line);
+  line = (char *) xmalloc (size);
   while ((s = fgets (line + len, size - len, stdin)) != NULL
         && (len = strlen (line),
             len == size - 1 && line[len - 1] != '\n'))
     {
-      if ((size_t) -1 / 2 < size)
+      if (STRING_BYTES_BOUND / 2 < size)
        memory_full (SIZE_MAX);
       size *= 2;
       line = (char *) xrealloc (line, size);
@@ -259,11 +259,9 @@
 
   if (s)
     {
-      len = strlen (line);
-
-      if (len > 0 && line[len - 1] == '\n')
-       line[--len] = '\0';
-
+      char *nl = strchr (line, '\n');
+      if (nl)
+       *nl = '\0';
       val = build_string (line);
       xfree (line);
     }

=== modified file 'src/print.c'
--- a/src/print.c       2011-06-08 21:43:46 +0000
+++ b/src/print.c       2011-06-23 07:33:28 +0000
@@ -159,8 +159,9 @@
         }                                                              \
        else                                                            \
         {                                                              \
-           print_buffer_size = 1000;                                   \
-           print_buffer = (char *) xmalloc (print_buffer_size);                
\
+          ptrdiff_t new_size = 1000;                                   \
+          print_buffer = (char *) xmalloc (new_size);                  \
+          print_buffer_size = new_size;                                \
           free_print_buffer = 1;                                       \
         }                                                              \
        print_buffer_pos = 0;                                           \
@@ -235,9 +236,15 @@
 
       if (NILP (fun))
        {
-         if (print_buffer_pos_byte + len >= print_buffer_size)
-           print_buffer = (char *) xrealloc (print_buffer,
-                                             print_buffer_size *= 2);
+         if (print_buffer_size - len <= print_buffer_pos_byte)
+           {
+             ptrdiff_t new_size;
+             if (STRING_BYTES_BOUND / 2 < print_buffer_size)
+               string_overflow ();
+             new_size = print_buffer_size * 2;
+             print_buffer = (char *) xrealloc (print_buffer, new_size);
+             print_buffer_size = new_size;
+           }
          memcpy (print_buffer + print_buffer_pos_byte, str, len);
          print_buffer_pos += 1;
          print_buffer_pos_byte += len;
@@ -280,11 +287,14 @@
 
   if (NILP (printcharfun))
     {
-      if (print_buffer_pos_byte + size_byte > print_buffer_size)
+      if (print_buffer_size - size_byte < print_buffer_pos_byte)
        {
-         print_buffer_size = print_buffer_size * 2 + size_byte;
-         print_buffer = (char *) xrealloc (print_buffer,
-                                           print_buffer_size);
+         ptrdiff_t new_size;
+         if (STRING_BYTES_BOUND / 2 - size_byte < print_buffer_size)
+           string_overflow ();
+         new_size = print_buffer_size * 2 + size_byte;
+         print_buffer = (char *) xrealloc (print_buffer, new_size);
+         print_buffer_size = new_size;
        }
       memcpy (print_buffer + print_buffer_pos_byte, ptr, size_byte);
       print_buffer_pos += size;


reply via email to

[Prev in Thread] Current Thread [Next in Thread]