Hello tech@,

Currently we accept codepoints 0-0xff in citrus_none, but the C/POSIX
locale use 7 bit ascii, allowing us currently to return unspecified
values. From code-inspection, NetBSD does the same thing we do (since
they also use citrus, that's to be expected), but FreeBSD (from code-
inspection) and glibc (from testing) return EILSEQ on >0x7f.

Changing this also allows us to drop a few (now useless) casts and a
wrapper-function.

This change will make the CSI case for regress/lib/libc/locale/wcrtomb
fail, but that's easy enough to fix.

OK (after unlock)?

martijn@

Index: citrus_none.c
===================================================================
RCS file: /cvs/src/lib/libc/citrus/citrus_none.c,v
retrieving revision 1.9
diff -u -p -r1.9 citrus_none.c
--- citrus_none.c       7 Sep 2016 17:10:43 -0000       1.9
+++ citrus_none.c       18 Apr 2021 14:40:59 -0000
@@ -35,22 +35,6 @@
 
 #include "citrus_ctype.h"
 
-static char     wrapv(unsigned char);
-
-
-/*
- * Convert an unsigned char value into a char value without relying on
- * signed overflow behavior.
- */
-static char
-wrapv(unsigned char ch)
-{
-       if (ch >= 0x80)
-               return (int)ch - 0x100;
-       else
-               return ch;
-}
-
 size_t
 _citrus_none_ctype_mbrtowc(wchar_t * __restrict pwc,
     const char * __restrict s, size_t n)
@@ -59,8 +43,12 @@ _citrus_none_ctype_mbrtowc(wchar_t * __r
                return 0;
        if (n == 0)
                return -2;
+       if (*s > 0x7f) {
+               errno = EILSEQ;
+               return -1;
+       }
        if (pwc != NULL)
-               *pwc = (wchar_t)(unsigned char)*s;
+               *pwc = (wchar_t)*s;
        return *s != '\0';
 }
 
@@ -74,7 +62,11 @@ _citrus_none_ctype_mbsnrtowcs(wchar_t * 
                return strnlen(*src, nmc);
 
        for (i = 0; i < nmc && i < len; i++)
-               if ((dst[i] = (wchar_t)(unsigned char)(*src)[i]) == L'\0') {
+               if ((*src)[i] > 0x7f) {
+                       errno = EILSEQ;
+                       return -1;
+               }
+               if ((dst[i] = (wchar_t)(*src)[i]) == L'\0') {
                        *src = NULL;
                        return i;
                }
@@ -89,12 +81,12 @@ _citrus_none_ctype_wcrtomb(char * __rest
        if (s == NULL)
                return 1;
 
-       if (wc < 0 || wc > 0xff) {
+       if (wc < 0 || wc > 0x7f) {
                errno = EILSEQ;
                return -1;
        }
 
-       *s = wrapv(wc);
+       *s = (char)wc;
        return 1;
 }
 
@@ -107,7 +99,7 @@ _citrus_none_ctype_wcsnrtombs(char * __r
        if (dst == NULL) {
                for (i = 0; i < nwc; i++) {
                        wchar_t wc = (*src)[i];
-                       if (wc < 0 || wc > 0xff) {
+                       if (wc < 0 || wc > 0x7f) {
                                errno = EILSEQ;
                                return -1;
                        }
@@ -119,12 +111,12 @@ _citrus_none_ctype_wcsnrtombs(char * __r
 
        for (i = 0; i < nwc && i < len; i++) {
                wchar_t wc = (*src)[i];
-               if (wc < 0 || wc > 0xff) {
+               if (wc < 0 || wc > 0x7f) {
                        *src += i;
                        errno = EILSEQ;
                        return -1;
                }
-               dst[i] = wrapv(wc);
+               dst[i] = (char)wc;
                if (wc == L'\0') {
                        *src = NULL;
                        return i;


Reply via email to