bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#8794: (a) uncontroversial fixes (2011-06-06 version)


From: Paul Eggert
Subject: bug#8794: (a) uncontroversial fixes (2011-06-06 version)
Date: Mon, 06 Jun 2011 01:39:14 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: address@hidden
# target_branch: bzr+ssh://address@hidden/emacs/trunk
# testament_sha1: c8b36cc2ea7b3f5a15360443ec4a0832655a629c
# timestamp: 2011-06-06 01:28:12 -0700
# base_revision_id: address@hidden
# 
# Begin patch
=== modified file 'src/ChangeLog'
--- src/ChangeLog       2011-06-06 04:54:23 +0000
+++ src/ChangeLog       2011-06-06 06:16:12 +0000
@@ -1,5 +1,52 @@
 2011-06-06  Paul Eggert  <address@hidden>
 
+       Check for buffer and string overflow more precisely.
+       * buffer.h (BUF_BYTES_MAX): New macro.
+       * lisp.h (STRING_BYTES_MAX): New macro.
+       * alloc.c (Fmake_string):
+       * character.c (string_escape_byte8):
+       * coding.c (coding_alloc_by_realloc):
+       * doprnt.c (doprnt):
+       * editfns.c (Fformat):
+       * eval.c (verror):
+       Use STRING_BYTES_MAX, not MOST_POSITIVE_FIXNUM,
+       since they may not be the same number.
+       * editfns.c (Finsert_char):
+       * fileio.c (Finsert_file_contents):
+       Likewise for BUF_BYTES_MAX.
+
+       * image.c: Use ptrdiff_t, not int, for sizes.
+       (slurp_file): Switch from int to ptrdiff_t.
+       All uses changed.
+       (slurp_file): Check that file size fits in both size_t (for
+       malloc) and ptrdiff_t (for sanity and safety).
+
+       * fileio.c (Fverify_visited_file_modtime): Avoid time overflow
+       if b->modtime has its maximal value.
+
+       * dired.c (Ffile_attributes): Don't assume EMACS_INT has >32 bits.
+
+       Don't assume time_t can fit into int.
+       * buffer.h (struct buffer.modtime): Now time_t, not int.
+       * fileio.c (Fvisited_file_modtime): No need for time_t cast now.
+       * undo.c (Fprimitive_undo): Use time_t, not int, for time_t value.
+
+       Minor fixes for signed vs unsigned integers.
+       * character.h (MAYBE_UNIFY_CHAR):
+       * charset.c (maybe_unify_char):
+       * keyboard.c (read_char, reorder_modifiers):
+       XINT -> XFASTINT, since the integer must be nonnegative.
+       * ftfont.c (ftfont_spec_pattern):
+       * keymap.c (access_keymap, silly_event_symbol_error):
+       XUINT -> XFASTINT, since the integer must be nonnegative.
+       (Fsingle_key_description, preferred_sequence_p): XUINT -> XINT,
+       since it makes no difference and we prefer signed.
+       * keyboard.c (record_char): Use XUINT when all the neighbors do.
+       (access_keymap): NATNUMP -> INTEGERP, since the integer must be
+       nonnegative.
+
+2011-06-06  Paul Eggert  <address@hidden>
+
        * alloc.c (memory_full) [SYSTEM_MALLOC]: Port to MacOS (Bug#8800).
        Do not assume that spare memory exists; that assumption is valid
        only if SYSTEM_MALLOC.

=== modified file 'src/alloc.c'
--- src/alloc.c 2011-06-06 04:54:23 +0000
+++ src/alloc.c 2011-06-06 06:16:12 +0000
@@ -2211,7 +2211,7 @@
       int len = CHAR_STRING (c, str);
       EMACS_INT string_len = XINT (length);
 
-      if (string_len > MOST_POSITIVE_FIXNUM / len)
+      if (string_len > STRING_BYTES_MAX / len)
        string_overflow ();
       nbytes = len * string_len;
       val = make_uninit_multibyte_string (string_len, nbytes);

=== modified file 'src/buffer.h'
--- src/buffer.h        2011-05-12 07:07:06 +0000
+++ src/buffer.h        2011-06-06 06:16:12 +0000
@@ -306,6 +306,11 @@
   }                                                            \
 while (0)
 
