]> git.saurik.com Git - apple/libc.git/blobdiff - stdio/FreeBSD/vfscanf.c.patch
Libc-498.tar.gz
[apple/libc.git] / stdio / FreeBSD / vfscanf.c.patch
index aa47ead8515742ae845a6989764199bb28e89b79..54d979939db8e2285ad4722f6601eae37a8c881d 100644 (file)
@@ -1,5 +1,5 @@
 --- vfscanf.c.orig     2004-11-25 11:38:35.000000000 -0800
-+++ vfscanf.c  2005-02-23 19:24:50.000000000 -0800
++++ vfscanf.c  2005-05-20 00:46:37.000000000 -0700
 @@ -40,6 +40,8 @@
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.37 2004/05/02 10:55:05 das Exp $");
                                n = 0;
 -                              while (!isspace(*fp->_p) && width != 0) {
 -                                      if (n == MB_CUR_MAX) {
-+                              while (!isspace_l(*fp->_p, loc) && width != 0) {
++                              while (width != 0) {
 +                                      if (n == mb_cur_max) {
                                                fp->_flags |= __SERR;
                                                goto input_failure;
                                if (flags & POINTER)
                                        *va_arg(ap, void **) =
                                                        (void *)(uintptr_t)res;
-@@ -763,43 +800,52 @@
+@@ -763,43 +800,48 @@
                                nassigned++;
                        }
                        nread += p - buf;
 -                      if (width == 0 || width > sizeof(buf) - 1)
 -                              width = sizeof(buf) - 1;
 -                      if ((width = parsefloat(fp, buf, buf + width)) == 0)
-+                      if ((width = parsefloat(fp, &pbuf, width, loc)) == 0) {
-+                              if (pbuf)
-+                                      free(pbuf);
++                      if ((width = parsefloat(fp, &pbuf, width, loc)) == 0)
                                goto match_failure;
-+                      }
                        if ((flags & SUPPRESS) == 0) {
                                if (flags & LONGDBL) {
 -                                      long double res = strtold(buf, &p);
                        }
                        nread += width;
 -                      nconversions++;
-+                      free(pbuf);
                        break;
 +              }
  #endif /* !NO_FLOATING_POINT */
  /*
   * Fill in the given table from the scanset at the given format
   * (just after `[').  Return a pointer to the character past the
-@@ -807,9 +853,10 @@
+@@ -807,9 +849,10 @@
   * considered part of the scanset.
   */
  static const u_char *
  {
        int c, n, v, i;
  
-@@ -845,6 +892,7 @@
+@@ -845,6 +888,7 @@
                        return (fmt - 1);
  
                case '-':
                        /*
                         * A scanset of the form
                         *      [01+-]
-@@ -865,8 +913,8 @@
+@@ -865,8 +909,8 @@
                         */
                        n = *fmt;
                        if (n == ']'
                               )
                           ) {
                                c = '-';
-@@ -874,14 +922,14 @@
+@@ -874,14 +918,14 @@
                        }
                        fmt++;
                        /* fill in the range */
                                           )
                                                tab[i] = v;
                        }
-@@ -901,7 +949,7 @@
+@@ -901,7 +945,7 @@
                                return (fmt);
  #endif
                        break;
                case ']':               /* end of scanset */
                        return (fmt);
  
-@@ -915,7 +963,7 @@
+@@ -915,18 +959,42 @@
  
  #ifndef NO_FLOATING_POINT
  static int
  {
        char *commit, *p;
        int infnanpos = 0;
-@@ -924,9 +972,18 @@
-               S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
+       enum {
+               S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX,
+-              S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
++              S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS, S_DECIMAL_POINT
        } state = S_START;
        unsigned char c;
 -      char decpt = *localeconv()->decimal_point;
-+      char decpt = *localeconv_l(loc)->decimal_point;
++      unsigned char *decpt = (unsigned char *)localeconv_l(loc)->decimal_point;
++      char *decpt_start;
        _Bool gotmantdig = 0, ishex = 0;
-+      char *b, *e;
+-
++      static char *b = NULL;
++      static size_t bsiz = 0;
++      char *e;
 +      size_t s;
-+      s = (width == 0 ? BUF : width + 1);
-+      b = (char *)malloc(s);
-+      if (b == NULL) {
-+              *buf = NULL;
-+              return 0;
++
++      if (bsiz = 0) {
++              b = (char *)malloc(BUF);
++              if (b == NULL) {
++                      *buf = NULL;
++                      return 0;
++              }
++              bsiz = BUF;
++      }
++      s = (width == 0 ? BUF : (width + 1));
++      if (s > bsiz) {
++              b = (char *)reallocf(b, s);
++              if (b == NULL) {
++                      bsiz = 0;
++                      *buf = NULL;
++                      return 0;
++              }
++              bsiz = s;
 +      }
 +      e = b + (s - 1);
        /*
         * We set commit = p whenever the string we have read so far
         * constitutes a valid representation of a floating point
-@@ -936,8 +993,8 @@
+@@ -936,8 +1004,8 @@
         * always necessary to read at least one character that doesn't
         * match; thus, we can't short-circuit "infinity" or "nan(...)".
         */
                c = *fp->_p;
  reswitch:
                switch (state) {
-@@ -997,7 +1054,7 @@
+@@ -997,7 +1065,7 @@
                                if (c == ')') {
                                        commit = p;
                                        infnanpos = -2;
                                        goto parsedone;
                                break;
                        }
-@@ -1013,7 +1070,7 @@
+@@ -1013,16 +1081,33 @@
                                goto reswitch;
                        }
                case S_DIGITS:
 +                      if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc))
                                gotmantdig = 1;
                        else {
-                               state = S_FRAC;
-@@ -1030,7 +1087,7 @@
+-                              state = S_FRAC;
+-                              if (c != decpt)
+-                                      goto reswitch;
++                              state = S_DECIMAL_POINT;
++                              decpt_start = p;
++                              goto reswitch;
+                       }
+                       if (gotmantdig)
+                               commit = p;
+                       break;
++              case S_DECIMAL_POINT:
++                      if (*decpt == 0) {
++                              if (gotmantdig)
++                                      commit = p - 1;
++                              state = S_FRAC;
++                              goto reswitch;
++                      }
++                      if (*decpt++ == c)
++                              break;
++                      /* not decimal point */
++                      state = S_FRAC;
++                      if (decpt_start == p)
++                              goto reswitch;
++                      while (decpt_start < --p)
++                              __ungetc(*(u_char *)p, fp);
++                      c = *(u_char *)p;
++                      goto reswitch;
+               case S_FRAC:
+                       if (((c == 'E' || c == 'e') && !ishex) ||
+                           ((c == 'P' || c == 'p') && ishex)) {
+@@ -1030,7 +1115,7 @@
                                        goto parsedone;
                                else
                                        state = S_EXP;
                                commit = p;
                                gotmantdig = 1;
                        } else
-@@ -1043,7 +1100,7 @@
+@@ -1043,7 +1128,7 @@
                        else
                                goto reswitch;
                case S_EXPDIGITS:
                                commit = p;
                        else
                                goto parsedone;
-@@ -1051,6 +1108,17 @@
+@@ -1051,6 +1136,21 @@
                default:
                        abort();
                }
 +              if (p >= e) {
-+                      size_t diff = (p - b);
++                      ssize_t diff = (p - b);
++                      ssize_t com = (commit - b);
 +                      s += BUF;
 +                      b = (char *)reallocf(b, s);
 +                      if (b == NULL) {
++                              bsiz = 0;
 +                              *buf = NULL;
 +                              return 0;
 +                      }
++                      bsiz = s;
 +                      e = b + (s - 1);
 +                      p = b + diff;
++                      commit = b + com;
 +              }
                *p++ = c;
                if (--fp->_r > 0)
                        fp->_p++;
-@@ -1062,6 +1130,7 @@
+@@ -1062,6 +1162,7 @@
        while (commit < --p)
                __ungetc(*(u_char *)p, fp);
        *++commit = '\0';