about summary refs log tree commit diff
path: root/src/locale
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-06-18 21:41:38 -0400
committerRich Felker <dalias@aerifal.cx>2012-06-18 21:41:38 -0400
commit26710be7148d51a954c4fe4acedab90d161e609a (patch)
tree62a9d951af316883fc531603065f9f2a9d5cff1d /src/locale
parent673633c689989c5cb7ba0b919f8ef82c4041e2ec (diff)
downloadmusl-26710be7148d51a954c4fe4acedab90d161e609a.tar.gz
musl-26710be7148d51a954c4fe4acedab90d161e609a.tar.xz
musl-26710be7148d51a954c4fe4acedab90d161e609a.zip
fix multiple iconv bugs reading utf-16/32 and wchar_t
Diffstat (limited to 'src/locale')
-rw-r--r--src/locale/iconv.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/src/locale/iconv.c b/src/locale/iconv.c
index 78c215e1..508d322e 100644
--- a/src/locale/iconv.c
+++ b/src/locale/iconv.c
@@ -12,8 +12,8 @@
 #define UTF_32LE    0303
 #define UCS2BE      0304
 #define UCS2LE      0305
-#define US_ASCII    0306
-#define WCHAR_T     0307
+#define WCHAR_T     0306
+#define US_ASCII    0307
 #define UTF_8       0310
 #define EUC_JP      0320
 #define SHIFT_JIS   0321
@@ -34,14 +34,14 @@
 
 static const unsigned char charmaps[] =
 "utf8\0\0\310"
-"wchart\0\0\307"
+"wchart\0\0\306"
 "ucs2\0ucs2be\0\0\304"
 "ucs2le\0\0\305"
 "utf16\0utf16be\0\0\302"
 "utf16le\0\0\301"
 "ucs4\0ucs4be\0utf32\0utf32be\0\0\300"
 "ucs4le\0utf32le\0\0\303"
-"ascii\0usascii\0iso646\0iso646us\0\0\306"
+"ascii\0usascii\0iso646\0iso646us\0\0\307"
 "eucjp\0\0\320"
 "shiftjis\0sjis\0\0\321"
 "gb18030\0\0\330"
@@ -161,7 +161,7 @@ size_t iconv(iconv_t cd0, char **in, size_t *inb, char **out, size_t *outb)
 		c = *(unsigned char *)*in;
 		l = 1;
 
-		if (c >= 128) switch (type) {
+		if (c >= 128 || type-UTF_32BE < 7U) switch (type) {
 		case UTF_8:
 			l = mbrtowc_utf8(&wc, *in, *inb, &st);
 			if (!l) l++;
@@ -196,9 +196,9 @@ size_t iconv(iconv_t cd0, char **in, size_t *inb, char **out, size_t *outb)
 				if (type-UCS2BE < 2U) goto ilseq;
 				l = 4;
 				if (*inb < 4) goto starved;
-				d = get_16((void *)(*in + 2), from);
-				if ((unsigned)(c-0xdc00) >= 0x400) goto ilseq;
-				c = ((c-0xd800)<<10) | (d-0xdc00);
+				d = get_16((void *)(*in + 2), type);
+				if ((unsigned)(d-0xdc00) >= 0x400) goto ilseq;
+				c = ((c-0xd7c0)<<10) + (d-0xdc00);
 			}
 			break;
 		case SHIFT_JIS: