From 6bc5c0e01ba63d0fd8557d26fb468a2e61f129da Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 26 Dec 2019 00:50:12 -0800 Subject: [PATCH] mbrtowc: port better to narrow-wchar_t platforms MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * lib/mbrtowc.c (mbrtowc): On platforms like AIX 7.2, where wchar_t is too narrow to represent all the Unicode characters, consider a byte sequence for an out-of-wchar_t-range character to be an encoding error. This fixes grep’s surrogate-pair test failure on AIX 7.2. --- ChangeLog | 9 +++++++++ lib/mbrtowc.c | 37 ++++++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 40f74abdde..70b46625fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2019-12-26 Paul Eggert + + mbrtowc: port better to narrow-wchar_t platforms + * lib/mbrtowc.c (mbrtowc): On platforms like AIX 7.2, where + wchar_t is too narrow to represent all the Unicode characters, + consider a byte sequence for an out-of-wchar_t-range character to + be an encoding error. This fixes grep’s surrogate-pair test + failure on AIX 7.2. + 2019-12-24 Bruno Haible localcharset: Avoid referencing rpl_setlocale on native Windows. diff --git a/lib/mbrtowc.c b/lib/mbrtowc.c index 1aad22cd5a..38301dfbae 100644 --- a/lib/mbrtowc.c +++ b/lib/mbrtowc.c @@ -214,12 +214,17 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) if ((c3 ^ 0x80) < 0x40) { - if (pwc != NULL) - *pwc = ((unsigned int) (c & 0x0f) << 12) - | ((unsigned int) (c2 ^ 0x80) << 6) - | (unsigned int) (c3 ^ 0x80); - res = 3; - goto success; + unsigned int wc + = (((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (c2 ^ 0x80) << 6) + | (unsigned int) (c3 ^ 0x80)); + if (wc <= WCHAR_MAX) + { + if (pwc != NULL) + *pwc = wc; + res = 3; + goto success; + } } } } @@ -253,13 +258,19 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) if ((c4 ^ 0x80) < 0x40) { - if (pwc != NULL) - *pwc = ((unsigned int) (c & 0x07) << 18) - | ((unsigned int) (c2 ^ 0x80) << 12) - | ((unsigned int) (c3 ^ 0x80) << 6) - | (unsigned int) (c4 ^ 0x80); - res = 4; - goto success; + unsigned int wc + = (((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (c2 ^ 0x80) + << 12) + | ((unsigned int) (c3 ^ 0x80) << 6) + | (unsigned int) (c4 ^ 0x80)); + if (wc <= WCHAR_MAX) + { + if (pwc != NULL) + *pwc = wc; + res = 4; + goto success; + } } } } -- 2.39.5