From d8a7290f8621b72139461ed6606cde31fa4d544f Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Fri, 23 Oct 2009 22:51:29 -0700 Subject: [PATCH] Give iconvbufs() an ICB_INIT flag. --- flist.c | 10 +++++----- io.c | 11 ++++++----- log.c | 2 +- rsync.c | 8 ++++---- rsync.h | 1 + 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/flist.c b/flist.c index 5a1ab9dc..d0777d23 100644 --- a/flist.c +++ b/flist.c @@ -731,7 +731,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x INIT_CONST_XBUF(outbuf, thisname); INIT_XBUF(inbuf, lastname, basename_len, (size_t)-1); - if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) { + if (iconvbufs(ic_recv, &inbuf, &outbuf, ICB_INIT) < 0) { io_error |= IOERR_GENERAL; rprintf(FERROR_UTF8, "[%s] cannot convert filename: %s (%s)\n", @@ -1049,7 +1049,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x read_sbuf(f, inbuf.buf, inbuf.len); INIT_XBUF(outbuf, bp, 0, alloc_len); - if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) { + if (iconvbufs(ic_recv, &inbuf, &outbuf, ICB_INIT) < 0) { io_error |= IOERR_GENERAL; rprintf(FERROR_XFER, "[%s] cannot convert symlink data for: %s (%s)\n", @@ -1464,14 +1464,14 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, if (file->dirname) { INIT_XBUF_STRLEN(inbuf, (char*)file->dirname); outbuf.size -= 2; /* Reserve room for '/' & 1 more char. */ - if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) + if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0) goto convert_error; outbuf.size += 2; fbuf[outbuf.len++] = '/'; } INIT_XBUF_STRLEN(inbuf, (char*)file->basename); - if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) { + if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0) { convert_error: io_error |= IOERR_GENERAL; rprintf(FERROR_XFER, @@ -1485,7 +1485,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, if (symlink_len && sender_symlink_iconv) { INIT_XBUF(inbuf, (char*)symlink_name, symlink_len, (size_t)-1); INIT_CONST_XBUF(outbuf, symlink_buf); - if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) { + if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0) { io_error |= IOERR_GENERAL; f_name(file, fbuf); rprintf(FERROR_XFER, diff --git a/io.c b/io.c index b0f0204e..3ece9c3b 100644 --- a/io.c +++ b/io.c @@ -378,7 +378,7 @@ static void forward_filesfrom_data(void) } if (len) { char *f = x.buf + x.pos; - char *t = f; /* Keep any non-zero offset to avoid iconv reset. */ + char *t = x.buf; char *eob = f + len; /* Eliminate any multi-'\0' runs. */ while (f != eob) { @@ -393,7 +393,7 @@ static void forward_filesfrom_data(void) if (filesfrom_convert) { /* TODO would it help to translate each string between nulls separately? */ x.len = len; - iconvbufs(ic_send, &x, &iobuf.out, ICB_INCLUDE_BAD|ICB_INCLUDE_INCOMPLETE|ICB_CIRCULAR_OUT); + iconvbufs(ic_send, &x, &iobuf.out, ICB_INCLUDE_BAD|ICB_INCLUDE_INCOMPLETE|ICB_CIRCULAR_OUT|ICB_INIT); } else #endif if (len) { @@ -803,7 +803,7 @@ int send_msg(enum msgcode code, const char *buf, size_t len, int convert) len = iobuf.msg.len; iconvbufs(ic_send, &inbuf, &iobuf.msg, - ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_CIRCULAR_OUT); + ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_CIRCULAR_OUT | ICB_INIT); if (inbuf.len > 0) { rprintf(FERROR, "overflowed iobuf.msg buffer in send_msg"); exit_cleanup(RERR_UNSUPPORTED); @@ -1039,7 +1039,7 @@ int read_line(int fd, char *buf, size_t bufsiz, int flags) iconv_buf.pos = 0; iconv_buf.len = s - iconv_buf.buf; iconvbufs(ic_recv, &iconv_buf, &outbuf, - ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE); + ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_INIT); outbuf.buf[outbuf.len] = '\0'; return outbuf.len; } @@ -1301,13 +1301,14 @@ static void read_a_msg(void) INIT_XBUF(inbuf, ibuf, 0, (size_t)-1); while (msg_bytes) { + inbuf.pos = 0; inbuf.len = msg_bytes > sizeof ibuf ? sizeof ibuf : msg_bytes; memcpy(inbuf.buf, perform_io(inbuf.len, PIO_INPUT_AND_CONSUME), inbuf.len); if (!(msg_bytes -= inbuf.len) && !ibuf[inbuf.len-1]) inbuf.len--, add_null = 1; if (iconvbufs(ic_send, &inbuf, &outbuf, - ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE) < 0) + ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_INIT) < 0) goto overflow; } if (add_null) { diff --git a/log.c b/log.c index 0aa5b251..61d01ce5 100644 --- a/log.c +++ b/log.c @@ -359,7 +359,7 @@ output_msg: INIT_XBUF(inbuf, (char*)buf, len, (size_t)-1); while (inbuf.len) { - iconvbufs(ic, &inbuf, &outbuf, 0); + iconvbufs(ic, &inbuf, &outbuf, inbuf.pos ? 0 : ICB_INIT); ierrno = errno; if (outbuf.len) { filtered_fwrite(f, convbuf, outbuf.len, 0); diff --git a/rsync.c b/rsync.c index 3008e2db..2d0de925 100644 --- a/rsync.c +++ b/rsync.c @@ -160,8 +160,8 @@ static void wrap_overflow(xbuf *out, int siz) * "flags", any badly-encoded chars are included verbatim in the "out" xbuf, * so EILSEQ will not be returned. Likewise for ICB_INCLUDE_INCOMPLETE with * respect to an incomplete multi-byte char at the end, which ensures that - * EINVAL is not returned. Anytime "in.pos" is 0 we will reset the iconv() - * state prior to processing the characters. */ + * EINVAL is not returned. If ICB_INIT is set, the iconv() conversion state + * is initialized prior to processing the characters. */ int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags) { ICONV_CONST char *ibuf; @@ -171,7 +171,7 @@ int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags) if (!out->size && flags & ICB_EXPAND_OUT) alloc_xbuf(out, 1024); - if (!in->pos) + if (flags & ICB_INIT) iconv(ic, NULL, 0, NULL, 0); ibuf = in->buf + in->pos; @@ -265,7 +265,7 @@ void send_protected_args(int fd, char *args[]) else if (convert) { INIT_XBUF_STRLEN(inbuf, args[i]); iconvbufs(ic_send, &inbuf, &outbuf, - ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE); + ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_INIT); outbuf.buf[outbuf.len] = '\0'; write_buf(fd, outbuf.buf, outbuf.len + 1); outbuf.len = 0; diff --git a/rsync.h b/rsync.h index c5e76913..e6a62608 100644 --- a/rsync.h +++ b/rsync.h @@ -901,6 +901,7 @@ typedef struct { #define ICB_INCLUDE_BAD (1<<1) #define ICB_INCLUDE_INCOMPLETE (1<<2) #define ICB_CIRCULAR_OUT (1<<3) +#define ICB_INIT (1<<4) #define RL_EOL_NULLS (1<<0) #define RL_DUMP_COMMENTS (1<<1) -- 2.34.1