summaryrefslogtreecommitdiffstats
path: root/libcpp
diff options
context:
space:
mode:
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2007-12-12 01:38:10 +0000
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2007-12-12 01:38:10 +0000
commit2d1f9589a302bf6e28f4929a1a0a1e46af2a55f8 (patch)
tree0b62ddc2f572ce42be0b6c205799d426377b9049 /libcpp
parent6349d0b0c066399932730df41a844850740c91a9 (diff)
downloadppe42-gcc-2d1f9589a302bf6e28f4929a1a0a1e46af2a55f8.tar.gz
ppe42-gcc-2d1f9589a302bf6e28f4929a1a0a1e46af2a55f8.zip
* charset.c (convert_using_iconv): Close out any shift states,
returning to the initial state. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130785 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog5
-rw-r--r--libcpp/charset.c25
2 files changed, 26 insertions, 4 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 1cc5d7f57f1..217294af563 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,8 @@
+2007-12-11 DJ Delorie <dj@redhat.com>
+
+ * charset.c (convert_using_iconv): Close out any shift states,
+ returning to the initial state.
+
2007-12-06 Tom Tromey <tromey@redhat.com>
PR c/29172:
diff --git a/libcpp/charset.c b/libcpp/charset.c
index d1323601bd1..5db8fc13430 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -548,6 +548,15 @@ convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED,
/* And this one uses the system iconv primitive. It's a little
different, since iconv's interface is a little different. */
#if HAVE_ICONV
+
+#define CONVERT_ICONV_GROW_BUFFER \
+ do { \
+ outbytesleft += OUTBUF_BLOCK_SIZE; \
+ to->asize += OUTBUF_BLOCK_SIZE; \
+ to->text = XRESIZEVEC (uchar, to->text, to->asize); \
+ outbuf = (char *)to->text + to->asize - outbytesleft; \
+ } while (0)
+
static bool
convert_using_iconv (iconv_t cd, const uchar *from, size_t flen,
struct _cpp_strbuf *to)
@@ -570,16 +579,24 @@ convert_using_iconv (iconv_t cd, const uchar *from, size_t flen,
iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
if (__builtin_expect (inbytesleft == 0, 1))
{
+ /* Close out any shift states, returning to the initial state. */
+ if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1)
+ {
+ if (errno != E2BIG)
+ return false;
+
+ CONVERT_ICONV_GROW_BUFFER;
+ if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1)
+ return false;
+ }
+
to->len = to->asize - outbytesleft;
return true;
}
if (errno != E2BIG)
return false;
- outbytesleft += OUTBUF_BLOCK_SIZE;
- to->asize += OUTBUF_BLOCK_SIZE;
- to->text = XRESIZEVEC (uchar, to->text, to->asize);
- outbuf = (char *)to->text + to->asize - outbytesleft;
+ CONVERT_ICONV_GROW_BUFFER;
}
}
#else
OpenPOWER on IntegriCloud