Commit a3da112d authored by David Woodhouse's avatar David Woodhouse

Split out get_utf8char() from buf_append_utf16le()

We'll want this for working around Yubikey/Android PIN weirdness.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 5f52379e
......@@ -171,56 +171,61 @@ void buf_append_from_utf16le(struct oc_text_buf *buf, const void *_utf16)
buf_append_bytes(buf, utf8, 1);
}
int buf_append_utf16le(struct oc_text_buf *buf, const char *utf8)
int get_utf8char(const char **p)
{
int len = 0;
const char *utf8 = *p;
unsigned char c;
unsigned long utfchar;
int min;
int nr_extra;
int utfchar, nr_extra, min;
c = *(utf8++);
if (c < 128) {
utfchar = c;
nr_extra = 0;
min = 0;
} else if ((c & 0xe0) == 0xc0) {
utfchar = c & 0x1f;
nr_extra = 1;
min = 0x80;
} else if ((c & 0xf0) == 0xe0) {
utfchar = c & 0x0f;
nr_extra = 2;
min = 0x800;
} else if ((c & 0xf8) == 0xf0) {
utfchar = c & 0x07;
nr_extra = 3;
min = 0x10000;
} else {
return -EILSEQ;
}
/* Ick. Now I'm implementing my own UTF8 handling too. Perhaps it's
time to bite the bullet and start requiring something like glib? */
while (*utf8) {
while (nr_extra--) {
c = *(utf8++);
if (c < 128) {
utfchar = c;
nr_extra = 0;
min = 0;
} else if ((c & 0xe0) == 0xc0) {
utfchar = c & 0x1f;
nr_extra = 1;
min = 0x80;
} else if ((c & 0xf0) == 0xe0) {
utfchar = c & 0x0f;
nr_extra = 2;
min = 0x800;
} else if ((c & 0xf8) == 0xf0) {
utfchar = c & 0x07;
nr_extra = 3;
min = 0x10000;
} else {
if (buf)
buf->error = -EILSEQ;
if ((c & 0xc0) != 0x80)
return -EILSEQ;
}
while (nr_extra--) {
c = *(utf8++);
if ((c & 0xc0) != 0x80) {
if (buf)
buf->error = -EILSEQ;
return -EILSEQ;
}
utfchar <<= 6;
utfchar |= (c & 0x3f);
}
if (utfchar > 0x10ffff || utfchar < min) {
utfchar <<= 6;
utfchar |= (c & 0x3f);
}
if (utfchar > 0x10ffff || utfchar < min)
return -EILSEQ;
*p = utf8;
return utfchar;
}
int buf_append_utf16le(struct oc_text_buf *buf, const char *utf8)
{
int utfchar, len = 0;
/* Ick. Now I'm implementing my own UTF8 handling too. Perhaps it's
time to bite the bullet and start requiring something like glib? */
while (*utf8) {
utfchar = get_utf8char(&utf8);
if (utfchar < 0) {
if (buf)
buf->error = -EILSEQ;
return -EILSEQ;
buf->error = utfchar;
return utfchar;
}
if (!buf)
continue;
......
......@@ -920,6 +920,7 @@ void __attribute__ ((format (printf, 2, 3)))
void buf_append_bytes(struct oc_text_buf *buf, const void *bytes, int len);
void buf_append_base64(struct oc_text_buf *buf, const void *bytes, int len);
int buf_append_utf16le(struct oc_text_buf *buf, const char *utf8);
int get_utf8char(const char **utf8);
void buf_append_from_utf16le(struct oc_text_buf *buf, const void *utf16);
void *openconnect_base64_decode(int *len, const char *in);
void buf_truncate(struct oc_text_buf *buf);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment