summaryrefslogtreecommitdiff
path: root/iconv/gconv_simple.c
diff options
context:
space:
mode:
Diffstat (limited to 'iconv/gconv_simple.c')
-rw-r--r--iconv/gconv_simple.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
index 91a347b058..582c6f5a27 100644
--- a/iconv/gconv_simple.c
+++ b/iconv/gconv_simple.c
@@ -123,14 +123,23 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
data->outbufsize - data->outbufavail,
(mbstate_t *) data->data);
- /* Status so far. */
- result = GCONV_EMPTY_INPUT;
-
/* Remember how much we converted. */
do_write += newinbuf - inbuf;
*inlen -= (newinbuf - inbuf) * sizeof (wchar_t);
data->outbufavail += actually;
+
+ if (data->is_last)
+ {
+ /* This is the last step. */
+ result = (*inlen < sizeof (wchar_t)
+ ? GCONV_EMPTY_INPUT : GCONV_FULL_OUTPUT);
+ break;
+ }
+
+ /* Status so far. */
+ result = GCONV_EMPTY_INPUT;
+
if (data->outbufavail > 0)
{
/* Call the functions below in the chain. */
@@ -140,7 +149,7 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
written, 0);
/* Correct the output buffer. */
- if (newavail != data->outbufavail)
+ if (newavail != data->outbufavail && newavail > 0)
{
memmove (data->outbuf,
&data->outbuf[data->outbufavail - newavail],
@@ -204,14 +213,23 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
/ sizeof (wchar_t)),
(mbstate_t *) data->data);
- /* Status so far. */
- result = GCONV_EMPTY_INPUT;
-
/* Remember how much we converted. */
do_write += actually;
*inlen -= newinbuf - inbuf;
data->outbufavail += actually * sizeof (wchar_t);
+
+ if (data->is_last)
+ {
+ /* This is the last step. */
+ result = (data->outbufavail + sizeof (wchar_t) > data->outbufsize
+ ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
+ break;
+ }
+
+ /* Status so far. */
+ result = GCONV_EMPTY_INPUT;
+
if (data->outbufavail > 0)
{
/* Call the functions below in the chain. */
@@ -221,7 +239,7 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
written, 0);
/* Correct the output buffer. */
- if (newavail != data->outbufavail)
+ if (newavail != data->outbufavail && newavail > 0)
{
memmove (data->outbuf,
&data->outbuf[data->outbufavail - newavail],
@@ -236,5 +254,5 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
if (written != NULL && data->is_last)
*written = do_write;
- return GCONV_OK;
+ return result;
}