Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177400141
D61153.1794293321.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
8 KB
Referenced Files
None
Subscribers
None
D61153.1794293321.diff
View Options
diff --git a/lib/libc/tests/locale/Makefile b/lib/libc/tests/locale/Makefile
--- a/lib/libc/tests/locale/Makefile
+++ b/lib/libc/tests/locale/Makefile
@@ -6,6 +6,7 @@
ATF_TESTS_C+= mblen_test
ATF_TESTS_C+= mbrlen_test
ATF_TESTS_C+= mbrtoc16_test
+ATF_TESTS_C+= mbrtoc32_test
ATF_TESTS_C+= mbrtowc_2_test
ATF_TESTS_C+= mbsnrtowcs_2_test
ATF_TESTS_C+= mbsrtowcs_test
diff --git a/lib/libc/tests/locale/c16rtomb_test.c b/lib/libc/tests/locale/c16rtomb_test.c
--- a/lib/libc/tests/locale/c16rtomb_test.c
+++ b/lib/libc/tests/locale/c16rtomb_test.c
@@ -151,6 +151,29 @@
ATF_REQUIRE((unsigned char)buf[0] == 0xcc);
}
+ATF_TC_WITHOUT_HEAD(c16rtomb_gb18030_test);
+ATF_TC_BODY(c16rtomb_gb18030_test, tc)
+{
+ require_lc_ctype("zh_CN.GB18030");
+
+ /* U+0080, a four-byte character in the BMP. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ ATF_REQUIRE(c16rtomb(buf, 0x80, &s) == 4);
+ ATF_REQUIRE((unsigned char)buf[0] == 0x81 &&
+ (unsigned char)buf[1] == 0x30 && (unsigned char)buf[2] == 0x81 &&
+ (unsigned char)buf[3] == 0x30 && (unsigned char)buf[4] == 0xcc);
+
+ /* U+1F60B, outside the BMP. */
+ memset(&s, 0, sizeof(s));
+ memset(buf, 0xcc, sizeof(buf));
+ ATF_REQUIRE(c16rtomb(buf, 0xd83d, &s) == 0);
+ ATF_REQUIRE(c16rtomb(buf, 0xde0b, &s) == 4);
+ ATF_REQUIRE((unsigned char)buf[0] == 0x94 &&
+ (unsigned char)buf[1] == 0x39 && (unsigned char)buf[2] == 0xfd &&
+ (unsigned char)buf[3] == 0x37 && (unsigned char)buf[4] == 0xcc);
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -158,6 +181,7 @@
ATF_TP_ADD_TC(tp, c16rtomb_iso_8859_1_test);
ATF_TP_ADD_TC(tp, c16rtomb_iso_8859_15_test);
ATF_TP_ADD_TC(tp, c16rtomb_utf_8_test);
+ ATF_TP_ADD_TC(tp, c16rtomb_gb18030_test);
return (atf_no_error());
}
diff --git a/lib/libc/tests/locale/mbrtoc16_test.c b/lib/libc/tests/locale/mbrtoc16_test.c
--- a/lib/libc/tests/locale/mbrtoc16_test.c
+++ b/lib/libc/tests/locale/mbrtoc16_test.c
@@ -199,6 +199,42 @@
ATF_REQUIRE(c16 == 0x301);
}
+ATF_TC_WITHOUT_HEAD(mbrtoc16_gb18030_test);
+ATF_TC_BODY(mbrtoc16_gb18030_test, tc)
+{
+ require_lc_ctype("zh_CN.GB18030");
+
+ /* Double-byte character. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ ATF_REQUIRE(mbrtoc16(&c16, "\xb0\xa1", 2, &s) == 2);
+ ATF_REQUIRE(c16 == 0x554a);
+
+ /* Four-byte character in the BMP. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ ATF_REQUIRE(mbrtoc16(&c16, "\x81\x30\x81\x30", 4, &s) == 4);
+ ATF_REQUIRE(c16 == 0x80);
+
+ /* Four-byte character outside the BMP: surrogate pair. */
+ memset(&s, 0, sizeof(s));
+ c16 = 0;
+ ATF_REQUIRE(mbrtoc16(&c16, "\x94\x39\xfd\x37", 4, &s) == 4);
+ ATF_REQUIRE(c16 == 0xd83d);
+ ATF_REQUIRE(mbrtoc16(&c16, "", 0, &s) == (size_t)-3);
+ ATF_REQUIRE(c16 == 0xde0b);
+
+ /* Incomplete four-byte character. */
+ memset(&s, 0, sizeof(s));
+ ATF_REQUIRE(mbrtoc16(&c16, "\x94\x39", 2, &s) == (size_t)-2);
+
+ /* Invalid lead byte. */
+ memset(&s, 0, sizeof(s));
+ errno = 0;
+ ATF_REQUIRE(mbrtoc16(&c16, "\xff", 1, &s) == (size_t)-1);
+ ATF_REQUIRE(errno == EILSEQ);
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -206,6 +242,7 @@
ATF_TP_ADD_TC(tp, mbrtoc16_iso_8859_1_test);
ATF_TP_ADD_TC(tp, mbrtoc16_iso_8859_15_test);
ATF_TP_ADD_TC(tp, mbrtoc16_utf_8_test);
+ ATF_TP_ADD_TC(tp, mbrtoc16_gb18030_test);
return (atf_no_error());
}
diff --git a/lib/libc/tests/locale/mbrtoc32_test.c b/lib/libc/tests/locale/mbrtoc32_test.c
new file mode 100644
--- /dev/null
+++ b/lib/libc/tests/locale/mbrtoc32_test.c
@@ -0,0 +1,74 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+/*
+ * Test program for mbrtoc32() as specified by ISO/IEC 9899:2011.
+ */
+
+#include <atf-c.h>
+#include <errno.h>
+#include <locale.h>
+#include <string.h>
+#include <uchar.h>
+
+static void
+require_lc_ctype(const char *locale_name)
+{
+ char *lc_ctype_set;
+
+ lc_ctype_set = setlocale(LC_CTYPE, locale_name);
+ if (lc_ctype_set == NULL)
+ atf_tc_fail("setlocale(LC_CTYPE, \"%s\") failed; errno=%d",
+ locale_name, errno);
+
+ ATF_REQUIRE(strcmp(lc_ctype_set, locale_name) == 0);
+}
+
+static mbstate_t s;
+static char32_t c32;
+
+ATF_TC_WITHOUT_HEAD(mbrtoc32_gb18030_test);
+ATF_TC_BODY(mbrtoc32_gb18030_test, tc)
+{
+ require_lc_ctype("zh_CN.GB18030");
+
+ /* Double-byte character. */
+ memset(&s, 0, sizeof(s));
+ c32 = 0;
+ ATF_REQUIRE(mbrtoc32(&c32, "\xb0\xa1", 2, &s) == 2);
+ ATF_REQUIRE(c32 == 0x554a);
+
+ /* First, an arbitrary and last character outside the BMP. */
+ memset(&s, 0, sizeof(s));
+ c32 = 0;
+ ATF_REQUIRE(mbrtoc32(&c32, "\x90\x30\x81\x30", 4, &s) == 4);
+ ATF_REQUIRE(c32 == 0x10000);
+ memset(&s, 0, sizeof(s));
+ c32 = 0;
+ ATF_REQUIRE(mbrtoc32(&c32, "\x94\x39\xfd\x37", 4, &s) == 4);
+ ATF_REQUIRE(c32 == 0x1f60b);
+ memset(&s, 0, sizeof(s));
+ c32 = 0;
+ ATF_REQUIRE(mbrtoc32(&c32, "\xe3\x32\x9a\x35", 4, &s) == 4);
+ ATF_REQUIRE(c32 == 0x10ffff);
+
+ /* Well-formed, but beyond U+10FFFF. */
+ memset(&s, 0, sizeof(s));
+ errno = 0;
+ ATF_REQUIRE(mbrtoc32(&c32, "\xe3\x32\x9a\x36", 4, &s) == (size_t)-1);
+ ATF_REQUIRE(errno == EILSEQ);
+
+ /* Restarting in the middle of a four-byte character. */
+ memset(&s, 0, sizeof(s));
+ c32 = 0;
+ ATF_REQUIRE(mbrtoc32(&c32, "\x94\x39", 2, &s) == (size_t)-2);
+ ATF_REQUIRE(mbrtoc32(&c32, "\xfd\x37", 2, &s) == 2);
+ ATF_REQUIRE(c32 == 0x1f60b);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, mbrtoc32_gb18030_test);
+
+ return (atf_no_error());
+}
diff --git a/lib/libiconv_modules/GBK2K/citrus_gbk2k.c b/lib/libiconv_modules/GBK2K/citrus_gbk2k.c
--- a/lib/libiconv_modules/GBK2K/citrus_gbk2k.c
+++ b/lib/libiconv_modules/GBK2K/citrus_gbk2k.c
@@ -315,6 +315,20 @@
/* ISO646 */
*csid = 0;
*idx = (_index_t)wc;
+ } else if ((uint32_t)wc >= 0x90308130U) {
+ /* GB18030SUPP : 4-byte area mapped linearly onto U+10000- */
+ uint32_t b1, b2, b3, b4, ucs;
+
+ b1 = ((uint32_t)wc >> 24) & 0xFF;
+ b2 = ((uint32_t)wc >> 16) & 0xFF;
+ b3 = ((uint32_t)wc >> 8) & 0xFF;
+ b4 = (uint32_t)wc & 0xFF;
+ ucs = 0x10000 + ((((b1 - 0x90) * 10 + (b2 - 0x30)) * 126 +
+ (b3 - 0x81)) * 10 + (b4 - 0x30));
+ if (b1 > 0xE3 || ucs > 0x10FFFF)
+ return (EILSEQ);
+ *csid = 4;
+ *idx = (_index_t)ucs;
} else if ((uint32_t)wc >= 0x10000) {
/* GBKUCS : XXX */
*csid = 3;
@@ -361,6 +375,19 @@
return (EINVAL);
*wc = (wchar_t)idx;
break;
+ case 4:
+ /* GB18030SUPP */
+ if (ei->mb_cur_max != 4 || idx < 0x10000 || idx > 0x10FFFF)
+ return (EILSEQ);
+ idx -= 0x10000;
+ *wc = (wchar_t)(0x30 + idx % 10);
+ idx /= 10;
+ *wc |= (wchar_t)((0x81 + idx % 126) << 8);
+ idx /= 126;
+ *wc |= (wchar_t)((0x30 + idx % 10) << 16);
+ idx /= 10;
+ *wc |= (wchar_t)((uint32_t)(0x90 + idx) << 24);
+ break;
default:
return (EILSEQ);
}
diff --git a/share/i18n/csmapper/GB/charset.pivot.GB.src b/share/i18n/csmapper/GB/charset.pivot.GB.src
--- a/share/i18n/csmapper/GB/charset.pivot.GB.src
+++ b/share/i18n/csmapper/GB/charset.pivot.GB.src
@@ -7,6 +7,7 @@
GB2312:GB18030 UCS 1
GBK UCS 1
GBK:GB18030 UCS 1
+GB18030SUPP UCS 1
GBKUCS UCS 1
ISO-IR-165 UCS 1
UCS GB12345 1
@@ -16,5 +17,6 @@
UCS GB2312:GB18030 1
UCS GBK 1
UCS GBK:GB18030 1
+UCS GB18030SUPP 1
UCS GBKUCS 1
UCS ISO-IR-165 1
diff --git a/share/i18n/csmapper/GB/mapper.dir.GB.src b/share/i18n/csmapper/GB/mapper.dir.GB.src
--- a/share/i18n/csmapper/GB/mapper.dir.GB.src
+++ b/share/i18n/csmapper/GB/mapper.dir.GB.src
@@ -9,6 +9,7 @@
GBKEXT/UCS mapper_std GB/GBKEXT%UCS.mps
GBKUDA/UCS mapper_std GB/GBKUDA%UCS.mps
GB18030/UCS:BMP mapper_std GB/GB18030%UCS@BMP.mps
+GB18030SUPP/UCS mapper_zone 0x10000 - 0x10FFFF
ISO-IR-165EXT/UCS mapper_std GB/ISO-IR-165EXT%UCS.mps
GB2312:CP936/UCS mapper_parallel GB2312EXT/UCS,GB2312GBK/UCS
GB2312:GBK/UCS mapper_parallel GB2312UDA1/UCS,GB2312:CP936/UCS
@@ -25,6 +26,7 @@
UCS/GBKEXT mapper_std GB/UCS%GBKEXT.mps
UCS/GBKUDA mapper_std GB/UCS%GBKUDA.mps
UCS:BMP/GB18030 mapper_std GB/UCS@BMP%GB18030.mps
+UCS/GB18030SUPP mapper_zone 0x10000 - 0x10FFFF
UCS/ISO-IR-165EXT mapper_std GB/UCS%ISO-IR-165EXT.mps
UCS/GB2312GBK mapper_parallel UCS/GBKEXT,UCS/GB2312
UCS/GB2312:CP936 mapper_parallel UCS/GB2312GBK,UCS/GB2312EXT
diff --git a/share/i18n/esdb/GB/GB18030.src b/share/i18n/esdb/GB/GB18030.src
--- a/share/i18n/esdb/GB/GB18030.src
+++ b/share/i18n/esdb/GB/GB18030.src
@@ -7,4 +7,5 @@
DEFCSID "GBKUCS" 3
DEFCSID "GBK:GB18030" 2
DEFCSID "GB2312:GB18030" 1
+DEFCSID "GB18030SUPP" 4
INVALID 0x3F # '?'
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 10, 6:48 AM (6 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41630827
Default Alt Text
D61153.1794293321.diff (8 KB)
Attached To
Mode
D61153: libiconv/gbk2k: Handle GB18030SUPP correctly.
Attached
Detach File
Event Timeline