From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2138) id CC1923858CDA; Thu, 12 Oct 2023 09:43:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CC1923858CDA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1697103817; bh=neXCTG2jC8Ec1ikR6K1Om67M8/vTzHZKsKpcyZtUgJA=; h=From:To:Subject:Date:From; b=CAeKsLlIAn74WZgvboCS8vE/qxu92h/y2/tEF/dGtrtLt4yEyLYDSEwNLBI7CB3Ys Ln+T+11cOYtB4wE8C07KmWjZAVeO37hSyn4NXqZf7HwbsLU10zfNfvhUX7Xb1IrAJa BF5PaH41QN20a4QrobvDCXcqNh/WAYMvqPRzN3mo= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Andreas Schwab To: glibc-cvs@sourceware.org Subject: [glibc] stdlib: fix grouping verification with multi-byte thousands separator (bug 30964) X-Act-Checkin: glibc X-Git-Author: Andreas Schwab X-Git-Refname: refs/heads/master X-Git-Oldrev: d846c2838942297c9644f2f38bdad0fb88f42245 X-Git-Newrev: 69239bd7a216007692470aa9d5f3658024638742 Message-Id: <20231012094337.CC1923858CDA@sourceware.org> Date: Thu, 12 Oct 2023 09:43:37 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=69239bd7a216007692470aa9d5f3658024638742 commit 69239bd7a216007692470aa9d5f3658024638742 Author: Andreas Schwab Date: Wed Oct 11 16:22:16 2023 +0200 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. Diff: --- 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]))