diff options
author | Jeffrey Stedfast <fejj@gnome.org> | 2013-08-14 19:40:59 -0400 |
---|---|---|
committer | Jo Shields <directhex@apebox.org> | 2013-10-12 23:53:15 +0100 |
commit | 235060d86f87c6bb8dac8d0e40b598a248c0599b (patch) | |
tree | 3a153d9a12d00237d408ea81fb220c8110621e9b | |
parent | 8e272717ad84c79b1dcd198567405b07943901a4 (diff) | |
download | mono-235060d86f87c6bb8dac8d0e40b598a248c0599b.tar.gz |
[eglib] Fixed g_utf8_to_utf16_general() to handle invalid utf8
(cherry picked from commit a81cd6dae81a7077a7f014948c78075da08f02f7)
-rw-r--r-- | eglib/src/giconv.c | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/eglib/src/giconv.c b/eglib/src/giconv.c index 2f44336aa0..da48c6f628 100644 --- a/eglib/src/giconv.c +++ b/eglib/src/giconv.c @@ -894,7 +894,7 @@ eg_utf8_to_utf16_general (const gchar *str, glong len, glong *items_read, glong size_t inleft; char *inptr; gunichar c; - int n; + int u, n; g_return_val_if_fail (str != NULL, NULL); @@ -903,6 +903,7 @@ eg_utf8_to_utf16_general (const gchar *str, glong len, glong *items_read, glong g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, "Conversions with embedded nulls must pass the string length"); return NULL; } + len = strlen (str); } @@ -910,29 +911,18 @@ eg_utf8_to_utf16_general (const gchar *str, glong len, glong *items_read, glong inleft = len; while (inleft > 0) { - if ((n = decode_utf8 (inptr, inleft, &c)) < 0) { - if (errno == EILSEQ) { - g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, - "Illegal byte sequence encounted in the input."); - } else if (items_read) { - /* partial input is ok if we can let our caller know... */ - break; - } else { - g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, - "Partial byte sequence encountered in the input."); - } - - if (items_read) - *items_read = inptr - str; - - if (items_written) - *items_written = 0; - - return NULL; - } else if (c == 0 && !include_nuls) + if ((n = decode_utf8 (inptr, inleft, &c)) < 0) + goto error; + + if (c == 0 && !include_nuls) break; - outlen += g_unichar_to_utf16 (c, NULL); + if ((u = g_unichar_to_utf16 (c, NULL)) < 0) { + errno = EILSEQ; + goto error; + } + + outlen += u; inleft -= n; inptr += n; } @@ -950,7 +940,8 @@ eg_utf8_to_utf16_general (const gchar *str, glong len, glong *items_read, glong while (inleft > 0) { if ((n = decode_utf8 (inptr, inleft, &c)) < 0) break; - else if (c == 0 && !include_nuls) + + if (c == 0 && !include_nuls) break; outptr += g_unichar_to_utf16 (c, outptr); @@ -961,6 +952,26 @@ eg_utf8_to_utf16_general (const gchar *str, glong len, glong *items_read, glong *outptr = '\0'; return outbuf; + + error: + if (errno == EILSEQ) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + "Illegal byte sequence encounted in the input."); + } else if (items_read) { + /* partial input is ok if we can let our caller know... */ + break; + } else { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + "Partial byte sequence encountered in the input."); + } + + if (items_read) + *items_read = inptr - str; + + if (items_written) + *items_written = 0; + + return NULL; } gunichar2 * |