Improve iconvbufs() to do more buffer size checks.
authorWayne Davison <wayned@samba.org>
Sun, 19 May 2013 23:56:34 +0000 (23:56 +0000)
committerWayne Davison <wayned@samba.org>
Sun, 19 May 2013 23:56:34 +0000 (23:56 +0000)
- If iconv() returns EINVAL or EILSEQ and the error is being ignored, make
  sure that there is room in the output buffer to store the erroneous char.
- When accepting an erroneous char, be sure to break if there are no more
  input characters (without calling iconv() with a zero input length).

rsync.c

diff --git a/rsync.c b/rsync.c
index 540ccd939979731a12790fd87ed33a48696526cf..cf210099abfe2c1b011622c0ed22b71cffafb2d6 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -210,11 +210,16 @@ int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags)
                        if (errno == EINVAL) {
                                if (!(flags & ICB_INCLUDE_INCOMPLETE))
                                        goto finish;
+                               if (!ocnt)
+                                       goto e2big;
                        } else if (errno == EILSEQ) {
                                if (!(flags & ICB_INCLUDE_BAD))
                                        goto finish;
+                               if (!ocnt)
+                                       goto e2big;
                        } else if (errno == E2BIG) {
                                size_t siz;
+                         e2big:
                                opos = obuf - out->buf;
                                if (flags & ICB_CIRCULAR_OUT && out->pos > 1 && opos > out->pos) {
                                        /* We are in a divided circular buffer at the physical
@@ -242,6 +247,8 @@ int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags)
                        }
                        *obuf++ = *ibuf++;
                        ocnt--, icnt--;
+                       if (!icnt)
+                               break;
                }
        }