+/* Maximum number of bytes in a buffer.
+   A buffer cannot contain more bytes than a 1-origin fixnum can represent,
+   nor can it be so large that C pointer arithmetic stops working.  */
+#define BUF_BYTES_MAX min (MOST_POSITIVE_FIXNUM - 1, min (SIZE_MAX, 
PTRDIFF_MAX))
+
 /* Return the address of byte position N in current buffer.  */
 
 #define BYTE_POS_ADDR(n) \
@@ -545,7 +550,7 @@
      -1 means visited file was nonexistent.
      0 means visited file modtime unknown; in no case complain
      about any mismatch on next save attempt.  */
-  int modtime;
+  time_t modtime;
   /* Size of the file when modtime was set.  This is used to detect the
      case where the file grew while we were reading it, so the modtime
      is still the same (since it's rounded up to seconds) but we're actually

=== modified file 'src/character.c'
--- src/character.c     2011-05-21 04:33:23 +0000
+++ src/character.c     2011-06-06 06:16:12 +0000
@@ -838,7 +838,7 @@
   if (multibyte)
     {
       if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count
-         || (MOST_POSITIVE_FIXNUM - nbytes) / 2 < byte8_count)
+         || (STRING_BYTES_MAX - nbytes) / 2 < byte8_count)
        string_overflow ();
 
       /* Convert 2-byte sequence of byte8 chars to 4-byte octal.  */
@@ -847,7 +847,7 @@
     }
   else
     {
-      if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count)
+      if ((STRING_BYTES_MAX - nchars) / 3 < byte8_count)
        string_overflow ();
 
       /* Convert 1-byte sequence of byte8 chars to 4-byte octal.  */

=== modified file 'src/character.h'
--- src/character.h     2011-05-21 04:33:23 +0000
+++ src/character.h     2011-06-01 02:49:12 +0000
@@ -544,7 +544,7 @@
        Lisp_Object val;                                \
        val = CHAR_TABLE_REF (Vchar_unify_table, c);    \
        if (INTEGERP (val))                             \
-         c = XINT (val);                               \
+         c = XFASTINT (val);                           \
        else if (! NILP (val))                          \
          c = maybe_unify_char (c, val);                \
       }                                                        \

=== modified file 'src/charset.c'
--- src/charset.c       2011-05-31 06:05:00 +0000
+++ src/charset.c       2011-06-03 18:11:17 +0000
@@ -1637,7 +1637,7 @@
   struct charset *charset;
 
   if (INTEGERP (val))
-    return XINT (val);
+    return XFASTINT (val);
   if (NILP (val))
     return c;
 
@@ -1647,7 +1647,7 @@
     {
       val = CHAR_TABLE_REF (Vchar_unify_table, c);
       if (! NILP (val))
-       c = XINT (val);
+       c = XFASTINT (val);
     }
   else
     {

=== modified file 'src/coding.c'
--- src/coding.c        2011-05-30 01:12:12 +0000
+++ src/coding.c        2011-06-06 06:16:12 +0000
@@ -1071,8 +1071,8 @@
 static void
 coding_alloc_by_realloc (struct coding_system *coding, EMACS_INT bytes)
 {
-  if (coding->dst_bytes >= MOST_POSITIVE_FIXNUM - bytes)
-    error ("Maximum size of buffer or string exceeded");
+  if (STRING_BYTES_MAX - coding->dst_bytes < bytes)
+    string_overflow ();
   coding->destination = (unsigned char *) xrealloc (coding->destination,
                                                    coding->dst_bytes + bytes);
   coding->dst_bytes += bytes;

=== modified file 'src/dired.c'
--- src/dired.c 2011-04-14 19:34:42 +0000
+++ src/dired.c 2011-06-06 05:55:38 +0000
@@ -1013,12 +1013,11 @@
         The code on the next line avoids a compiler warning on
         systems where st_ino is 32 bit wide. (bug#766).  */
       EMACS_INT high_ino = s.st_ino >> 31 >> 1;
-      EMACS_INT low_ino  = s.st_ino & 0xffffffff;
 
       values[10] = Fcons (make_number (high_ino >> 8),
                          Fcons (make_number (((high_ino & 0xff) << 16)
-                                             + (low_ino >> 16)),
-                                make_number (low_ino & 0xffff)));
+                                             + (s.st_ino >> 16 & 0xffff)),
+                                make_number (s.st_ino & 0xffff)));
     }
 
   /* Likewise for device.  */

