On OSF/1 5.1, in the zh_CN.GB18030 locale, the test-mbsstr3.sh test fails. The reason is that 1) lib/mbrtowc.c has no particular code for the GB18030 encoding, 2) for an unknown encoding, it runs into an abort().
This fixes it. 2009-01-25 Bruno Haible <br...@clisp.org> * lib/mbrtowc.c (mbrtowc): Distinguish invalid and incomplete multibyte characters also for the GB18030 encoding. Don't crash when the encoding is unknown and nstate = 0. Needed on OSF/1 5.1. --- lib/mbrtowc.c.orig 2009-01-25 22:37:05.000000000 +0100 +++ lib/mbrtowc.c 2009-01-25 22:21:51.000000000 +0100 @@ -1,5 +1,5 @@ /* Convert multibyte character to wide character. - Copyright (C) 1999-2002, 2005-2008 Free Software Foundation, Inc. + Copyright (C) 1999-2002, 2005-2009 Free Software Foundation, Inc. Written by Bruno Haible <br...@clisp.org>, 2008. This program is free software: you can redistribute it and/or modify @@ -118,7 +118,7 @@ lack mbrtowc(), we use the second approach. The possible encodings are: - 8-bit encodings, - - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, SJIS, + - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS, - UTF-8. Use specialized code for each. */ if (m >= 4 || m >= MB_CUR_MAX) @@ -238,6 +238,39 @@ } goto invalid; } + if (STREQ (encoding, "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe)) + goto incomplete; + } + else /* m == 2 || m == 3 */ + { + unsigned char c = (unsigned char) p[0]; + + if (c >= 0x90 && c <= 0xe3) + { + unsigned char c2 = (unsigned char) p[1]; + + if (c2 >= 0x30 && c2 <= 0x39) + { + if (m == 2) + goto incomplete; + else /* m == 3 */ + { + unsigned char c3 = (unsigned char) p[2]; + + if (c3 >= 0x81 && c3 <= 0xfe) + goto incomplete; + } + } + } + } + goto invalid; + } if (STREQ (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0)) { if (m == 1) @@ -258,10 +291,14 @@ incomplete: { size_t k = nstate; - /* Here 0 < k < m < 4. */ + /* Here 0 <= k < m < 4. */ pstate[++k] = s[0]; if (k < m) - pstate[++k] = s[1]; + { + pstate[++k] = s[1]; + if (k < m) + pstate[++k] = s[2]; + } if (k != m) abort (); }