mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-08 14:20:07 +00:00
stdlib: fix grouping verification with multi-byte thousands separator (bug 30964)
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.
This commit is contained in:
parent
d846c28389
commit
69239bd7a2
@ -59,7 +59,6 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
|
|||||||
size_t thousands_len = 1;
|
size_t thousands_len = 1;
|
||||||
#else
|
#else
|
||||||
size_t thousands_len = strlen (thousands);
|
size_t thousands_len = strlen (thousands);
|
||||||
int cnt;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (end - begin >= thousands_len)
|
while (end - begin >= thousands_len)
|
||||||
@ -74,14 +73,8 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
|
|||||||
if (*cp == thousands)
|
if (*cp == thousands)
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
if (cp[thousands_len - 1] == *thousands)
|
if (memcmp (cp, thousands, thousands_len) == 0)
|
||||||
{
|
break;
|
||||||
for (cnt = 1; thousands[cnt] != '\0'; ++cnt)
|
|
||||||
if (thousands[cnt] != cp[thousands_len - 1 - cnt])
|
|
||||||
break;
|
|
||||||
if (thousands[cnt] == '\0')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
--cp;
|
--cp;
|
||||||
}
|
}
|
||||||
@ -91,7 +84,7 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
|
|||||||
if (cp < begin)
|
if (cp < begin)
|
||||||
return end;
|
return end;
|
||||||
|
|
||||||
if (end - cp == (int) *gp + 1)
|
if (end - cp == (int) *gp + thousands_len)
|
||||||
{
|
{
|
||||||
/* This group matches the specification. */
|
/* 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
|
remainder of the string from BEGIN to NEW_END is the part we
|
||||||
will consider if there is a grouping error in this trailing
|
will consider if there is a grouping error in this trailing
|
||||||
portion from CP to END. */
|
portion from CP to END. */
|
||||||
new_end = cp - 1;
|
new_end = cp;
|
||||||
|
|
||||||
/* Loop while the grouping is correct. */
|
/* Loop while the grouping is correct. */
|
||||||
while (1)
|
while (1)
|
||||||
@ -132,10 +125,7 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
|
|||||||
if (*cp == thousands)
|
if (*cp == thousands)
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
|
if (memcmp (cp, thousands, thousands_len) == 0)
|
||||||
if (thousands[cnt] != cp[thousands_len - cnt - 1])
|
|
||||||
break;
|
|
||||||
if (thousands[cnt] == '\0')
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
--cp;
|
--cp;
|
||||||
@ -156,20 +146,17 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
|
|||||||
if (*cp == thousands)
|
if (*cp == thousands)
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
|
if (memcmp (cp, thousands, thousands_len) == 0)
|
||||||
if (thousands[cnt] != cp[thousands_len - cnt - 1])
|
|
||||||
break;
|
|
||||||
if (thousands[cnt] == '\0')
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
--cp;
|
--cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cp < begin && group_end - cp <= (int) *gp)
|
if (cp < begin && group_end - cp <= (int) *gp + thousands_len - 1)
|
||||||
/* Final group is correct. */
|
/* Final group is correct. */
|
||||||
return end;
|
return end;
|
||||||
|
|
||||||
if (cp < begin || group_end - cp != (int) *gp)
|
if (cp < begin || group_end - cp != (int) *gp + thousands_len - 1)
|
||||||
/* Incorrect group. Punt. */
|
/* Incorrect group. Punt. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -183,8 +170,8 @@ __correctly_grouped_prefixmb (const STRING_TYPE *begin, const STRING_TYPE *end,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Even the first group was wrong; determine maximum shift. */
|
/* Even the first group was wrong; determine maximum shift. */
|
||||||
if (end - cp > (int) *gp + 1)
|
if (end - cp > (int) *gp + thousands_len)
|
||||||
end = cp + (int) *gp + 1;
|
end = cp + (int) *gp + thousands_len;
|
||||||
else if (cp < begin)
|
else if (cp < begin)
|
||||||
/* This number does not fill the first group, but is correct. */
|
/* This number does not fill the first group, but is correct. */
|
||||||
return end;
|
return end;
|
||||||
|
@ -13,7 +13,9 @@ static const struct
|
|||||||
} tests[] =
|
} tests[] =
|
||||||
{
|
{
|
||||||
{ "000"NNBSP"000"NNBSP"000", "", 0.0 },
|
{ "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]))
|
#define NTESTS (sizeof (tests) / sizeof (tests[0]))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user