mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Gabriel Ravier <gabravier@gmail.com>
To: musl@lists.openwall.com
Cc: Gabriel Ravier <gabravier@gmail.com>
Subject: [musl] [PATCH] fix return value of wcs{,n}cmp for near-limits signed wchar_t values
Date: Wed,  4 Jan 2023 16:07:19 +0100	[thread overview]
Message-ID: <20230104150719.252185-1-gabravier@gmail.com> (raw)

The standard states that:

  > Unless explicitly stated otherwise, the functions described in
    this subclause order two wide characters the same way as two
    integers of the underlying integer type designated by `wchar_t`.
  > [...]
  > The `wcscmp` function returns an integer greater than, equal to,
    or less than zero, accordingly as the wide string pointed to by s1
    is greater than, equal to, or less than the wide string pointed to
    by s2.
  > The `wcsncmp` function returns an integer greater than, equal to,
    or less than zero, accordingly as the possibly null-terminated
    array pointed to by s1 is greater than, equal to, or less than the
    possibly null-terminated array pointed to by s2
  - N3047 (latest C draft as of the time of writing)

Yet a simple test program such as this:

    #include <wchar.h>
    #include <stdio.h>

    int main()
    {
        wchar_t str1[2] = { WCHAR_MAX, L'\0' };
        wchar_t str2[2] = { WCHAR_MIN, L'\0' };

        printf("%d\n", wcscmp(str1, str2));
        printf("%d\n", wcsncmp(str1, str2, 1));
    }

Will fail to run correctly according to this specification on musl (on
targets that have signed wchar_t), as it will print -1 instead of
1 (it should print 1, since WCHAR_MAX > WCHAR_MIN).

This appears to be due to the fact that musl uses a simple subtraction
to implement wcscmp and wcsncmp, which may result in an overflow.

This patch fixes this by replacing the subtraction with a little bit
of code that orders the characters correctly, returning -1 if the
character from the first string is smaller than the one from the
second, 0 if they are equal and 1 if the character from the first
string is larger than the one from the second
---
 src/string/wcscmp.c  | 2 +-
 src/string/wcsncmp.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/string/wcscmp.c b/src/string/wcscmp.c
index 26eeee70..286ec3ea 100644
--- a/src/string/wcscmp.c
+++ b/src/string/wcscmp.c
@@ -3,5 +3,5 @@
 int wcscmp(const wchar_t *l, const wchar_t *r)
 {
 	for (; *l==*r && *l && *r; l++, r++);
-	return *l - *r;
+	return *l < *r ? -1 : *l > *r;
 }
diff --git a/src/string/wcsncmp.c b/src/string/wcsncmp.c
index 4ab32a92..2b3558bf 100644
--- a/src/string/wcsncmp.c
+++ b/src/string/wcsncmp.c
@@ -3,5 +3,5 @@
 int wcsncmp(const wchar_t *l, const wchar_t *r, size_t n)
 {
 	for (; n && *l==*r && *l && *r; n--, l++, r++);
-	return n ? *l - *r : 0;
+	return n ? (*l < *r ? -1 : *l > *r) : 0;
 }
-- 
2.38.1


             reply	other threads:[~2023-01-04 15:07 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-04 15:07 Gabriel Ravier [this message]
2023-01-06  9:20 ` Markus Wichmann
2023-01-06  9:31   ` Markus Wichmann
2023-01-06 11:17   ` Rich Felker
2023-01-06 16:57     ` Markus Wichmann
2023-01-07  1:51       ` Gabriel Ravier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230104150719.252185-1-gabravier@gmail.com \
    --to=gabravier@gmail.com \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).