moriyoshi Fri Jan 3 00:28:25 2003 EDT
Modified files:
/php4/ext/iconv iconv.c
Log:
More shift-sequence awareness for iconv_substr()
Index: php4/ext/iconv/iconv.c
diff -u php4/ext/iconv/iconv.c:1.70 php4/ext/iconv/iconv.c:1.71
--- php4/ext/iconv/iconv.c:1.70 Fri Jan 3 00:26:44 2003
+++ php4/ext/iconv/iconv.c Fri Jan 3 00:28:25 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: iconv.c,v 1.70 2003/01/03 05:26:44 moriyoshi Exp $ */
+/* $Id: iconv.c,v 1.71 2003/01/03 05:28:25 moriyoshi Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -311,41 +311,70 @@
size_t prev_in_left = in_left;
#endif
- while (in_left > 0) {
- out_left = buf_growth - out_left;
- {
- size_t newlen;
- smart_str_alloc((d), out_left, 0);
- }
+ if (in_p != NULL) {
+ while (in_left > 0) {
+ out_left = buf_growth - out_left;
+ {
+ size_t newlen;
+ smart_str_alloc((d), out_left, 0);
+ }
- out_p = (d)->c + (d)->len;
+ out_p = (d)->c + (d)->len;
- if (icv(cd, &in_p, &in_left, (char **) &out_p, &out_left) ==
(size_t)-1) {
+ if (icv(cd, &in_p, &in_left, (char **) &out_p, &out_left) ==
+(size_t)-1) {
#if ICONV_SUPPORTS_ERRNO
- switch (errno) {
- case EINVAL:
- return PHP_ICONV_ERR_ILLEGAL_CHAR;
+ switch (errno) {
+ case EINVAL:
+ return PHP_ICONV_ERR_ILLEGAL_CHAR;
- case EILSEQ:
- return PHP_ICONV_ERR_ILLEGAL_SEQ;
+ case EILSEQ:
+ return PHP_ICONV_ERR_ILLEGAL_SEQ;
- case E2BIG:
- break;
+ case E2BIG:
+ break;
- default:
- return PHP_ICONV_ERR_UNKNOWN;
- }
+ default:
+ return PHP_ICONV_ERR_UNKNOWN;
+ }
#else
- if (prev_in_left == in_left) {
- return PHP_ICONV_ERR_UNKNOWN;
+ if (prev_in_left == in_left) {
+ return PHP_ICONV_ERR_UNKNOWN;
+ }
+#endif
}
+#if !ICONV_SUPPORTS_ERRNO
+ prev_in_left = in_left;
#endif
+ (d)->len += (buf_growth - out_left);
+ buf_growth <<= 1;
}
-#if !ICONV_SUPPORTS_ERRNO
- prev_in_left = in_left;
+ } else {
+ for (;;) {
+ out_left = buf_growth - out_left;
+ {
+ size_t newlen;
+ smart_str_alloc((d), out_left, 0);
+ }
+
+ out_p = (d)->c + (d)->len;
+
+ if (icv(cd, NULL, NULL, (char **) &out_p, &out_left) ==
+(size_t)0) {
+ (d)->len += (buf_growth - out_left);
+ break;
+ } else {
+#if ICONV_SUPPORTS_ERRNO
+ if (errno != E2BIG) {
+ return PHP_ICONV_ERR_UNKNOWN;
+ }
+#else
+ if (out_left != 0) {
+ return PHP_ICONV_ERR_UNKNOWN;
+ }
#endif
- (d)->len += (buf_growth - out_left);
- buf_growth <<= 1;
+ }
+ (d)->len += (buf_growth - out_left);
+ buf_growth <<= 1;
+ }
}
return PHP_ICONV_ERR_SUCCESS;
}
@@ -622,7 +651,7 @@
php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS;
- iconv_t cd;
+ iconv_t cd1, cd2;
const char *in_p;
size_t in_left;
@@ -632,8 +661,6 @@
unsigned int cnt;
- const char *substr_ofs;
-
/* normalize the offset and the length */
if (offset < 0 || len < 0) {
unsigned int total_len;
@@ -653,9 +680,9 @@
}
}
- cd = icv_open(GENERIC_SUPERSET_NAME, enc);
+ cd1 = icv_open(GENERIC_SUPERSET_NAME, enc);
- if (cd == (iconv_t)(-1)) {
+ if (cd1 == (iconv_t)(-1)) {
#if ICONV_SUPPORTS_ERRNO
if (errno == EINVAL) {
return PHP_ICONV_ERR_WRONG_CHARSET;
@@ -667,7 +694,7 @@
#endif
}
- substr_ofs = NULL;
+ cd2 = NULL;
for (in_p = str, in_left = nbytes, cnt = 0; in_left > 0 && len > 0; ++cnt) {
size_t prev_in_left;
@@ -676,18 +703,35 @@
prev_in_left = in_left;
- if (cnt >= offset) {
- if (substr_ofs == NULL) {
- substr_ofs = in_p;
+ if (icv(cd1, &in_p, &in_left, (char **) &out_p, &out_left) ==
+(size_t)-1) {
+ if (prev_in_left == in_left) {
+ break;
}
- --len;
}
- if (icv(cd, &in_p, &in_left, (char **) &out_p, &out_left) ==
(size_t)-1) {
- if (prev_in_left == in_left) {
- break;
+ if (cnt >= offset) {
+ if (cd2 == NULL) {
+ cd2 = icv_open(enc, GENERIC_SUPERSET_NAME);
+
+ if (cd2 == (iconv_t)(-1)) {
+ cd2 = NULL;
+#if ICONV_SUPPORTS_ERRNO
+ if (errno == EINVAL) {
+ err = PHP_ICONV_ERR_WRONG_CHARSET;
+ } else {
+ err = PHP_ICONV_ERR_CONVERTER;
+ }
+#else
+ err = PHP_ICONV_ERR_UNKNOWN;
+#endif
+ break;
+ }
}
+
+ _php_iconv_appendl(pretval, buf, sizeof(buf), cd2);
+ --len;
}
+
}
#if ICONV_SUPPORTS_ERRNO
@@ -709,14 +753,19 @@
}
#endif
if (err == PHP_ICONV_ERR_SUCCESS) {
- if (substr_ofs != NULL) {
- smart_str_appendl(pretval, substr_ofs, (size_t)(in_p -
substr_ofs));
+ if (cd2 != NULL) {
+ _php_iconv_appendl(pretval, NULL, 0, cd2);
}
smart_str_0(pretval);
}
- icv_close(cd);
+ if (cd1 != NULL) {
+ icv_close(cd1);
+ }
+ if (cd2 != NULL) {
+ icv_close(cd2);
+ }
return err;
}
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php