--- src/libc/wchar/_validutf8.c | 2 +- src/libc/wchar/mbrtowc.c | 21 +++++++++++++-------- src/libc/wchar/wcrtomb.c | 9 +++++++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/libc/wchar/_validutf8.c b/src/libc/wchar/_validutf8.c index 45b12fdc..c41afe26 100644 --- a/src/libc/wchar/_validutf8.c +++ b/src/libc/wchar/_validutf8.c _at_@ -23,7 +23,7 @@ _validutf8(wchar_t wc, int *nbytes) }; struct range *bp; - for (bp = ranges; bp->begin <= wc && bp->end > wc; ++bp) + for (bp = ranges; bp->begin > wc || bp->end <= wc; ++bp) ; *nbytes = bp->nbytes; diff --git a/src/libc/wchar/mbrtowc.c b/src/libc/wchar/mbrtowc.c index 6f825f8b..2cf27900 100644 --- a/src/libc/wchar/mbrtowc.c +++ b/src/libc/wchar/mbrtowc.c _at_@ -1,3 +1,4 @@ +#include <errno.h> #include <wchar.h> #include "../libc.h" _at_@ -8,37 +9,41 @@ size_t mbrtowc(wchar_t *restrict pwc, const char *restrict s, size_t n, mbstate_t *restrict ps) { - unsigned char *t = (unsigned char *) s; + const unsigned char *t = (const unsigned char *) s; unsigned long wc; unsigned c; int i, len, maxlen; - if (s == NULL) + if (s == NULL || *s == '\0') return 0; wc = c = *t++; for (len = 0; n > 0 && c & 0x80; --n, ++len) c <<= 1; - if (n == 0 || len == 1 || len == 8) - return -1; + if (n == 0 && c & 0x80) + return -2; + if (len == 1 || len == 8) + goto return_error; if (len == 0) goto return_code; wc = (c & 0xFF) >> len; for (i = 0; i < len-1; i++) { if (((c = *t++) & 0xC0) != 0x80) - return -1; + goto return_error; wc <<= 6; wc |= c & 0x3F; } if (!_validutf8(wc, &maxlen) || len != maxlen) - return -1; + goto return_error; return_code: if (pwc) *pwc = wc; - if (*s == '\0') - return 0; return t - (unsigned char *) s; + +return_error: + errno = EILSEQ; + return -1; } diff --git a/src/libc/wchar/wcrtomb.c b/src/libc/wchar/wcrtomb.c index b302266f..4c2a3014 100644 --- a/src/libc/wchar/wcrtomb.c +++ b/src/libc/wchar/wcrtomb.c _at_@ -14,13 +14,18 @@ wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict ps) if (!s) return 1; + if (c < 0x80) { + *s = wc; + return 1; + } + if (!_validutf8(wc, &n)) { errno = EILSEQ; return -1; } - n--; - *s = 0; + + *s = 0x80; for (i = 0; i < n; i++) { *s >>= 1; *s |= 0x80; -- 2.46.1 -- To unsubscribe send a mail to scc-dev+unsubscribe_at_simple-cc.orgReceived on Mon 10 Mar 2025 - 11:29:08 CET
This archive was generated by hypermail 2.3.0 : Mon 10 Mar 2025 - 11:40:02 CET