From e03c010c4da26c351bc182568622cc88a926f3b6 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sat, 9 Jan 2021 00:45:51 +0000 Subject: [PATCH] Fix for non-UTF-8 wide charsets (Solaris patch 050-CR7065478) This upstreams a Solaris patch: https://github.com/oracle/solaris-userland/blob/master/components/ksh93/patches/050-CR7065478.patch src/lib/libast/comp/setlocale.c: - Add wide_wctomb() wrapper for wctomb(3). It changes an invalid character (wctomb returns -1) to a single byte with length 1. - set_ctype(): Use wide_wctomb() instead of wctomb(3) as the conversion discipline function (ast.mb_conv). Effectively this means there are no invalid characters. Perhaps this is necessary for compatibility with ASCII. Sadly, no public info available. --- src/lib/libast/comp/setlocale.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/lib/libast/comp/setlocale.c b/src/lib/libast/comp/setlocale.c index 65553f8bb..013f4ef51 100644 --- a/src/lib/libast/comp/setlocale.c +++ b/src/lib/libast/comp/setlocale.c @@ -2217,6 +2217,23 @@ iswalpha(wchar_t c) typedef int (*Isw_f)(wchar_t); +static int +wide_wctomb(char* u, wchar_t w) +{ + int size = 0; + + if (u) + { + size = wctomb(u, w); + if (size < 0) + { + *u = (char)(w & 0xff); + size = 1; + } + } + return size; +} + /* * called when LC_CTYPE initialized or changes */ @@ -2261,7 +2278,7 @@ set_ctype(Lc_category_t* cp) { if (!(ast.mb_width = wcwidth)) ast.mb_width = default_wcwidth; - ast.mb_conv = wctomb; + ast.mb_conv = wide_wctomb; #ifdef mb_state { /*