]> sourceware.org Git - glibc.git/commitdiff
stdlib: fix grouping verification with multi-byte thousands separator (bug 30964)
authorAndreas Schwab <schwab@suse.de>
Wed, 11 Oct 2023 14:22:16 +0000 (16:22 +0200)
committerAndreas Schwab <schwab@suse.de>
Thu, 12 Oct 2023 09:42:22 +0000 (11:42 +0200)
The grouping verification only worked for a single-byte thousands
separator.  With a multi-byte separator it returned as if no separators
were present.  The actual parsing in str_to_mpn will then go wrong when
there are multiple adjacent multi-byte separators in the number.

stdlib/grouping.c
stdlib/tst-strtod4.c

index b6bf1dbab2196485ed271f613707438defb02402..16b266d3e0c84a485d5afe7de14dadc33120c7c4 100644 (file)
@@ -59,7 +59,6 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
   size_t thousands_len = 1;
 #else
   size_t thousands_len = strlen (thousands);
-  int cnt;
 #endif
 
   while (end - begin >= thousands_len)
@@ -74,14 +73,8 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
          if (*cp == thousands)
            break;
 #else
-         if (cp[thousands_len - 1] == *thousands)
-           {
-             for (cnt = 1; thousands[cnt] != '\0'; ++cnt)
-               if (thousands[cnt] != cp[thousands_len - 1 - cnt])
-                 break;
-             if (thousands[cnt] == '\0')
-               break;
-           }
+         if (memcmp (cp, thousands, thousands_len) == 0)
+           break;
 #endif
          --cp;
        }
@@ -91,7 +84,7 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
       if (cp < begin)
        return end;
 
-      if (end - cp == (int) *gp + 1)
+      if (end - cp == (int) *gp + thousands_len)
        {
          /* This group matches the specification.  */
 
@@ -105,7 +98,7 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
             remainder of the string from BEGIN to NEW_END is the part we
             will consider if there is a grouping error in this trailing
             portion from CP to END.  */
-         new_end = cp - 1;
+         new_end = cp;
 
          /* Loop while the grouping is correct.  */
          while (1)
@@ -132,10 +125,7 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
                      if (*cp == thousands)
                        break;
 #else
-                     for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
-                       if (thousands[cnt] != cp[thousands_len - cnt - 1])
-                         break;
-                     if (thousands[cnt] == '\0')
+                     if (memcmp (cp, thousands, thousands_len) == 0)
                        break;
 #endif
                      --cp;
@@ -156,20 +146,17 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
                      if (*cp == thousands)
                        break;
 #else
-                     for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
-                       if (thousands[cnt] != cp[thousands_len - cnt - 1])
-                         break;
-                     if (thousands[cnt] == '\0')
+                     if (memcmp (cp, thousands, thousands_len) == 0)
                        break;
 #endif
                      --cp;
                    }
 
-                 if (cp < begin && group_end - cp <= (int) *gp)
+                 if (cp < begin && group_end - cp <= (int) *gp + thousands_len - 1)
                    /* Final group is correct.  */
                    return end;
 
-                 if (cp < begin || group_end - cp != (int) *gp)
+                 if (cp < begin || group_end - cp != (int) *gp + thousands_len - 1)
                    /* Incorrect group.  Punt.  */
                    break;
                }
@@ -183,8 +170,8 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
       else
        {
          /* Even the first group was wrong; determine maximum shift.  */
-         if (end - cp > (int) *gp + 1)
-           end = cp + (int) *gp + 1;
+         if (end - cp > (int) *gp + thousands_len)
+           end = cp + (int) *gp + thousands_len;
          else if (cp < begin)
            /* This number does not fill the first group, but is correct.  */
            return end;
index aae9835d82d38b4ee15fcc9cab9b4630aded4d06..6cc4e843c78a4ac08593b93704f837673d4b6a90 100644 (file)
@@ -13,7 +13,9 @@ static const struct
 } tests[] =
   {
     { "000"NNBSP"000"NNBSP"000", "", 0.0 },
-    { "1"NNBSP"000"NNBSP"000,5x", "x", 1000000.5 }
+    { "1"NNBSP"000"NNBSP"000,5x", "x", 1000000.5 },
+    /* Bug 30964 */
+    { "10"NNBSP NNBSP"200", NNBSP NNBSP"200", 10.0 }
   };
 #define NTESTS (sizeof (tests) / sizeof (tests[0]))
 
This page took 0.048766 seconds and 5 git commands to generate.