=== modified file 'src/doprnt.c'
--- src/doprnt.c        2011-04-30 20:05:43 +0000
+++ src/doprnt.c        2011-06-06 06:16:12 +0000
@@ -329,7 +329,7 @@
                minlen = atoi (&fmtcpy[1]);
              string = va_arg (ap, char *);
              tem = strlen (string);
-             if (tem > MOST_POSITIVE_FIXNUM)
+             if (tem > STRING_BYTES_MAX)
                error ("String for %%s or %%S format is too long");
              width = strwidth (string, tem);
              goto doit1;
@@ -338,7 +338,7 @@
            doit:
              /* Coming here means STRING contains ASCII only.  */
              tem = strlen (string);
-             if (tem > MOST_POSITIVE_FIXNUM)
+             if (tem > STRING_BYTES_MAX)
                error ("Format width or precision too large");
              width = tem;
            doit1:

=== modified file 'src/editfns.c'
--- src/editfns.c       2011-06-05 22:46:26 +0000
+++ src/editfns.c       2011-06-06 06:16:12 +0000
@@ -2342,7 +2342,7 @@
     len = CHAR_STRING (XFASTINT (character), str);
   else
     str[0] = XFASTINT (character), len = 1;
-  if (MOST_POSITIVE_FIXNUM / len < XINT (count))
+  if (BUF_BYTES_MAX / len < XINT (count))
     error ("Maximum buffer size would be exceeded");
   n = XINT (count) * len;
   if (n <= 0)
@@ -3589,7 +3589,7 @@
   char initial_buffer[4000];
   char *buf = initial_buffer;
   EMACS_INT bufsize = sizeof initial_buffer;
-  EMACS_INT max_bufsize = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX);
+  EMACS_INT max_bufsize = STRING_BYTES_MAX + 1;
   char *p;
   Lisp_Object buf_save_value IF_LINT (= {0});
   register char *format, *end, *format_start;

=== modified file 'src/eval.c'
--- src/eval.c  2011-05-30 05:39:59 +0000
+++ src/eval.c  2011-06-06 06:16:12 +0000
@@ -1994,7 +1994,7 @@
 {
   char buf[4000];
   size_t size = sizeof buf;
-  size_t size_max = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX);
+  size_t size_max = STRING_BYTES_MAX + 1;
   size_t mlen = strlen (m);
   char *buffer = buf;
   size_t used;

=== modified file 'src/fileio.c'
--- src/fileio.c        2011-04-29 19:47:29 +0000
+++ src/fileio.c        2011-06-06 06:16:12 +0000
@@ -3248,7 +3248,7 @@
   /* Check whether the size is too large or negative, which can happen on a
      platform that allows file sizes greater than the maximum off_t value.  */
   if (! not_regular
-      && ! (0 <= st.st_size && st.st_size <= MOST_POSITIVE_FIXNUM))
+      && ! (0 <= st.st_size && st.st_size <= BUF_BYTES_MAX))
     error ("Maximum buffer size exceeded");
 
   /* Prevent redisplay optimizations.  */
@@ -4960,7 +4960,7 @@
   if ((st.st_mtime == b->modtime
        /* If both are positive, accept them if they are off by one second.  */
        || (st.st_mtime > 0 && b->modtime > 0
-          && (st.st_mtime == b->modtime + 1
+          && (st.st_mtime - 1 == b->modtime
               || st.st_mtime == b->modtime - 1)))
       && (st.st_size == b->modtime_size
           || b->modtime_size < 0))
@@ -4990,7 +4990,7 @@
 {
   if (! current_buffer->modtime)
     return make_number (0);
-  return make_time ((time_t) current_buffer->modtime);
+  return make_time (current_buffer->modtime);
 }
 
 DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,

=== modified file 'src/ftfont.c'
--- src/ftfont.c        2011-04-11 03:39:45 +0000
+++ src/ftfont.c        2011-06-01 02:49:12 +0000
@@ -815,7 +815,7 @@
            goto err;
          for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars))
            if (CHARACTERP (XCAR (chars))
-               && ! FcCharSetAddChar (charset, XUINT (XCAR (chars))))
+               && ! FcCharSetAddChar (charset, XFASTINT (XCAR (chars))))
              goto err;
        }
     }

