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

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

bug#8545: issues with recent doprnt-related changes


From: Paul Eggert
Subject: bug#8545: issues with recent doprnt-related changes
Date: Wed, 27 Apr 2011 20:11:52 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110223 Thunderbird/3.1.8

On 04/27/11 18:32, Juanma Barranquero wrote:

> A cursory look suggests that fmt == format_end + 1 is possible

Thanks, I had missed that possibility.  (Evidently your cursory looks
are better than mine. :-)  A possible patch is below.

> would it be undefined behavior,
> as long as the pointer has not been dereferenced?

Yes.  A portable C program is not allowed to create a pointer that
doesn't point to an object, with the two exceptions of a null pointer
and a pointer to the address immediately after an object.  On
some architectures, attempting to point to random addresses can cause
exceptions or other undefined behavior.

=== modified file 'src/doprnt.c'
--- src/doprnt.c        2011-04-27 23:04:20 +0000
+++ src/doprnt.c        2011-04-28 03:00:59 +0000
@@ -194,22 +194,21 @@ doprnt (char *buffer, register size_t bu
                     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';
-                 while (fmt < format_end
-                        && '0' <= fmt[1] && fmt[1] <= '9')
+                 size_t n = *fmt++ - '0';
+                 while (fmt < format_end && '0' <= *fmt && *fmt <= '9')
                    {
                      if (n >= SIZE_MAX / 10
                          || n * 10 > SIZE_MAX - (fmt[1] - '0'))
                        error ("Format width or precision too large");
-                     n = n * 10 + fmt[1] - '0';
-                     *string++ = *++fmt;
+                     n = n * 10 + *fmt - '0';
+                     *string++ = *fmt++;
                    }
 
                  if (size_bound < n)
                    size_bound = n;
                }
              else if (*fmt == '-' || *fmt == ' ' || *fmt == '.' || *fmt == '+')
-               ;
+               fmt++;
              else if (*fmt == 'l')
                {
                  long_flag = 1 + (fmt + 1 < format_end && fmt[1] == 'l');
@@ -218,10 +217,7 @@ doprnt (char *buffer, register size_t bu
                }
              else
                break;
-             fmt++;
            }
-         if (fmt > format_end)
-           fmt = format_end;
          *string = 0;
 
          /* Make the size bound large enough to handle floating point formats






reply via email to

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