cvs: php4 /ext/iconv config.m4 iconv.c

From: Date: Thu, 11 Jul 2002 03:37:28 +0000
Subject: cvs: php4 /ext/iconv config.m4 iconv.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-12775@lists.php.net to get a copy of this message
yohgaki Wed Jul 10 23:37:28 2002 EDT Modified files: /php4/ext/iconv config.m4 iconv.c Log: Fix #16069. Patch by Moriyoshi Koizumi <readjust@deneb.freemail.ne.jp> @ Made iconv() work well with libiconv or libgconv. (Moriyoshi, Yasuo) Index: php4/ext/iconv/config.m4 diff -u php4/ext/iconv/config.m4:1.11 php4/ext/iconv/config.m4:1.12 --- php4/ext/iconv/config.m4:1.11 Sun Mar 17 16:09:21 2002 +++ php4/ext/iconv/config.m4 Wed Jul 10 23:37:28 2002 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.11 2002/03/17 21:09:21 sniper Exp $ +dnl $Id: config.m4,v 1.12 2002/07/11 03:37:28 yohgaki Exp $ dnl PHP_ARG_WITH(iconv, for iconv support, @@ -8,6 +8,41 @@ if test "$PHP_ICONV" != "no"; then PHP_SETUP_ICONV(ICONV_SHARED_LIBADD, [ + AC_MSG_CHECKING([if iconv supports errno]) + AC_TRY_RUN([ +#define LIBICONV_PLUG +#include <iconv.h> +#include <errno.h> +#if defined(_LIBICONV_H) +#define icv_open(a, b) libiconv_open(a, b) +#define icv_close(a) libiconv_close(a) +#define icv(a, b, c, d, e) libiconv(a, b, c, d, e) +#else +#define icv_open(a, b) iconv_open(a, b) +#define icv_close(a) iconv_close(a) +#define icv(a, b, c, d, e) iconv(a, b, c, d, e) +#endif + +int main() { + iconv_t cd; + cd = icv_open( "*blahblah*", "*blahblah*" ); + if( cd == (iconv_t)(-1) ) { + if( errno == EINVAL ) { + return 0; + } else { + return 1; + } + } + icv_close( cd ); + return 2; +} +],[ + AC_MSG_RESULT(yes) + PHP_DEFINE(ICONV_SUPPORTS_ERRNO) +],[ + AC_MSG_RESULT(no) +]) + PHP_NEW_EXTENSION(iconv, iconv.c, $ext_shared) PHP_SUBST(ICONV_SHARED_LIBADD) ], [ Index: php4/ext/iconv/iconv.c diff -u php4/ext/iconv/iconv.c:1.39 php4/ext/iconv/iconv.c:1.40 --- php4/ext/iconv/iconv.c:1.39 Fri Jun 28 03:12:32 2002 +++ php4/ext/iconv/iconv.c Wed Jul 10 23:37:28 2002 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: iconv.c,v 1.39 2002/06/28 07:12:32 derick Exp $ */ +/* $Id: iconv.c,v 1.40 2002/07/11 03:37:28 yohgaki Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -28,6 +28,7 @@ #ifdef PHP_ATOM_INC #include "php_have_iconv.h" #include "php_have_libiconv.h" +#include "php_iconv_supports_errno.h" #endif #if HAVE_ICONV @@ -49,6 +50,7 @@ #if HAVE_LIBICONV +#define LIBICONV_PLUG #define icv_open(a, b) libiconv_open(a, b) #define icv_close(a) libiconv_close(a) #define icv(a, b, c, d, e) libiconv(a, b, c, d, e) @@ -145,8 +147,7 @@ char **out, size_t *out_len, const char *in_charset, const char *out_charset, int *err TSRMLS_DC) { -#if HAVE_LIBICONV - /* No errno for libiconv(?) */ +#if !defined(ICONV_SUPPORTS_ERRNO) unsigned int in_size, out_size, out_left; char *out_buffer, *out_p; iconv_t cd; @@ -163,9 +164,9 @@ a single char can be more than 4 bytes. I added 15 extra bytes for safety. <yohgaki@php.net> */ - out_size = in_len * sizeof(ucs4_t) + 16; - out_buffer = (char *) emalloc(out_size); - + out_size = in_len * sizeof(ucs4_t) + 15; + out_buffer = (char *) emalloc(out_size + 1); + *out = out_buffer; out_p = out_buffer; out_left = out_size; @@ -197,71 +198,78 @@ #else /* - libc iconv should support errno. Handle it better way. + iconv supports errno. Handle it better way. */ iconv_t cd; size_t in_left, out_size, out_left; char *out_p, *out_buf, *tmp_buf; - size_t i, bsz, result; + size_t bsz, result; *err = 0; - cd = iconv_open(out_charset, in_charset); + cd = icv_open(out_charset, in_charset); + if (cd == (iconv_t)(-1)) { if (errno == EINVAL) { *err = PHP_ICONV_WRONG_CHARSET; - php_error(E_NOTICE, "%s() wrong charset, cannot convert from %s' to %s'", + php_error(E_NOTICE, "%s(): wrong charset, cannot convert from %s' to %s'", get_active_function_name(TSRMLS_C), in_charset, out_charset); - } - else { + } else { *err = PHP_ICONV_CONVERTER; - php_error(E_NOTICE, "%s() cannot open converter", + php_error(E_NOTICE, "%s(): cannot open converter", get_active_function_name(TSRMLS_C)); } return FAILURE; } - in_left= in_len; out_left = in_len + 32; /* Avoid realloc() most cases */ + out_size = 0; bsz = out_left; out_buf = (char *) emalloc(bsz+1); out_p = out_buf; - result = iconv(cd, (char **)&in_p, &in_left, (char **) &out_p, &out_left); - out_size = bsz - out_left; - for (i = 2;in_left > 0 && errno == E2BIG; i++) { - /* converted string is longer than out buffer */ - tmp_buf = (char*)erealloc(out_buf, bsz*i+1); - if (tmp_buf == NULL) { - break; + + while(in_left > 0) { + result = icv(cd, (char **)&in_p, &in_left, (char **) &out_p, &out_left); + out_size = bsz - out_left; + if( result == (size_t)(-1) ) { + if( errno == E2BIG && in_left > 0 ) { + /* converted string is longer than out buffer */ + bsz += in_len; + + tmp_buf = (char*) erealloc(out_buf, bsz+1); + + if (tmp_buf != NULL) { + out_p = out_buf = tmp_buf; + out_p += out_size; + out_left = bsz - out_size; + continue; + } + } } - out_buf = tmp_buf; - out_p = tmp_buf; - out_p += out_size; - out_left = bsz; - result = iconv(cd, (char **)&in_p, &in_left, &out_p, &out_left); - out_size += bsz - out_left; + break; } - iconv_close(cd); + icv_close(cd); + if (result == (size_t)(-1)) { switch (errno) { case EINVAL: - php_error(E_NOTICE, "%s() detected incomplete character in input string", + php_error(E_NOTICE, "%s(): detected incomplete character in input string", get_active_function_name(TSRMLS_C)); *err = PHP_ICONV_ILLEGAL_CHAR; break; case EILSEQ: - php_error(E_NOTICE, "%s() detected illegal character in input string", + php_error(E_NOTICE, "%s(): detected illegal character in input string", get_active_function_name(TSRMLS_C)); *err = PHP_ICONV_ILLEGAL_SEQ; break; case E2BIG: /* should not happen */ - php_error(E_WARNING, "%s() run out buffer", + php_error(E_WARNING, "%s(): run out buffer", get_active_function_name(TSRMLS_C)); *err = PHP_ICONV_TOO_BIG; break; default: /* other error */ - php_error(E_NOTICE, "%s() unknown error (%d)", + php_error(E_NOTICE, "%s(): unknown error (%d)", get_active_function_name(TSRMLS_C), errno); *err = PHP_ICONV_UNKNOWN; efree(out_buf);

« previous php.cvs (#12775) next »