=== modified file 'src/image.c'
--- src/image.c 2011-05-31 06:05:00 +0000
+++ src/image.c 2011-06-06 06:10:06 +0000
@@ -2112,9 +2112,6 @@
                              File Handling
  ***********************************************************************/
 
-static unsigned char *slurp_file (char *, int *);
-
-
 /* Find image file FILE.  Look in data-directory/images, then
    x-bitmap-file-path.  Value is the encoded full name of the file
    found, or nil if not found.  */
@@ -2151,7 +2148,7 @@
    occurred.  *SIZE is set to the size of the file.  */
 
 static unsigned char *
-slurp_file (char *file, int *size)
+slurp_file (char *file, ptrdiff_t *size)
 {
   FILE *fp = NULL;
   unsigned char *buf = NULL;
@@ -2159,6 +2156,7 @@
 
   if (stat (file, &st) == 0
       && (fp = fopen (file, "rb")) != NULL
+      && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
       && (buf = (unsigned char *) xmalloc (st.st_size),
          fread (buf, 1, st.st_size, fp) == st.st_size))
     {
@@ -2814,7 +2812,7 @@
     {
       Lisp_Object file;
       unsigned char *contents;
-      int size;
+      ptrdiff_t size;
 
       file = x_find_image_file (file_name);
       if (!STRINGP (file))
@@ -4039,7 +4037,7 @@
     {
       Lisp_Object file;
       unsigned char *contents;
-      int size;
+      ptrdiff_t size;
 
       file = x_find_image_file (file_name);
       if (!STRINGP (file))
@@ -5021,6 +5019,7 @@
 
   if (stat (SDATA (file), &st) == 0
       && (fp = fopen (SDATA (file), "rb")) != NULL
+      && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
       && (buf = (char *) xmalloc (st.st_size),
          fread (buf, 1, st.st_size, fp) == st.st_size))
     {
@@ -5055,7 +5054,7 @@
   enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
   unsigned char *contents = NULL;
   unsigned char *end, *p;
-  int size;
+  ptrdiff_t size;
 
   specified_file = image_spec_value (img->spec, QCfile, NULL);
 
@@ -7869,7 +7868,7 @@
 static int svg_load (struct frame *f, struct image *img);
 
 static int svg_load_image (struct frame *, struct image *,
-                           unsigned char *, unsigned int);
+                           unsigned char *, ptrdiff_t);
 
 /* The symbol `svg' identifying images of this type. */
 
@@ -8047,7 +8046,7 @@
     {
       Lisp_Object file;
       unsigned char *contents;
-      int size;
+      ptrdiff_t size;
 
       file = x_find_image_file (file_name);
       if (!STRINGP (file))
@@ -8096,7 +8095,7 @@
 svg_load_image (struct frame *f,         /* Pointer to emacs frame structure.  
*/
                struct image *img,       /* Pointer to emacs image structure.  
*/
                unsigned char *contents, /* String containing the SVG XML data 
to be parsed.  */
-               unsigned int size)       /* Size of data in bytes.  */
+               ptrdiff_t size)          /* Size of data in bytes.  */
 {
   RsvgHandle *rsvg_handle;
   RsvgDimensionData dimension_data;

=== modified file 'src/keyboard.c'
--- src/keyboard.c      2011-06-04 07:41:44 +0000
+++ src/keyboard.c      2011-06-06 05:48:28 +0000
@@ -2395,8 +2395,8 @@
 
       c = Faref (Vexecuting_kbd_macro, make_number 
(executing_kbd_macro_index));
       if (STRINGP (Vexecuting_kbd_macro)
-         && (XINT (c) & 0x80) && (XUINT (c) <= 0xff))
-       XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80));
+         && (XFASTINT (c) & 0x80) && (XFASTINT (c) <= 0xff))
+       XSETFASTINT (c, CHAR_META | (XFASTINT (c) & ~0x80));
 
       executing_kbd_macro_index++;
 
@@ -3321,7 +3321,7 @@
       if (INTEGERP (c))
        {
          if (XUINT (c) < 0x100)
-           putc (XINT (c), dribble);
+           putc (XUINT (c), dribble);
          else
            fprintf (dribble, " 0x%"pI"x", XUINT (c));
        }
@@ -6370,7 +6370,7 @@
   Lisp_Object parsed;
 
   parsed = parse_modifiers (symbol);
-  return apply_modifiers ((int) XINT (XCAR (XCDR (parsed))),
+  return apply_modifiers (XFASTINT (XCAR (XCDR (parsed))),
                          XCAR (parsed));
 }
 

=== modified file 'src/keymap.c'
--- src/keymap.c        2011-05-12 07:07:06 +0000
+++ src/keymap.c        2011-06-01 02:49:12 +0000
@@ -462,7 +462,7 @@
     XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1)));
 
   /* Handle the special meta -> esc mapping. */
-  if (INTEGERP (idx) && XUINT (idx) & meta_modifier)
+  if (INTEGERP (idx) && XFASTINT (idx) & meta_modifier)
     {
       /* See if there is a meta-map.  If there's none, there is
          no binding for IDX, unless a default binding exists in MAP.  */
@@ -480,7 +480,7 @@
       if (CONSP (event_meta_map))
        {
          map = event_meta_map;
-         idx = make_number (XUINT (idx) & ~meta_modifier);
+         idx = make_number (XFASTINT (idx) & ~meta_modifier);
        }
       else if (t_ok)
        /* Set IDX to t, so that we only find a default binding.  */
@@ -529,7 +529,7 @@
          }
        else if (VECTORP (binding))
          {
-           if (NATNUMP (idx) && XFASTINT (idx) < ASIZE (binding))
+           if (INTEGERP (idx) && XFASTINT (idx) < ASIZE (binding))
              val = AREF (binding, XFASTINT (idx));
          }
        else if (CHAR_TABLE_P (binding))
@@ -537,7 +537,7 @@
            /* Character codes with modifiers
               are not included in a char-table.
               All character codes without modifiers are included.  */
-           if (NATNUMP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0)
+           if (INTEGERP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0)
              {
                val = Faref (binding, idx);
                /* `nil' has a special meaning for char-tables, so
@@ -1357,7 +1357,7 @@
   int modifiers;
 
   parsed = parse_modifiers (c);
-  modifiers = (int) XUINT (XCAR (XCDR (parsed)));
+  modifiers = XFASTINT (XCAR (XCDR (parsed)));
   base = XCAR (parsed);
   name = Fsymbol_name (base);
   /* This alist includes elements such as ("RET" . "\\r").  */
@@ -2416,7 +2416,7 @@
     {
       char tem[KEY_DESCRIPTION_SIZE];
 
-      *push_key_description (XUINT (key), tem, 1) = 0;
+      *push_key_description (XINT (key), tem, 1) = 0;
       return build_string (tem);
     }
   else if (SYMBOLP (key))      /* Function key or event-symbol */
@@ -2515,7 +2515,7 @@
        return 0;
       else
        {
-         int modifiers = XUINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META);
+         int modifiers = XINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META);
          if (modifiers == where_is_preferred_modifier)
            result = 2;
          else if (modifiers)

=== modified file 'src/lisp.h'
--- src/lisp.h  2011-06-02 08:25:28 +0000
+++ src/lisp.h  2011-06-06 06:16:12 +0000
@@ -763,6 +763,12 @@
 
 #endif /* not GC_CHECK_STRING_BYTES */
 
+/* A string cannot contain more bytes than a fixnum can represent,
+   nor can it be so long that C pointer arithmetic stops working on
+   the string plus a terminating null.  */
+#define STRING_BYTES_MAX  \
+  min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1)
+
 /* Mark STR as a unibyte string.  */
 #define STRING_SET_UNIBYTE(STR)  \
   do { if (EQ (STR, empty_multibyte_string))  \

=== modified file 'src/undo.c'
--- src/undo.c  2011-04-14 05:04:02 +0000
+++ src/undo.c  2011-06-02 06:15:15 +0000
@@ -500,7 +500,7 @@
                {
                  /* Element (t high . low) records previous modtime.  */
                  Lisp_Object high, low;
-                 int mod_time;
+                 time_t mod_time;
                  struct buffer *base_buffer = current_buffer;
 
                  high = Fcar (cdr);

# Begin bundle
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
zo+ou5IpwoSErW6vUA==





reply via email to

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