]> granicus.if.org Git - php/commitdiff
MFB: fixed shift-out sequence unawareness issue
authorMoriyoshi Koizumi <moriyoshi@php.net>
Fri, 3 Jan 2003 05:14:34 +0000 (05:14 +0000)
committerMoriyoshi Koizumi <moriyoshi@php.net>
Fri, 3 Jan 2003 05:14:34 +0000 (05:14 +0000)
ext/iconv/iconv.c

index 7212be5c5352f5046b115e1459d96a5dbe664eda..260f68442201f6da61c5230c0d13b1ddcc1009ec 100644 (file)
@@ -240,7 +240,7 @@ unsigned char *php_quot_print_decode(const unsigned char *str, size_t length, si
        size_t decoded_len;
        unsigned char *retval;
 
-       unsigned int hexval_tbl[256] = {
+       static unsigned int hexval_tbl[256] = {
                16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
                16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
                16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
@@ -402,7 +402,19 @@ php_iconv_err_t php_iconv_string(const char *in_p, size_t in_len,
                efree(out_buffer);
                return PHP_ICONV_ERR_UNKNOWN;
        }
-       
+
+       if (out_left < 8) {
+               out_buffer = (char *) erealloc(out_buffer, out_size + 8);
+       }
+
+       /* flush the shift-out sequences */ 
+       result = icv(cd, NULL, NULL, &out_p, &out_left);
+
+       if (result == (size_t)(-1)) {
+               efree(out_buffer);
+               return PHP_ICONV_ERR_UNKNOWN;
+       }
+
        *out_len = out_size - out_left;
        out_buffer[*out_len] = '\0';
        *out = out_buffer;
@@ -460,6 +472,34 @@ php_iconv_err_t php_iconv_string(const char *in_p, size_t in_len,
                }
                break;
        }
+
+       if (result != (size_t)(-1)) {
+               /* flush the shift-out sequences */ 
+               for (;;) {
+                       result = icv(cd, NULL, NULL, (char **) &out_p, &out_left);
+                       out_size = bsz - out_left;
+
+                       if (result != (size_t)(-1)) {
+                               break;
+                       }
+
+                       if (errno == E2BIG) {
+                               bsz += 16;
+                               tmp_buf = (char *) erealloc(out_buf, bsz);
+
+                               if (tmp_buf == NULL) {
+                                       break;
+                               }
+                               
+                               out_p = out_buf = tmp_buf;
+                               out_p += out_size;
+                               out_left = bsz - out_size;
+                       } else {
+                               break;
+                       }
+               }
+       }
+
        icv_close(cd);
 
        if (result == (size_t)(-1)) {
@@ -471,6 +511,7 @@ php_iconv_err_t php_iconv_string(const char *in_p, size_t in_len,
                        case EILSEQ:
                                retval = PHP_ICONV_ERR_ILLEGAL_SEQ;
                                break;
+
                        case E2BIG:
                                /* should not happen */
                                retval = PHP_ICONV_ERR_TOO_BIG;