* termcap.c: Integer and memory overflow issues.
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 29 Jul 2011 01:24:19 +0000 (18:24 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 29 Jul 2011 01:24:19 +0000 (18:24 -0700)
(tgetent): Use ptrdiff_t, not int, to record results of
subtracting pointers.
(gobble_line): Check for overflow more carefully.  Don't update size
until alloc done.

src/ChangeLog
src/termcap.c

index 7485afb..24610e3 100644 (file)
@@ -1,5 +1,11 @@
 2011-07-29  Paul Eggert  <eggert@cs.ucla.edu>
 
+       * termcap.c: Integer and memory overflow issues.
+       (tgetent): Use ptrdiff_t, not int, to record results of
+       subtracting pointers.
+       (gobble_line): Check for overflow more carefully.  Don't update size
+       until alloc done.
+
        * term.c: Integer and memory overflow issues.
        (max_frame_lines): Remove; unused.
        (encode_terminal_src_size, encode_terminal_dst_size): Now ptrdiff_t,
index 96b9303..791c593 100644 (file)
@@ -480,7 +480,7 @@ tgetent (char *bp, const char *name)
       /* If BP is malloc'd by us, make sure it is big enough.  */
       if (malloc_size)
        {
-         int offset1 = bp1 - bp, offset2 = tc_search_point - bp;
+         ptrdiff_t offset1 = bp1 - bp, offset2 = tc_search_point - bp;
          malloc_size = offset1 + buf.size;
          bp = termcap_name = (char *) xrealloc (bp, malloc_size);
          bp1 = termcap_name + offset1;
@@ -619,7 +619,6 @@ gobble_line (int fd, register struct termcap_buffer *bufp, char *append_end)
   register char *end;
   register int nread;
   register char *buf = bufp->beg;
-  register char *tem;
 
   if (!append_end)
     append_end = bufp->ptr;
@@ -636,14 +635,17 @@ gobble_line (int fd, register struct termcap_buffer *bufp, char *append_end)
        {
          if (bufp->full == bufp->size)
            {
-             if ((PTRDIFF_MAX - 1) / 2 < bufp->size)
+             ptrdiff_t ptr_offset = bufp->ptr - buf;
+             ptrdiff_t append_end_offset = append_end - buf;
+             ptrdiff_t size;
+             if ((min (PTRDIFF_MAX, SIZE_MAX) - 1) / 2 < bufp->size)
                memory_full (SIZE_MAX);
-             bufp->size *= 2;
+             size = 2 * bufp->size;
              /* Add 1 to size to ensure room for terminating null.  */
-             tem = (char *) xrealloc (buf, bufp->size + 1);
-             bufp->ptr = (bufp->ptr - buf) + tem;
-             append_end = (append_end - buf) + tem;
-             bufp->beg = buf = tem;
+             bufp->beg = buf = (char *) xrealloc (buf, size + 1);
+             bufp->size = size;
+             bufp->ptr = buf + ptr_offset;
+             append_end = buf + append_end_offset;
            }
        }
       else