aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 15:09:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 15:09:47 -0500
commit55b81e6f2795484ea8edf5805c95c007cacfa736 (patch)
treec3724975107857fcc03b5dd649c462e4f72397be /fs
parent5983faf942f260023e547f3c5f38c1033c35cc9b (diff)
parent08e87d0d773dc9ca5faf4c3306e238ed0ea129b0 (diff)
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (232 commits) USB: Add USB-ID for Multiplex RC serial adapter to cp210x.c xhci: Clean up 32-bit build warnings. USB: update documentation for usbmon usb: usb-storage doesn't support dynamic id currently, the patch disables the feature to fix an oops drivers/usb/class/cdc-acm.c: clear dangling pointer drivers/usb/dwc3/dwc3-pci.c: introduce missing kfree drivers/usb/host/isp1760-if.c: introduce missing kfree usb: option: add ZD Incorporated HSPA modem usb: ch9: fix up MaxStreams helper USB: usb-skeleton.c: cleanup open_count USB: usb-skeleton.c: fix open/disconnect race xhci: Properly handle COMP_2ND_BW_ERR USB: remove dead code from suspend/resume path USB: add quirk for another camera drivers: usb: wusbcore: Fix dependency for USB_WUSB xhci: Better debugging for critical host errors. xhci: Be less verbose during URB cancellation. xhci: Remove debugging about ring structure allocation. xhci: Remove debugging about toggling cycle bits. xhci: Remove debugging for individual transfers. ...
Diffstat (limited to 'fs')
-rw-r--r--fs/fat/namei_vfat.c3
-rw-r--r--fs/nls/nls_base.c73
2 files changed, 50 insertions, 26 deletions
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 3a444b4e2368..a81eb2367d39 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -512,7 +512,8 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
512 int charlen; 512 int charlen;
513 513
514 if (utf8) { 514 if (utf8) {
515 *outlen = utf8s_to_utf16s(name, len, (wchar_t *)outname); 515 *outlen = utf8s_to_utf16s(name, len, UTF16_HOST_ENDIAN,
516 (wchar_t *) outname, FAT_LFN_LEN + 2);
516 if (*outlen < 0) 517 if (*outlen < 0)
517 return *outlen; 518 return *outlen;
518 else if (*outlen > FAT_LFN_LEN) 519 else if (*outlen > FAT_LFN_LEN)
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index 44a88a9fa2c8..fea6bd5831dc 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -52,7 +52,7 @@ static const struct utf8_table utf8_table[] =
52#define SURROGATE_LOW 0x00000400 52#define SURROGATE_LOW 0x00000400
53#define SURROGATE_BITS 0x000003ff 53#define SURROGATE_BITS 0x000003ff
54 54
55int utf8_to_utf32(const u8 *s, int len, unicode_t *pu) 55int utf8_to_utf32(const u8 *s, int inlen, unicode_t *pu)
56{ 56{
57 unsigned long l; 57 unsigned long l;
58 int c0, c, nc; 58 int c0, c, nc;
@@ -71,7 +71,7 @@ int utf8_to_utf32(const u8 *s, int len, unicode_t *pu)
71 *pu = (unicode_t) l; 71 *pu = (unicode_t) l;
72 return nc; 72 return nc;
73 } 73 }
74 if (len <= nc) 74 if (inlen <= nc)
75 return -1; 75 return -1;
76 s++; 76 s++;
77 c = (*s ^ 0x80) & 0xFF; 77 c = (*s ^ 0x80) & 0xFF;
@@ -83,7 +83,7 @@ int utf8_to_utf32(const u8 *s, int len, unicode_t *pu)
83} 83}
84EXPORT_SYMBOL(utf8_to_utf32); 84EXPORT_SYMBOL(utf8_to_utf32);
85 85
86int utf32_to_utf8(unicode_t u, u8 *s, int maxlen) 86int utf32_to_utf8(unicode_t u, u8 *s, int maxout)
87{ 87{
88 unsigned long l; 88 unsigned long l;
89 int c, nc; 89 int c, nc;
@@ -97,7 +97,7 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxlen)
97 return -1; 97 return -1;
98 98
99 nc = 0; 99 nc = 0;
100 for (t = utf8_table; t->cmask && maxlen; t++, maxlen--) { 100 for (t = utf8_table; t->cmask && maxout; t++, maxout--) {
101 nc++; 101 nc++;
102 if (l <= t->lmask) { 102 if (l <= t->lmask) {
103 c = t->shift; 103 c = t->shift;
@@ -114,34 +114,57 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxlen)
114} 114}
115EXPORT_SYMBOL(utf32_to_utf8); 115EXPORT_SYMBOL(utf32_to_utf8);
116 116
117int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs) 117static inline void put_utf16(wchar_t *s, unsigned c, enum utf16_endian endian)
118{
119 switch (endian) {
120 default:
121 *s = (wchar_t) c;
122 break;
123 case UTF16_LITTLE_ENDIAN:
124 *s = __cpu_to_le16(c);
125 break;
126 case UTF16_BIG_ENDIAN:
127 *s = __cpu_to_be16(c);
128 break;
129 }
130}
131
132int utf8s_to_utf16s(const u8 *s, int inlen, enum utf16_endian endian,
133 wchar_t *pwcs, int maxout)
118{ 134{
119 u16 *op; 135 u16 *op;
120 int size; 136 int size;
121 unicode_t u; 137 unicode_t u;
122 138
123 op = pwcs; 139 op = pwcs;
124 while (*s && len > 0) { 140 while (inlen > 0 && maxout > 0 && *s) {
125 if (*s & 0x80) { 141 if (*s & 0x80) {
126 size = utf8_to_utf32(s, len, &u); 142 size = utf8_to_utf32(s, inlen, &u);
127 if (size < 0) 143 if (size < 0)
128 return -EINVAL; 144 return -EINVAL;
145 s += size;
146 inlen -= size;
129 147
130 if (u >= PLANE_SIZE) { 148 if (u >= PLANE_SIZE) {
149 if (maxout < 2)
150 break;
131 u -= PLANE_SIZE; 151 u -= PLANE_SIZE;
132 *op++ = (wchar_t) (SURROGATE_PAIR | 152 put_utf16(op++, SURROGATE_PAIR |
133 ((u >> 10) & SURROGATE_BITS)); 153 ((u >> 10) & SURROGATE_BITS),
134 *op++ = (wchar_t) (SURROGATE_PAIR | 154 endian);
155 put_utf16(op++, SURROGATE_PAIR |
135 SURROGATE_LOW | 156 SURROGATE_LOW |
136 (u & SURROGATE_BITS)); 157 (u & SURROGATE_BITS),
158 endian);
159 maxout -= 2;
137 } else { 160 } else {
138 *op++ = (wchar_t) u; 161 put_utf16(op++, u, endian);
162 maxout--;
139 } 163 }
140 s += size;
141 len -= size;
142 } else { 164 } else {
143 *op++ = *s++; 165 put_utf16(op++, *s++, endian);
144 len--; 166 inlen--;
167 maxout--;
145 } 168 }
146 } 169 }
147 return op - pwcs; 170 return op - pwcs;
@@ -160,27 +183,27 @@ static inline unsigned long get_utf16(unsigned c, enum utf16_endian endian)
160 } 183 }
161} 184}
162 185
163int utf16s_to_utf8s(const wchar_t *pwcs, int len, enum utf16_endian endian, 186int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian,
164 u8 *s, int maxlen) 187 u8 *s, int maxout)
165{ 188{
166 u8 *op; 189 u8 *op;
167 int size; 190 int size;
168 unsigned long u, v; 191 unsigned long u, v;
169 192
170 op = s; 193 op = s;
171 while (len > 0 && maxlen > 0) { 194 while (inlen > 0 && maxout > 0) {
172 u = get_utf16(*pwcs, endian); 195 u = get_utf16(*pwcs, endian);
173 if (!u) 196 if (!u)
174 break; 197 break;
175 pwcs++; 198 pwcs++;
176 len--; 199 inlen--;
177 if (u > 0x7f) { 200 if (u > 0x7f) {
178 if ((u & SURROGATE_MASK) == SURROGATE_PAIR) { 201 if ((u & SURROGATE_MASK) == SURROGATE_PAIR) {
179 if (u & SURROGATE_LOW) { 202 if (u & SURROGATE_LOW) {
180 /* Ignore character and move on */ 203 /* Ignore character and move on */
181 continue; 204 continue;
182 } 205 }
183 if (len <= 0) 206 if (inlen <= 0)
184 break; 207 break;
185 v = get_utf16(*pwcs, endian); 208 v = get_utf16(*pwcs, endian);
186 if ((v & SURROGATE_MASK) != SURROGATE_PAIR || 209 if ((v & SURROGATE_MASK) != SURROGATE_PAIR ||
@@ -191,18 +214,18 @@ int utf16s_to_utf8s(const wchar_t *pwcs, int len, enum utf16_endian endian,
191 u = PLANE_SIZE + ((u & SURROGATE_BITS) << 10) 214 u = PLANE_SIZE + ((u & SURROGATE_BITS) << 10)
192 + (v & SURROGATE_BITS); 215 + (v & SURROGATE_BITS);
193 pwcs++; 216 pwcs++;
194 len--; 217 inlen--;
195 } 218 }
196 size = utf32_to_utf8(u, op, maxlen); 219 size = utf32_to_utf8(u, op, maxout);
197 if (size == -1) { 220 if (size == -1) {
198 /* Ignore character and move on */ 221 /* Ignore character and move on */
199 } else { 222 } else {
200 op += size; 223 op += size;
201 maxlen -= size; 224 maxout -= size;
202 } 225 }
203 } else { 226 } else {
204 *op++ = (u8) u; 227 *op++ = (u8) u;
205 maxlen--; 228 maxout--;
206 } 229 }
207 } 230 }
208 return op - s; 231 return op - s;