summaryrefslogtreecommitdiff
path: root/src/iconv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/iconv.c')
-rw-r--r--src/iconv.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/iconv.c b/src/iconv.c
index c81a0b2..21bf665 100644
--- a/src/iconv.c
+++ b/src/iconv.c
@@ -292,6 +292,10 @@ size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf,
/* Clear skip */
e->skip = 0;
+ /* Reset transliteration state */
+ e->substitution = NULL;
+ e->substlen = 0;
+
/* Reset read codec */
if (e->in) {
encoding_reset(e->in);
@@ -342,13 +346,20 @@ size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf,
e->outbytesleft = outbytesleft;
/* Flush through any remaining transliteration */
- ret = translit_flush_replacement(e);
- if (ret <= 0) {
- errno = E2BIG;
- return (size_t)-1;
- }
+ if (e->substlen > 0) {
+ ret = translit_flush_replacement(e);
+ if (ret <= 0) {
+ errno = E2BIG;
+ return (size_t)-1;
+ }
- LOG(("reading"));
+ /* Force write state to success, so if there's no more input
+ * (i.e. we were transliterating the last character of input)
+ * we'll report success, rather than whatever caused us to
+ * stop writing the transliterated sequence last time round.
+ */
+ e->write_state = WRITE_SUCCESS;
+ }
/* If, on the previous attempt to convert data, we reached the end
* of the input buffer mid-sequence, then we retain the number of
@@ -359,12 +370,16 @@ size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf,
* start.
*/
if (e->skip != 0) {
+ LOG(("Skipping %d bytes of input", e->skip));
+
*inbuf += e->skip;
*inbytesleft -= e->skip;
e->skip = 0;
}
+ LOG(("Reading %zd bytes of input", *inbytesleft));
+
/* Perform the conversion.
*
* To ensure that we detect the correct error conditions