]> git.eshelyaron.com Git - emacs.git/commitdiff
* doprnt.c: Prefer signed to unsigned when either works.
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 7 Jul 2011 02:14:52 +0000 (19:14 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 7 Jul 2011 02:14:52 +0000 (19:14 -0700)
* eval.c (verror):
* doprnt.c (doprnt):
* lisp.h (doprnt):
* xdisp.c (vmessage):
Use ptrdiff_t, not size_t, when using or implementing doprnt,
since the sizes cannot exceed ptrdiff_t bounds anyway, and we
prefer signed arithmetic to avoid comparison confusion.
* doprnt.c (doprnt): Avoid a "+ 1" that can't overflow,
but is a bit tricky.

src/ChangeLog
src/doprnt.c
src/eval.c
src/lisp.h
src/xdisp.c

index d91837877e1a905e366e9affb7955b87f066950b..6e63fdd633317fb34ea693a6c71fdc2ee3e159cc 100644 (file)
@@ -1,5 +1,16 @@
 2011-07-07  Paul Eggert  <eggert@cs.ucla.edu>
 
+       * doprnt.c: Prefer signed to unsigned when either works.
+       * eval.c (verror):
+       * doprnt.c (doprnt):
+       * lisp.h (doprnt):
+       * xdisp.c (vmessage):
+       Use ptrdiff_t, not size_t, when using or implementing doprnt,
+       since the sizes cannot exceed ptrdiff_t bounds anyway, and we
+       prefer signed arithmetic to avoid comparison confusion.
+       * doprnt.c (doprnt): Avoid a "+ 1" that can't overflow,
+       but is a bit tricky.
+
        Assume freestanding C89 headers, string.h, stdlib.h.
        * data.c, doprnt.c, floatfns.c, print.c:
        Include float.h unconditionally.
index 0632046525af65f22d3920db149287c4a22043c1..79f9f36e4616cb636f9460ff73a85e06f2d234c4 100644 (file)
@@ -129,8 +129,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    String arguments are passed as C strings.
    Integers are passed as C integers.  */
 
-size_t
-doprnt (char *buffer, register size_t bufsize, const char *format,
+ptrdiff_t
+doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
        const char *format_end, va_list ap)
 {
   const char *fmt = format;    /* Pointer into format string */
@@ -140,7 +140,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
   char tembuf[DBL_MAX_10_EXP + 100];
 
   /* Size of sprintf_buffer.  */
-  size_t size_allocated = sizeof (tembuf);
+  ptrdiff_t size_allocated = sizeof (tembuf);
 
   /* Buffer to use for sprintf.  Either tembuf or same as BIG_BUFFER.  */
   char *sprintf_buffer = tembuf;
@@ -159,7 +159,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
   if (format_end == 0)
     format_end = format + strlen (format);
 
-  if ((format_end - format + 1) < sizeof (fixed_buffer))
+  if (format_end - format < sizeof (fixed_buffer) - 1)
     fmtcpy = fixed_buffer;
   else
     SAFE_ALLOCA (fmtcpy, char *, format_end - format + 1);
@@ -171,7 +171,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
     {
       if (*fmt == '%') /* Check for a '%' character */
        {
-         size_t size_bound = 0;
+         ptrdiff_t size_bound = 0;
          EMACS_INT width;  /* Columns occupied by STRING on display.  */
          int long_flag = 0;
          int pIlen = sizeof pI - 1;
@@ -189,16 +189,16 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
                     This might be a field width or a precision; e.g.
                     %1.1000f and %1000.1f both might need 1000+ bytes.
                     Parse the width or precision, checking for overflow.  */
-                 size_t n = *fmt - '0';
+                 ptrdiff_t n = *fmt - '0';
                  while (fmt + 1 < format_end
                         && '0' <= fmt[1] && fmt[1] <= '9')
                    {
-                     /* Avoid size_t overflow.  Avoid int overflow too, as
+                     /* Avoid ptrdiff_t, size_t, and int overflow, as
                         many sprintfs mishandle widths greater than INT_MAX.
                         This test is simple but slightly conservative: e.g.,
                         (INT_MAX - INT_MAX % 10) is reported as an overflow
                         even when it's not.  */
-                     if (n >= min (INT_MAX, SIZE_MAX) / 10)
+                     if (n >= min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX)) / 10)
                        error ("Format width or precision too large");
                      n = n * 10 + fmt[1] - '0';
                      *string++ = *++fmt;
@@ -230,7 +230,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
 
          /* Make the size bound large enough to handle floating point formats
             with large numbers.  */
-         if (size_bound > SIZE_MAX - DBL_MAX_10_EXP - 50)
+         if (size_bound > min (PTRDIFF_MAX, SIZE_MAX) - DBL_MAX_10_EXP - 50)
            error ("Format width or precision too large");
          size_bound += DBL_MAX_10_EXP + 50;
 
index 90d0df61858d40783ba3a71a3e71320843f2d105..ef169e80e274892e887d39f55dbe8f3dda86d251 100644 (file)
@@ -1968,18 +1968,18 @@ void
 verror (const char *m, va_list ap)
 {
   char buf[4000];
-  size_t size = sizeof buf;
-  size_t size_max = STRING_BYTES_BOUND + 1;
-  size_t mlen = strlen (m);
+  ptrdiff_t size = sizeof buf;
+  ptrdiff_t size_max = STRING_BYTES_BOUND + 1;
+  char const *m_end = m + strlen (m);
   char *buffer = buf;
-  size_t used;
+  ptrdiff_t used;
   Lisp_Object string;
 
   while (1)
     {
       va_list ap_copy;
       va_copy (ap_copy, ap);
-      used = doprnt (buffer, size, m, m + mlen, ap_copy);
+      used = doprnt (buffer, size, m, m_end, ap_copy);
       va_end (ap_copy);
 
       /* Note: the -1 below is because `doprnt' returns the number of bytes
index cd3cfd316a524d237ab6d4864817410046c6cd4b..f16a32e6331323b013fd74cebc89f6fdc2ae5282 100644 (file)
@@ -2868,7 +2868,8 @@ extern void float_to_string (char *, double);
 extern void syms_of_print (void);
 
 /* Defined in doprnt.c */
-extern size_t doprnt (char *, size_t, const char *, const char *, va_list);
+extern ptrdiff_t doprnt (char *, ptrdiff_t, const char *, const char *,
+                        va_list);
 
 /* Defined in lread.c.  */
 extern Lisp_Object Qvariable_documentation, Qstandard_input;
index a99f06a4e45b021df9823d8897d52dd5932331ec..c1347e2dc27a05eba6d4c4f1877ae052a3a9aa56 100644 (file)
@@ -8485,7 +8485,7 @@ vmessage (const char *m, va_list ap)
        {
          if (m)
            {
-             size_t len;
+             ptrdiff_t len;
 
              len = doprnt (FRAME_MESSAGE_BUF (f),
                            FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);