diff options
-rw-r--r-- | ext/iconv/iconv.c | 194 |
1 files changed, 90 insertions, 104 deletions
diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index ba0a6ab6e8..9310870dfb 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -49,14 +49,14 @@ #endif -/* {{{ iconv_functions[] +/* {{{ iconv_functions[] */ function_entry iconv_functions[] = { PHP_NAMED_FE(iconv,php_if_iconv, NULL) PHP_FE(ob_iconv_handler, NULL) PHP_FE(iconv_get_encoding, NULL) PHP_FE(iconv_set_encoding, NULL) - {NULL, NULL, NULL} + {NULL, NULL, NULL} }; /* }}} */ @@ -71,7 +71,7 @@ zend_module_entry iconv_module_entry = { NULL, NULL, PHP_MINFO(miconv), - NO_VERSION_YET, + NO_VERSION_YET, STANDARD_MODULE_PROPERTIES }; /* }}} */ @@ -122,12 +122,12 @@ PHP_MINFO_FUNCTION(miconv) DISPLAY_INI_ENTRIES(); } # -#define PHP_ICONV_CONVERTER 1 -#define PHP_ICONV_WRONG_CHARSET 2 -#define PHP_ICONV_TOO_BIG 3 -#define PHP_ICONV_ILLEGAL_SEQ 4 -#define PHP_ICONV_ILLEGAL_CHAR 5 -#define PHP_ICONV_UNKNOWN 6 +#define PHP_ICONV_CONVERTER 1 +#define PHP_ICONV_WRONG_CHARSET 2 +#define PHP_ICONV_TOO_BIG 3 +#define PHP_ICONV_ILLEGAL_SEQ 4 +#define PHP_ICONV_ILLEGAL_CHAR 5 +#define PHP_ICONV_UNKNOWN 6 /* {{{ php_iconv_string */ @@ -137,14 +137,14 @@ static int php_iconv_string(const char *in_p, size_t in_len, { #if HAVE_LIBICONV /* No errno for libiconv(?) */ - unsigned int in_size, out_size, out_left; - char *out_buffer, *out_p; - iconv_t cd; - size_t result; - typedef unsigned int ucs4_t; + unsigned int in_size, out_size, out_left; + char *out_buffer, *out_p; + iconv_t cd; + size_t result; + typedef unsigned int ucs4_t; *err = 0; - in_size = in_len; + in_size = in_len; /* This is not the right way to get output size... @@ -153,53 +153,53 @@ static int php_iconv_string(const char *in_p, size_t in_len, 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) + 16; + out_buffer = (char *) emalloc(out_size); + *out = out_buffer; - out_p = out_buffer; + out_p = out_buffer; out_left = out_size; - - cd = icv_open(out_charset, in_charset); - + + cd = icv_open(out_charset, in_charset); + if (cd == (iconv_t)(-1)) { *err = PHP_ICONV_UNKNOWN; - php_error(E_WARNING, "iconv: cannot convert from `%s' to `%s'", - in_charset, out_charset); + php_error(E_WARNING, "%s(): unknown error, unable to convert from `%s' to `%s'", + get_active_function_name(TSRMLS_C), in_charset, out_charset); efree(out_buffer); return FAILURE; } result = icv(cd, (char **) &in_p, &in_size, (char **) - &out_p, &out_left); - - if (result == (size_t)(-1)) { + &out_p, &out_left); + + if (result == (size_t)(-1)) { *err = PHP_ICONV_UNKNOWN; efree(out_buffer); return FAILURE; - } - + } + *out_len = out_size - out_left; out_buffer[*out_len] = '\0'; - icv_close(cd); - - return SUCCESS; + icv_close(cd); + + return SUCCESS; #else /* libc iconv should support 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; + iconv_t cd; + size_t in_left, out_size, out_left; + char *out_p, *out_buf, *tmp_buf; + size_t i, bsz, result; *err = 0; - cd = iconv_open(out_charset, in_charset); + cd = iconv_open(out_charset, in_charset); if (cd == (iconv_t)(-1)) { if (errno == EINVAL) { *err = PHP_ICONV_WRONG_CHARSET; - php_error(E_NOTICE, "%s() 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 { @@ -207,14 +207,14 @@ static int php_iconv_string(const char *in_p, size_t in_len, php_error(E_NOTICE, "%s() cannot open converter", get_active_function_name(TSRMLS_C)); } - return FAILURE; + return FAILURE; } in_left= in_len; out_left = in_len + 32; /* Avoid realloc() most cases */ bsz = out_left; - out_buf = (char *) emalloc(bsz+1); - out_p = out_buf; + 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++) { @@ -230,39 +230,39 @@ static int php_iconv_string(const char *in_p, size_t in_len, result = iconv(cd, (char **)&in_p, &in_left, &out_p, &out_left); out_size += bsz - out_left; } - iconv_close(cd); - if (result == (size_t)(-1)) { + iconv_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() error", - get_active_function_name(TSRMLS_C)); + php_error(E_NOTICE, "%s() unknown error (%d)", + get_active_function_name(TSRMLS_C), errno); *err = PHP_ICONV_UNKNOWN; efree(out_buf); return FAILURE; break; } - } + } *out_p = '\0'; *out = out_buf; *out_len = out_size; - return SUCCESS; + return SUCCESS; #endif } /* }}} */ @@ -271,22 +271,17 @@ static int php_iconv_string(const char *in_p, size_t in_len, Returns str converted to the out_charset character set */ PHP_NAMED_FUNCTION(php_if_iconv) { - zval **in_charset, **out_charset, **in_buffer; - char *out_buffer; + char *in_charset, *out_charset, *in_buffer, *out_buffer; unsigned int out_len; - int err; + int in_charset_len, out_charset_len, in_buffer_len, err; - if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &in_charset, &out_charset, &in_buffer) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(in_charset); - convert_to_string_ex(out_charset); - convert_to_string_ex(in_buffer); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", + &in_charset, &in_charset_len, &out_charset, &out_charset_len, &in_buffer, &in_buffer_len) == FAILURE) + return; - if (php_iconv_string(Z_STRVAL_PP(in_buffer), Z_STRLEN_PP(in_buffer), + if (php_iconv_string(in_buffer, in_buffer_len, &out_buffer, &out_len, - Z_STRVAL_PP(in_charset), Z_STRVAL_PP(out_charset), &err TSRMLS_CC) == SUCCESS) { + in_charset, out_charset, &err TSRMLS_CC) == SUCCESS) { RETVAL_STRINGL(out_buffer, out_len, 0); } else { RETURN_FALSE; @@ -299,28 +294,26 @@ PHP_NAMED_FUNCTION(php_if_iconv) PHP_FUNCTION(ob_iconv_handler) { char *out_buffer; - zval **zv_string, **zv_status; + zval *zv_string; unsigned int out_len; - int err; + int err, status;; - if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &zv_string, &zv_status)==FAILURE) { - ZEND_WRONG_PARAM_COUNT(); - } + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &zv_string, &status) == FAILURE) + return; - convert_to_string_ex(zv_string); - convert_to_long_ex(zv_status); + convert_to_string_ex(&zv_string); if (SG(sapi_headers).send_default_content_type && - php_iconv_string(Z_STRVAL_PP(zv_string), Z_STRLEN_PP(zv_string), + php_iconv_string(Z_STRVAL_P(zv_string), Z_STRLEN_P(zv_string), &out_buffer, &out_len, - ICONVG(internal_encoding), + ICONVG(internal_encoding), ICONVG(output_encoding), - &err TSRMLS_CC)==SUCCESS) { + &err TSRMLS_CC) == SUCCESS) { RETVAL_STRINGL(out_buffer, out_len, 0); } else { zval_dtor(return_value); - *return_value = **zv_string; - zval_copy_ctor(return_value); + *return_value = *zv_string; + zval_copy_ctor(return_value); } } @@ -330,22 +323,18 @@ PHP_FUNCTION(ob_iconv_handler) Sets internal encoding and output encoding for ob_iconv_handler() */ PHP_FUNCTION(iconv_set_encoding) { - zval **type, **charset; - int argc = ZEND_NUM_ARGS(), retval; - - if (argc != 2 || zend_get_parameters_ex(2, &type, &charset) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(type); - convert_to_string_ex(charset); - - if(!strcasecmp("input_encoding", Z_STRVAL_PP(type))) { - retval = zend_alter_ini_entry("iconv.input_encoding", sizeof("iconv.input_encoding"), Z_STRVAL_PP(charset), Z_STRLEN_PP(charset), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - } else if(!strcasecmp("output_encoding", Z_STRVAL_PP(type))) { - retval = zend_alter_ini_entry("iconv.output_encoding", sizeof("iconv.output_encoding"), Z_STRVAL_PP(charset), Z_STRLEN_PP(charset), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - } else if(!strcasecmp("internal_encoding", Z_STRVAL_PP(type))) { - retval = zend_alter_ini_entry("iconv.internal_encoding", sizeof("iconv.internal_encoding"), Z_STRVAL_PP(charset), Z_STRLEN_PP(charset), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + char *type, *charset; + int type_len, charset_len, retval; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &type, &type_len, &charset, &charset_len) == FAILURE) + return; + + if(!strcasecmp("input_encoding", type)) { + retval = zend_alter_ini_entry("iconv.input_encoding", sizeof("iconv.input_encoding"), charset, charset_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + } else if(!strcasecmp("output_encoding", type)) { + retval = zend_alter_ini_entry("iconv.output_encoding", sizeof("iconv.output_encoding"), charset, charset_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + } else if(!strcasecmp("internal_encoding", type)) { + retval = zend_alter_ini_entry("iconv.internal_encoding", sizeof("iconv.internal_encoding"), charset, charset_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); } else { RETURN_FALSE; } @@ -362,30 +351,27 @@ PHP_FUNCTION(iconv_set_encoding) Get internal encoding and output encoding for ob_iconv_handler() */ PHP_FUNCTION(iconv_get_encoding) { - zval **type; - int argc = ZEND_NUM_ARGS(); - - if (argc < 0 || argc > 1 || zend_get_parameters_ex(1, &type) == FAILURE) { - WRONG_PARAM_COUNT; - } + char *type = "all"; + int type_len; - convert_to_string_ex(type); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &type, &type_len) == FAILURE) + return; - if (argc == 0 || !strcasecmp("all", Z_STRVAL_PP(type))) { + if (!strcasecmp("all", type)) { if (array_init(return_value) == FAILURE) { RETURN_FALSE; } - add_assoc_string(return_value, "input_encoding", + add_assoc_string(return_value, "input_encoding", ICONVG(input_encoding), 1); - add_assoc_string(return_value, "output_encoding", + add_assoc_string(return_value, "output_encoding", ICONVG(output_encoding), 1); - add_assoc_string(return_value, "internal_encoding", + add_assoc_string(return_value, "internal_encoding", ICONVG(internal_encoding), 1); - } else if (!strcasecmp("input_encoding", Z_STRVAL_PP(type))) { + } else if (!strcasecmp("input_encoding", type)) { RETVAL_STRING(ICONVG(input_encoding), 1); - } else if (!strcasecmp("output_encoding", Z_STRVAL_PP(type))) { + } else if (!strcasecmp("output_encoding", type)) { RETVAL_STRING(ICONVG(output_encoding), 1); - } else if (!strcasecmp("internal_encoding", Z_STRVAL_PP(type))) { + } else if (!strcasecmp("internal_encoding", type)) { RETVAL_STRING(ICONVG(internal_encoding), 1); } else { RETURN_FALSE; |