From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H2 autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 29620 invoked from network); 4 Jan 2023 15:07:38 -0000 Received: from second.openwall.net (193.110.157.125) by inbox.vuxu.org with ESMTPUTF8; 4 Jan 2023 15:07:38 -0000 Received: (qmail 32503 invoked by uid 550); 4 Jan 2023 15:07:34 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 32460 invoked from network); 4 Jan 2023 15:07:33 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=25KJwX7jfRaoiFaEj60DWVOIZp97tvjmBUt4ohrfVoc=; b=AxZkqABh1z4ldHcMP+5dIDgNteYREsHXsT4+MYOJPCPGB4X6PL10BSQE7lGl+EIBM9 4Uf4rO1jAzd+kLQIdyDBo29NAVqijqnKstJgNooxNfEFfieGGzdJNlnCsUMvzYqX2Me9 QVNDUnurE4KFERAoE7CHXAhsw3i57UQLuWMBRN+PWD/UVy+18EaasRYGKB182OBkp7S6 Ak82GKfAUASZbTjyZCJkP9NZ7H5L2ghv44Y9uqJ52ayH7IonMmwJyR/Oxk3sxL3nuza1 f/kpXJfSbRpRBLdDpunqj+wLC31ktjQU+bugQ7r0ZisdkBYDS8zPkaBwni6hvOCWl6SO OlnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=25KJwX7jfRaoiFaEj60DWVOIZp97tvjmBUt4ohrfVoc=; b=y4+k//u+zWAx0cWDynTmS/Iq5X/tCclaHS7FLl75PP/12rWcLtnpJE1WeaEs+hKM5r wxuR+T2F8Hw0C78JtUF+RyF1iv/WYKagasOe7pfxOY2QTJlnx2VgFoW2Tw630KGHbl+W PCWslUfDNxPZXnf11Aes/OBlJnvK4s9sdPALkYsiZlSqO0bABuzqwIHr1oGlG4qs9yTZ NnDzrxqJMio+mgwMgrh+3Ox2Qf/PSbz0/fH3jy9OQtA5RNQY2fmouC6kFZLlZab2c7Zh 31e4K/5uVDLecFX04sUkJQCtOlZ6+djVf9RMq8Cl3cHfMEBUeTKp391fwVi/rvjfGBoV siAg== X-Gm-Message-State: AFqh2kpe6bX93JepSZqk0nmOAHlYhgS6/m3mMpOcc8c0YY5eVvJ375+9 eD2RKh3z8q0Wa9FFZahECbBZ8wz/JcjxvQ== X-Google-Smtp-Source: AMrXdXvI44RUu7W7LfuMuGn7Tp+5h2sHcAequ/FaMTVVE5oUjyG/S7Mx82/6+dLnk3TcMEYCgyxE8A== X-Received: by 2002:adf:ed8d:0:b0:242:643e:6954 with SMTP id c13-20020adfed8d000000b00242643e6954mr31344845wro.14.1672844842043; Wed, 04 Jan 2023 07:07:22 -0800 (PST) From: Gabriel Ravier To: musl@lists.openwall.com Cc: Gabriel Ravier Date: Wed, 4 Jan 2023 16:07:19 +0100 Message-Id: <20230104150719.252185-1-gabravier@gmail.com> X-Mailer: git-send-email 2.38.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [musl] [PATCH] fix return value of wcs{,n}cmp for near-limits signed wchar_t values 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 #include 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