diff options
Diffstat (limited to 'backport-stdlib-fix-grouping-verification-with-multi-byte-tho.patch')
-rw-r--r-- | backport-stdlib-fix-grouping-verification-with-multi-byte-tho.patch | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/backport-stdlib-fix-grouping-verification-with-multi-byte-tho.patch b/backport-stdlib-fix-grouping-verification-with-multi-byte-tho.patch new file mode 100644 index 0000000..196707b --- /dev/null +++ b/backport-stdlib-fix-grouping-verification-with-multi-byte-tho.patch @@ -0,0 +1,131 @@ +From 69239bd7a216007692470aa9d5f3658024638742 Mon Sep 17 00:00:00 2001 +From: Andreas Schwab <schwab@suse.de> +Date: Wed, 11 Oct 2023 16:22:16 +0200 +Subject: [PATCH] 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. + +Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=69239bd7a216007692470aa9d5f3658024638742 +Conflict:NA + +--- + stdlib/grouping.c | 33 ++++++++++----------------------- + stdlib/tst-strtod4.c | 4 +++- + 2 files changed, 13 insertions(+), 24 deletions(-) + +diff --git a/stdlib/grouping.c b/stdlib/grouping.c +index b6bf1dbab2..16b266d3e0 100644 +--- a/stdlib/grouping.c ++++ b/stdlib/grouping.c +@@ -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; +diff --git a/stdlib/tst-strtod4.c b/stdlib/tst-strtod4.c +index aae9835d82..6cc4e843c7 100644 +--- a/stdlib/tst-strtod4.c ++++ b/stdlib/tst-strtod4.c +@@ -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])) + +-- +2.37.3.1 + |