Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 280773
b: refs/heads/master
c: 86dc243
h: refs/heads/master
i:
  280771: 87e2b7a
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Nov 18, 2011
1 parent b175dff commit 7917237
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 70 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0720a06a7518c9d0c0125bd5d1f3b6264c55c3dd
refs/heads/master: 86dc243cb2ddecb6984401463ebb0963ceff3cdc
1 change: 1 addition & 0 deletions trunk/drivers/usb/gadget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

menuconfig USB_GADGET
tristate "USB Gadget Support"
select NLS
help
USB is a master/slave protocol, organized with one master
host (such as a PC) controlling up to 127 peripheral devices.
Expand Down
73 changes: 4 additions & 69 deletions trunk/drivers/usb/gadget/usbstring.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,82 +13,17 @@
#include <linux/string.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/nls.h>

#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>

#include <asm/unaligned.h>


static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len)
{
int count = 0;
u8 c;
u16 uchar;

/* this insists on correct encodings, though not minimal ones.
* BUT it currently rejects legit 4-byte UTF-8 code points,
* which need surrogate pairs. (Unicode 3.1 can use them.)
*/
while (len != 0 && (c = (u8) *s++) != 0) {
if (unlikely(c & 0x80)) {
// 2-byte sequence:
// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
if ((c & 0xe0) == 0xc0) {
uchar = (c & 0x1f) << 6;

c = (u8) *s++;
if ((c & 0xc0) != 0x80)
goto fail;
c &= 0x3f;
uchar |= c;

// 3-byte sequence (most CJKV characters):
// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
} else if ((c & 0xf0) == 0xe0) {
uchar = (c & 0x0f) << 12;

c = (u8) *s++;
if ((c & 0xc0) != 0x80)
goto fail;
c &= 0x3f;
uchar |= c << 6;

c = (u8) *s++;
if ((c & 0xc0) != 0x80)
goto fail;
c &= 0x3f;
uchar |= c;

/* no bogus surrogates */
if (0xd800 <= uchar && uchar <= 0xdfff)
goto fail;

// 4-byte sequence (surrogate pairs, currently rare):
// 11101110wwwwzzzzyy + 110111yyyyxxxxxx
// = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
// (uuuuu = wwww + 1)
// FIXME accept the surrogate code points (only)

} else
goto fail;
} else
uchar = c;
put_unaligned_le16(uchar, cp++);
count++;
len--;
}
return count;
fail:
return -1;
}


/**
* usb_gadget_get_string - fill out a string descriptor
* @table: of c strings encoded using UTF-8
* @id: string id, from low byte of wValue in get string descriptor
* @buf: at least 256 bytes
* @buf: at least 256 bytes, must be 16-bit aligned
*
* Finds the UTF-8 string matching the ID, and converts it into a
* string descriptor in utf16-le.
Expand Down Expand Up @@ -125,8 +60,8 @@ usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf)

/* string descriptors have length, tag, then UTF16-LE text */
len = min ((size_t) 126, strlen (s->s));
memset (buf + 2, 0, 2 * len); /* zero all the bytes */
len = utf8_to_utf16le(s->s, (__le16 *)&buf[2], len);
len = utf8s_to_utf16s(s->s, len, UTF16_LITTLE_ENDIAN,
(wchar_t *) &buf[2], 126);
if (len < 0)
return -EINVAL;
buf [0] = (len + 1) * 2;
Expand Down

0 comments on commit 7917237

Please sign in to comment.