OSDN Git Service

* charset.c (convert_using_iconv): Close out any shift states,
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 12 Dec 2007 01:38:10 +0000 (01:38 +0000)
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 12 Dec 2007 01:38:10 +0000 (01:38 +0000)
returning to the initial state.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130785 138bc75d-0d04-0410-961f-82ee72b054a4

libcpp/ChangeLog
libcpp/charset.c

index 1cc5d7f..217294a 100644 (file)
@@ -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:
index d132360..5db8fc1 100644 (file)
@@ -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