g_iconv (GIConv cd, gchar **inbytes, gsize *inbytesleft,
gchar **outbytes, gsize *outbytesleft)
{
- size_t inleft, outleft;
+ gsize inleft, outleft;
char *inptr, *outptr;
gunichar c;
int rc = 0;
#ifdef HAVE_ICONV
- if (cd->cd != (iconv_t) -1)
- return iconv (cd->cd, inbytes, inbytesleft, outbytes, outbytesleft);
+ if (cd->cd != (iconv_t) -1) {
+ /* Note: gsize may have a different size than size_t, so we need to
+ remap inbytesleft and outbytesleft to size_t's. */
+ size_t *outleftptr, *inleftptr;
+ size_t n_outleft, n_inleft;
+
+ if (inbytesleft) {
+ n_inleft = *inbytesleft;
+ inleftptr = &n_inleft;
+ } else {
+ inleftptr = NULL;
+ }
+
+ if (outbytesleft) {
+ n_outleft = *outbytesleft;
+ outleftptr = &n_outleft;
+ } else {
+ outleftptr = NULL;
+ }
+
+ return iconv (cd->cd, inbytes, inleftptr, outbytes, outleftptr);
+ }
#endif
if (outbytes == NULL || outbytesleft == NULL) {
g_convert (const gchar *str, gssize len, const gchar *to_charset, const gchar *from_charset,
gsize *bytes_read, gsize *bytes_written, GError **err)
{
- size_t outsize, outused, outleft, inleft, grow, rc;
+ gsize outsize, outused, outleft, inleft, grow, rc;
char *result, *outbuf, *inbuf;
gboolean flush = FALSE;
gboolean done = FALSE;
else
rc = g_iconv (cd, NULL, NULL, &outbuf, &outleft);
- if (rc == (size_t) -1) {
+ if (rc == (gsize) -1) {
switch (errno) {
case E2BIG:
/* grow our result buffer */
size_t inleft;
char *inptr;
gunichar c;
- int n;
+ int u, n;
g_return_val_if_fail (str != NULL, NULL);
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);
}
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;
}
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);
*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... */
+ } 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 *