summaryrefslogtreecommitdiff
path: root/backport-stdlib-fix-grouping-verification-with-multi-byte-tho.patch
diff options
context:
space:
mode:
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.patch131
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
+