diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-03-14 05:42:27 +0000 |
---|---|---|
committer | <> | 2013-04-03 16:25:08 +0000 |
commit | c4dd7a1a684490673e25aaf4fabec5df138854c4 (patch) | |
tree | 4d57c44caae4480efff02b90b9be86f44bf25409 /ext/iconv | |
download | php2-master.tar.gz |
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/iconv')
81 files changed, 10092 insertions, 0 deletions
diff --git a/ext/iconv/CREDITS b/ext/iconv/CREDITS new file mode 100644 index 0000000..70d3825 --- /dev/null +++ b/ext/iconv/CREDITS @@ -0,0 +1,2 @@ +Iconv +Rui Hirokawa, Stig Bakken, Moriyoshi Koizumi diff --git a/ext/iconv/config.m4 b/ext/iconv/config.m4 new file mode 100644 index 0000000..d673b0a --- /dev/null +++ b/ext/iconv/config.m4 @@ -0,0 +1,180 @@ +dnl +dnl $Id$ +dnl + +PHP_ARG_WITH(iconv, for iconv support, +[ --without-iconv[=DIR] Exclude iconv support], yes) + +if test "$PHP_ICONV" != "no"; then + + PHP_SETUP_ICONV(ICONV_SHARED_LIBADD, [ + iconv_avail="yes"; + ],[ + iconv_avail="no"; + ]) + + if test "$iconv_avail" != "no"; then + if test -z "$ICONV_DIR"; then + for i in /usr/local /usr; do + if test -f "$i/include/iconv.h" || test -f "$i/include/giconv.h"; then + PHP_ICONV_PREFIX="$i" + break + fi + done + if test -z "$PHP_ICONV_PREFIX"; then + PHP_ICONV_PREFIX="/usr" + fi + else + PHP_ICONV_PREFIX="$ICONV_DIR" + fi + + CFLAGS="-I$PHP_ICONV_PREFIX/include $CFLAGS" + LDFLAGS="-L$PHP_ICONV_PREFIX/$PHP_LIBDIR $LDFLAGS" + + if test -r "$PHP_ICONV_PREFIX/include/giconv.h"; then + PHP_ICONV_H_PATH="$PHP_ICONV_PREFIX/include/giconv.h" + else + PHP_ICONV_H_PATH="$PHP_ICONV_PREFIX/include/iconv.h" + fi + + AC_MSG_CHECKING([if iconv is glibc's]) + AC_TRY_LINK([#include <gnu/libc-version.h>],[gnu_get_libc_version();], + [ + AC_MSG_RESULT(yes) + iconv_impl_name="glibc" + ],[ + AC_MSG_RESULT(no) + ]) + + if test -z "$iconv_impl_name"; then + AC_MSG_CHECKING([if using GNU libiconv]) + php_iconv_old_ld="$LDFLAGS" + LDFLAGS="-liconv $LDFLAGS" + AC_TRY_RUN([ +#include <$PHP_ICONV_H_PATH> +int main() { + printf("%d", _libiconv_version); + return 0; +} + ],[ + AC_MSG_RESULT(yes) + iconv_impl_name="gnu_libiconv" + ],[ + AC_MSG_RESULT(no) + LDFLAGS="$php_iconv_old_ld" + ],[ + AC_MSG_RESULT(no, cross-compiling) + LDFLAGS="$php_iconv_old_ld" + ]) + fi + + if test -z "$iconv_impl_name"; then + AC_MSG_CHECKING([if iconv is Konstantin Chuguev's]) + AC_TRY_LINK([#include <iconv.h>],[iconv_ccs_init(NULL, NULL);], + [ + AC_MSG_RESULT(yes) + iconv_impl_name="bsd" + ],[ + AC_MSG_RESULT(no) + ]) + fi + + if test -z "$iconv_impl_name"; then + AC_MSG_CHECKING([if using IBM iconv]) + php_iconv_old_ld="$LDFLAGS" + LDFLAGS="-liconv $LDFLAGS" + AC_TRY_LINK([#include <iconv.h>],[cstoccsid("");], + [ + AC_MSG_RESULT(yes) + iconv_impl_name="ibm" + ],[ + AC_MSG_RESULT(no) + LDFLAGS="$php_iconv_old_ld" + ]) + fi + + echo > ext/iconv/php_have_bsd_iconv.h + echo > ext/iconv/php_have_glibc_iconv.h + echo > ext/iconv/php_have_libiconv.h + echo > ext/iconv/php_have_ibm_iconv.h + + case "$iconv_impl_name" in + gnu_libiconv [)] + PHP_DEFINE([PHP_ICONV_IMPL],[\"libiconv\"],[ext/iconv]) + AC_DEFINE([PHP_ICONV_IMPL],["libiconv"],[Which iconv implementation to use]) + PHP_DEFINE([HAVE_LIBICONV],1,[ext/iconv]) + PHP_ADD_LIBRARY_WITH_PATH(iconv, "$PHP_ICONV_PREFIX/$PHP_LIBDIR", ICONV_SHARED_LIBADD) + ;; + + bsd [)] + PHP_DEFINE([HAVE_BSD_ICONV],1,[ext/iconv]) + AC_DEFINE([HAVE_BSD_ICONV],1,[Konstantin Chuguev's iconv implementation]) + PHP_DEFINE([PHP_ICONV_IMPL],[\"BSD iconv\"],[ext/iconv]) + AC_DEFINE([PHP_ICONV_IMPL],["BSD iconv"],[Which iconv implementation to use]) + ;; + + glibc [)] + PHP_DEFINE([HAVE_GLIBC_ICONV],1,[ext/iconv]) + AC_DEFINE([HAVE_GLIBC_ICONV],1,[glibc's iconv implementation]) + PHP_DEFINE([PHP_ICONV_IMPL],[\"glibc\"],[ext/iconv]) + AC_DEFINE([PHP_ICONV_IMPL],["glibc"],[Which iconv implementation to use]) + ;; + ibm [)] + PHP_DEFINE([HAVE_IBM_ICONV],1,[ext/iconv]) + AC_DEFINE([HAVE_IBM_ICONV],1,[IBM iconv implementation]) + PHP_DEFINE([PHP_ICONV_IMPL],[\"IBM iconv\"],[ext/iconv]) + AC_DEFINE([PHP_ICONV_IMPL],["IBM iconv"],[Which iconv implementation to use]) + ;; + esac + + AC_MSG_CHECKING([if iconv supports errno]) + AC_TRY_RUN([ +#include <$PHP_ICONV_H_PATH> +#include <errno.h> + +int main() { + iconv_t cd; + cd = iconv_open( "*blahblah*", "*blahblah*" ); + if (cd == (iconv_t)(-1)) { + if (errno == EINVAL) { + return 0; + } else { + return 1; + } + } + iconv_close( cd ); + return 2; +} + ],[ + AC_MSG_RESULT(yes) + PHP_DEFINE([ICONV_SUPPORTS_ERRNO],1,[ext/iconv]) + AC_DEFINE([ICONV_SUPPORTS_ERRNO],1,[Whether iconv supports error no or not]) + ],[ + AC_MSG_RESULT(no) + PHP_DEFINE([ICONV_SUPPORTS_ERRNO],0,[ext/iconv]) + AC_DEFINE([ICONV_SUPPORTS_ERRNO],0,[Whether iconv supports error no or not]) + ],[ + AC_MSG_RESULT(no, cross-compiling) + PHP_DEFINE([ICONV_SUPPORTS_ERRNO],0,[ext/iconv]) + AC_DEFINE([ICONV_SUPPORTS_ERRNO],0,[Whether iconv supports error no or not]) + ]) + + AC_MSG_CHECKING([if your cpp allows macro usage in include lines]) + AC_TRY_COMPILE([ +#define FOO <$PHP_ICONV_H_PATH> +#include FOO + ], [], [ + AC_MSG_RESULT([yes]) + PHP_DEFINE([PHP_ICONV_H_PATH], [<$PHP_ICONV_H_PATH>],[ext/iconv]) + AC_DEFINE_UNQUOTED([PHP_ICONV_H_PATH], [<$PHP_ICONV_H_PATH>], [Path to iconv.h]) + ], [ + AC_MSG_RESULT([no]) + ]) + + PHP_NEW_EXTENSION(iconv, iconv.c, $ext_shared,, [-I\"$PHP_ICONV_PREFIX/include\"]) + PHP_SUBST(ICONV_SHARED_LIBADD) + PHP_INSTALL_HEADERS([ext/iconv/]) + else + AC_MSG_ERROR(Please reinstall the iconv library.) + fi +fi diff --git a/ext/iconv/config.w32 b/ext/iconv/config.w32 new file mode 100644 index 0000000..00ab272 --- /dev/null +++ b/ext/iconv/config.w32 @@ -0,0 +1,28 @@ +// $Id$ +// vim: ft=javascript + +ARG_WITH("iconv", "iconv support", "yes"); + +if (PHP_ICONV != "no") { + if ((CHECK_LIB("libiconv_a.lib", "iconv", PHP_ICONV) || CHECK_LIB("libiconv.lib", "iconv", PHP_ICONV) || + CHECK_LIB("iconv_a.lib", "iconv", PHP_ICONV) || CHECK_LIB("iconv.lib", "iconv", PHP_ICONV)) && + CHECK_HEADER_ADD_INCLUDE("iconv.h", "CFLAGS_ICONV", PHP_ICONV)) { + + EXTENSION("iconv", "iconv.c"); + + AC_DEFINE("HAVE_ICONV", 1, "Define if iconv extension is enabled"); + AC_DEFINE("HAVE_LIBICONV", 1, "Define if libiconv is available"); + AC_DEFINE("ICONV_ALIASED_LIBICONV", 1, "The iconv function is called iconv() in libiconv"); + AC_DEFINE("PHP_ICONV_IMPL", "\"libiconv\"", "Which iconv implementation to use"); + AC_DEFINE("ICONV_SUPPORTS_ERRNO", 1, "Whether iconv supports errno or not"); + ADD_FLAG("CFLAGS_ICONV", "/D PHP_ICONV_EXPORTS "); + if (!PHP_ICONV_SHARED) { + ADD_DEF_FILE("ext\\iconv\\php_iconv.def"); + } + PHP_INSTALL_HEADERS("", "ext/iconv"); + } else { + WARNING("iconv support can't be enabled, libraries or headers are missing") + PHP_ICONV = "no"; + } +} + diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c new file mode 100644 index 0000000..ba893ea --- /dev/null +++ b/ext/iconv/iconv.c @@ -0,0 +1,2873 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Rui Hirokawa <rui_hirokawa@ybb.ne.jp> | + | Stig Bakken <ssb@php.net> | + | Moriyoshi Koizumi <moriyoshi@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "php_globals.h" +#include "ext/standard/info.h" +#include "main/php_output.h" +#include "SAPI.h" +#include "php_ini.h" + +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#endif + +#include <errno.h> + +#include "php_iconv.h" + +#ifdef HAVE_ICONV + +#ifdef PHP_ICONV_H_PATH +#include PHP_ICONV_H_PATH +#else +#include <iconv.h> +#endif + +#ifdef HAVE_GLIBC_ICONV +#include <gnu/libc-version.h> +#endif + +#ifdef HAVE_LIBICONV +#undef iconv +#endif + +#include "ext/standard/php_smart_str.h" +#include "ext/standard/base64.h" +#include "ext/standard/quot_print.h" + +#define _php_iconv_memequal(a, b, c) \ + ((c) == sizeof(unsigned long) ? *((unsigned long *)(a)) == *((unsigned long *)(b)) : ((c) == sizeof(unsigned int) ? *((unsigned int *)(a)) == *((unsigned int *)(b)) : memcmp(a, b, c) == 0)) + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_iconv_strlen, 0, 0, 1) + ZEND_ARG_INFO(0, str) + ZEND_ARG_INFO(0, charset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_iconv_substr, 0, 0, 2) + ZEND_ARG_INFO(0, str) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, length) + ZEND_ARG_INFO(0, charset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_iconv_strpos, 0, 0, 2) + ZEND_ARG_INFO(0, haystack) + ZEND_ARG_INFO(0, needle) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, charset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_iconv_strrpos, 0, 0, 2) + ZEND_ARG_INFO(0, haystack) + ZEND_ARG_INFO(0, needle) + ZEND_ARG_INFO(0, charset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_iconv_mime_encode, 0, 0, 2) + ZEND_ARG_INFO(0, field_name) + ZEND_ARG_INFO(0, field_value) + ZEND_ARG_INFO(0, preference) /* ZEND_ARG_ARRAY_INFO(0, preference, 1) */ +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_iconv_mime_decode, 0, 0, 1) + ZEND_ARG_INFO(0, encoded_string) + ZEND_ARG_INFO(0, mode) + ZEND_ARG_INFO(0, charset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_iconv_mime_decode_headers, 0, 0, 1) + ZEND_ARG_INFO(0, headers) + ZEND_ARG_INFO(0, mode) + ZEND_ARG_INFO(0, charset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_iconv, 0) + ZEND_ARG_INFO(0, in_charset) + ZEND_ARG_INFO(0, out_charset) + ZEND_ARG_INFO(0, str) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_iconv_set_encoding, 0) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, charset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_iconv_get_encoding, 0, 0, 0) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +/* }}} */ + +/* {{{ iconv_functions[] + */ +const zend_function_entry iconv_functions[] = { + PHP_RAW_NAMED_FE(iconv,php_if_iconv, arginfo_iconv) + PHP_FE(iconv_get_encoding, arginfo_iconv_get_encoding) + PHP_FE(iconv_set_encoding, arginfo_iconv_set_encoding) + PHP_FE(iconv_strlen, arginfo_iconv_strlen) + PHP_FE(iconv_substr, arginfo_iconv_substr) + PHP_FE(iconv_strpos, arginfo_iconv_strpos) + PHP_FE(iconv_strrpos, arginfo_iconv_strrpos) + PHP_FE(iconv_mime_encode, arginfo_iconv_mime_encode) + PHP_FE(iconv_mime_decode, arginfo_iconv_mime_decode) + PHP_FE(iconv_mime_decode_headers, arginfo_iconv_mime_decode_headers) + PHP_FE_END +}; +/* }}} */ + +ZEND_DECLARE_MODULE_GLOBALS(iconv) +static PHP_GINIT_FUNCTION(iconv); + +/* {{{ iconv_module_entry + */ +zend_module_entry iconv_module_entry = { + STANDARD_MODULE_HEADER, + "iconv", + iconv_functions, + PHP_MINIT(miconv), + PHP_MSHUTDOWN(miconv), + NULL, + NULL, + PHP_MINFO(miconv), + NO_VERSION_YET, + PHP_MODULE_GLOBALS(iconv), + PHP_GINIT(iconv), + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX +}; +/* }}} */ + +#ifdef COMPILE_DL_ICONV +ZEND_GET_MODULE(iconv) +#endif + +/* {{{ PHP_GINIT_FUNCTION */ +static PHP_GINIT_FUNCTION(iconv) +{ + iconv_globals->input_encoding = NULL; + iconv_globals->output_encoding = NULL; + iconv_globals->internal_encoding = NULL; +} +/* }}} */ + +#if defined(HAVE_LIBICONV) && defined(ICONV_ALIASED_LIBICONV) +#define iconv libiconv +#endif + +/* {{{ typedef enum php_iconv_enc_scheme_t */ +typedef enum _php_iconv_enc_scheme_t { + PHP_ICONV_ENC_SCHEME_BASE64, + PHP_ICONV_ENC_SCHEME_QPRINT +} php_iconv_enc_scheme_t; +/* }}} */ + +#define PHP_ICONV_MIME_DECODE_STRICT (1<<0) +#define PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR (1<<1) + +/* {{{ prototypes */ +static php_iconv_err_t _php_iconv_appendl(smart_str *d, const char *s, size_t l, iconv_t cd); +static php_iconv_err_t _php_iconv_appendc(smart_str *d, const char c, iconv_t cd); + +static void _php_iconv_show_error(php_iconv_err_t err, const char *out_charset, const char *in_charset TSRMLS_DC); + +static php_iconv_err_t _php_iconv_strlen(unsigned int *pretval, const char *str, size_t nbytes, const char *enc); + +static php_iconv_err_t _php_iconv_substr(smart_str *pretval, const char *str, size_t nbytes, int offset, int len, const char *enc); + +static php_iconv_err_t _php_iconv_strpos(unsigned int *pretval, const char *haystk, size_t haystk_nbytes, const char *ndl, size_t ndl_nbytes, int offset, const char *enc); + +static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fname, size_t fname_nbytes, const char *fval, size_t fval_nbytes, unsigned int max_line_len, const char *lfchars, php_iconv_enc_scheme_t enc_scheme, const char *out_charset, const char *enc); + +static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *str, size_t str_nbytes, const char *enc, const char **next_pos, int mode); + +static php_iconv_err_t php_iconv_stream_filter_register_factory(TSRMLS_D); +static php_iconv_err_t php_iconv_stream_filter_unregister_factory(TSRMLS_D); + +static int php_iconv_output_conflict(const char *handler_name, size_t handler_name_len TSRMLS_DC); +static php_output_handler *php_iconv_output_handler_init(const char *name, size_t name_len, size_t chunk_size, int flags TSRMLS_DC); +static int php_iconv_output_handler(void **nothing, php_output_context *output_context); +/* }}} */ + +/* {{{ static globals */ +static char _generic_superset_name[] = ICONV_UCS4_ENCODING; +#define GENERIC_SUPERSET_NAME _generic_superset_name +#define GENERIC_SUPERSET_NBYTES 4 +/* }}} */ + +static PHP_INI_MH(OnUpdateStringIconvCharset) +{ + if(new_value_length >= ICONV_CSNMAXLEN) { + return FAILURE; + } + OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); + return SUCCESS; +} + +/* {{{ PHP_INI + */ +PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("iconv.input_encoding", ICONV_INPUT_ENCODING, PHP_INI_ALL, OnUpdateStringIconvCharset, input_encoding, zend_iconv_globals, iconv_globals) + STD_PHP_INI_ENTRY("iconv.output_encoding", ICONV_OUTPUT_ENCODING, PHP_INI_ALL, OnUpdateStringIconvCharset, output_encoding, zend_iconv_globals, iconv_globals) + STD_PHP_INI_ENTRY("iconv.internal_encoding", ICONV_INTERNAL_ENCODING, PHP_INI_ALL, OnUpdateStringIconvCharset, internal_encoding, zend_iconv_globals, iconv_globals) +PHP_INI_END() +/* }}} */ + +/* {{{ PHP_MINIT_FUNCTION */ +PHP_MINIT_FUNCTION(miconv) +{ + char *version = "unknown"; + + REGISTER_INI_ENTRIES(); + +#if HAVE_LIBICONV + { + static char buf[16]; + snprintf(buf, sizeof(buf), "%d.%d", + ((_libiconv_version >> 8) & 0x0f), (_libiconv_version & 0x0f)); + version = buf; + } +#elif HAVE_GLIBC_ICONV + version = (char *)gnu_get_libc_version(); +#elif defined(NETWARE) + version = "OS built-in"; +#endif + +#ifdef PHP_ICONV_IMPL + REGISTER_STRING_CONSTANT("ICONV_IMPL", PHP_ICONV_IMPL, CONST_CS | CONST_PERSISTENT); +#elif HAVE_LIBICONV + REGISTER_STRING_CONSTANT("ICONV_IMPL", "libiconv", CONST_CS | CONST_PERSISTENT); +#elif defined(NETWARE) + REGISTER_STRING_CONSTANT("ICONV_IMPL", "Novell", CONST_CS | CONST_PERSISTENT); +#else + REGISTER_STRING_CONSTANT("ICONV_IMPL", "unknown", CONST_CS | CONST_PERSISTENT); +#endif + REGISTER_STRING_CONSTANT("ICONV_VERSION", version, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("ICONV_MIME_DECODE_STRICT", PHP_ICONV_MIME_DECODE_STRICT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ICONV_MIME_DECODE_CONTINUE_ON_ERROR", PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR, CONST_CS | CONST_PERSISTENT); + + if (php_iconv_stream_filter_register_factory(TSRMLS_C) != PHP_ICONV_ERR_SUCCESS) { + return FAILURE; + } + + php_output_handler_alias_register(ZEND_STRL("ob_iconv_handler"), php_iconv_output_handler_init TSRMLS_CC); + php_output_handler_conflict_register(ZEND_STRL("ob_iconv_handler"), php_iconv_output_conflict TSRMLS_CC); + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION */ +PHP_MSHUTDOWN_FUNCTION(miconv) +{ + php_iconv_stream_filter_unregister_factory(TSRMLS_C); + UNREGISTER_INI_ENTRIES(); + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MINFO_FUNCTION */ +PHP_MINFO_FUNCTION(miconv) +{ + zval iconv_impl, iconv_ver; + + zend_get_constant("ICONV_IMPL", sizeof("ICONV_IMPL")-1, &iconv_impl TSRMLS_CC); + zend_get_constant("ICONV_VERSION", sizeof("ICONV_VERSION")-1, &iconv_ver TSRMLS_CC); + + php_info_print_table_start(); + php_info_print_table_row(2, "iconv support", "enabled"); + php_info_print_table_row(2, "iconv implementation", Z_STRVAL(iconv_impl)); + php_info_print_table_row(2, "iconv library version", Z_STRVAL(iconv_ver)); + php_info_print_table_end(); + + DISPLAY_INI_ENTRIES(); + + zval_dtor(&iconv_impl); + zval_dtor(&iconv_ver); +} +/* }}} */ + +static int php_iconv_output_conflict(const char *handler_name, size_t handler_name_len TSRMLS_DC) +{ + if (php_output_get_level(TSRMLS_C)) { + if (php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("ob_iconv_handler") TSRMLS_CC) + || php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("mb_output_handler") TSRMLS_CC)) { + return FAILURE; + } + } + return SUCCESS; +} + +static php_output_handler *php_iconv_output_handler_init(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags TSRMLS_DC) +{ + return php_output_handler_create_internal(handler_name, handler_name_len, php_iconv_output_handler, chunk_size, flags TSRMLS_CC); +} + +static int php_iconv_output_handler(void **nothing, php_output_context *output_context) +{ + char *s, *content_type, *mimetype = NULL; + int output_status, mimetype_len = 0; + PHP_OUTPUT_TSRMLS(output_context); + + if (output_context->op & PHP_OUTPUT_HANDLER_START) { + output_status = php_output_get_status(TSRMLS_C); + if (output_status & PHP_OUTPUT_SENT) { + return FAILURE; + } + + if (SG(sapi_headers).mimetype && !strncasecmp(SG(sapi_headers).mimetype, "text/", 5)) { + if ((s = strchr(SG(sapi_headers).mimetype,';')) == NULL){ + mimetype = SG(sapi_headers).mimetype; + } else { + mimetype = SG(sapi_headers).mimetype; + mimetype_len = s - SG(sapi_headers).mimetype; + } + } else if (SG(sapi_headers).send_default_content_type) { + mimetype = SG(default_mimetype) ? SG(default_mimetype) : SAPI_DEFAULT_MIMETYPE; + } + + if (mimetype != NULL && !(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) { + int len; + char *p = strstr(ICONVG(output_encoding), "//"); + + if (p) { + len = spprintf(&content_type, 0, "Content-Type:%.*s; charset=%.*s", mimetype_len ? mimetype_len : (int) strlen(mimetype), mimetype, (int)(p - ICONVG(output_encoding)), ICONVG(output_encoding)); + } else { + len = spprintf(&content_type, 0, "Content-Type:%.*s; charset=%s", mimetype_len ? mimetype_len : (int) strlen(mimetype), mimetype, ICONVG(output_encoding)); + } + if (content_type && SUCCESS == sapi_add_header(content_type, len, 0)) { + SG(sapi_headers).send_default_content_type = 0; + php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC); + } + } + } + + if (output_context->in.used) { + output_context->out.free = 1; + _php_iconv_show_error(php_iconv_string(output_context->in.data, output_context->in.used, &output_context->out.data, &output_context->out.used, ICONVG(output_encoding), ICONVG(internal_encoding)), ICONVG(output_encoding), ICONVG(internal_encoding) TSRMLS_CC); + } + + return SUCCESS; +} + +/* {{{ _php_iconv_appendl() */ +static php_iconv_err_t _php_iconv_appendl(smart_str *d, const char *s, size_t l, iconv_t cd) +{ + const char *in_p = s; + size_t in_left = l; + char *out_p; + size_t out_left = 0; + size_t buf_growth = 128; +#if !ICONV_SUPPORTS_ERRNO + size_t prev_in_left = in_left; +#endif + + 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; + + if (iconv(cd, (char **)&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; + + case EILSEQ: + return PHP_ICONV_ERR_ILLEGAL_SEQ; + + case E2BIG: + break; + + default: + return PHP_ICONV_ERR_UNKNOWN; + } +#else + 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; + } + } 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 (iconv(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; + } + } + return PHP_ICONV_ERR_SUCCESS; +} +/* }}} */ + +/* {{{ _php_iconv_appendc() */ +static php_iconv_err_t _php_iconv_appendc(smart_str *d, const char c, iconv_t cd) +{ + return _php_iconv_appendl(d, &c, 1, cd); +} +/* }}} */ + +/* {{{ php_iconv_string() + */ +PHP_ICONV_API php_iconv_err_t php_iconv_string(const char *in_p, size_t in_len, + char **out, size_t *out_len, + const char *out_charset, const char *in_charset) +{ +#if !ICONV_SUPPORTS_ERRNO + size_t in_size, out_size, out_left; + char *out_buffer, *out_p; + iconv_t cd; + size_t result; + + *out = NULL; + *out_len = 0; + + /* + This is not the right way to get output size... + This is not space efficient for large text. + This is also problem for encoding like UTF-7/UTF-8/ISO-2022 which + a single char can be more than 4 bytes. + I added 15 extra bytes for safety. <yohgaki@php.net> + */ + out_size = in_len * sizeof(int) + 15; + out_left = out_size; + + in_size = in_len; + + cd = iconv_open(out_charset, in_charset); + + if (cd == (iconv_t)(-1)) { + return PHP_ICONV_ERR_UNKNOWN; + } + + out_buffer = (char *) emalloc(out_size + 1); + out_p = out_buffer; + +#ifdef NETWARE + result = iconv(cd, (char **) &in_p, &in_size, (char **) +#else + result = iconv(cd, (const char **) &in_p, &in_size, (char **) +#endif + &out_p, &out_left); + + if (result == (size_t)(-1)) { + efree(out_buffer); + return PHP_ICONV_ERR_UNKNOWN; + } + + if (out_left < 8) { + size_t pos = out_p - out_buffer; + out_buffer = (char *) safe_erealloc(out_buffer, out_size, 1, 8); + out_p = out_buffer+pos; + out_size += 7; + out_left += 7; + } + + /* flush the shift-out sequences */ + result = iconv(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; + + iconv_close(cd); + + return PHP_ICONV_ERR_SUCCESS; + +#else + /* + 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 bsz, result = 0; + php_iconv_err_t retval = PHP_ICONV_ERR_SUCCESS; + + *out = NULL; + *out_len = 0; + + cd = iconv_open(out_charset, in_charset); + + if (cd == (iconv_t)(-1)) { + if (errno == EINVAL) { + return PHP_ICONV_ERR_WRONG_CHARSET; + } else { + return PHP_ICONV_ERR_CONVERTER; + } + } + 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; + + while (in_left > 0) { + result = iconv(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); + out_p = out_buf = tmp_buf; + out_p += out_size; + out_left = bsz - out_size; + continue; + } + } + break; + } + + if (result != (size_t)(-1)) { + /* flush the shift-out sequences */ + for (;;) { + result = iconv(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); + + out_p = out_buf = tmp_buf; + out_p += out_size; + out_left = bsz - out_size; + } else { + break; + } + } + } + + iconv_close(cd); + + if (result == (size_t)(-1)) { + switch (errno) { + case EINVAL: + retval = PHP_ICONV_ERR_ILLEGAL_CHAR; + break; + + case EILSEQ: + retval = PHP_ICONV_ERR_ILLEGAL_SEQ; + break; + + case E2BIG: + /* should not happen */ + retval = PHP_ICONV_ERR_TOO_BIG; + break; + + default: + /* other error */ + retval = PHP_ICONV_ERR_UNKNOWN; + efree(out_buf); + return PHP_ICONV_ERR_UNKNOWN; + } + } + *out_p = '\0'; + *out = out_buf; + *out_len = out_size; + return retval; +#endif +} +/* }}} */ + +/* {{{ _php_iconv_strlen() */ +static php_iconv_err_t _php_iconv_strlen(unsigned int *pretval, const char *str, size_t nbytes, const char *enc) +{ + char buf[GENERIC_SUPERSET_NBYTES*2]; + + php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; + + iconv_t cd; + + const char *in_p; + size_t in_left; + + char *out_p; + size_t out_left; + + unsigned int cnt; + + *pretval = (unsigned int)-1; + + cd = iconv_open(GENERIC_SUPERSET_NAME, enc); + + if (cd == (iconv_t)(-1)) { +#if ICONV_SUPPORTS_ERRNO + if (errno == EINVAL) { + return PHP_ICONV_ERR_WRONG_CHARSET; + } else { + return PHP_ICONV_ERR_CONVERTER; + } +#else + return PHP_ICONV_ERR_UNKNOWN; +#endif + } + + errno = out_left = 0; + + for (in_p = str, in_left = nbytes, cnt = 0; in_left > 0; cnt+=2) { + size_t prev_in_left; + out_p = buf; + out_left = sizeof(buf); + + prev_in_left = in_left; + + if (iconv(cd, (char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { + if (prev_in_left == in_left) { + break; + } + } + } + + if (out_left > 0) { + cnt -= out_left / GENERIC_SUPERSET_NBYTES; + } + +#if ICONV_SUPPORTS_ERRNO + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + break; + + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + break; + + case E2BIG: + case 0: + *pretval = cnt; + break; + + default: + err = PHP_ICONV_ERR_UNKNOWN; + break; + } +#else + *pretval = cnt; +#endif + + iconv_close(cd); + + return err; +} + +/* }}} */ + +/* {{{ _php_iconv_substr() */ +static php_iconv_err_t _php_iconv_substr(smart_str *pretval, + const char *str, size_t nbytes, int offset, int len, const char *enc) +{ + char buf[GENERIC_SUPERSET_NBYTES]; + + php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; + + iconv_t cd1, cd2; + + const char *in_p; + size_t in_left; + + char *out_p; + size_t out_left; + + unsigned int cnt; + int total_len; + + err = _php_iconv_strlen(&total_len, str, nbytes, enc); + if (err != PHP_ICONV_ERR_SUCCESS) { + return err; + } + + if (len < 0) { + if ((len += (total_len - offset)) < 0) { + return PHP_ICONV_ERR_SUCCESS; + } + } + + if (offset < 0) { + if ((offset += total_len) < 0) { + return PHP_ICONV_ERR_SUCCESS; + } + } + + if(len > total_len) { + len = total_len; + } + + + if (offset >= total_len) { + return PHP_ICONV_ERR_SUCCESS; + } + + if ((offset + len) > total_len ) { + /* trying to compute the length */ + len = total_len - offset; + } + + if (len == 0) { + smart_str_appendl(pretval, "", 0); + smart_str_0(pretval); + return PHP_ICONV_ERR_SUCCESS; + } + + cd1 = iconv_open(GENERIC_SUPERSET_NAME, enc); + + if (cd1 == (iconv_t)(-1)) { +#if ICONV_SUPPORTS_ERRNO + if (errno == EINVAL) { + return PHP_ICONV_ERR_WRONG_CHARSET; + } else { + return PHP_ICONV_ERR_CONVERTER; + } +#else + return PHP_ICONV_ERR_UNKNOWN; +#endif + } + + cd2 = (iconv_t)NULL; + errno = 0; + + for (in_p = str, in_left = nbytes, cnt = 0; in_left > 0 && len > 0; ++cnt) { + size_t prev_in_left; + out_p = buf; + out_left = sizeof(buf); + + prev_in_left = in_left; + + if (iconv(cd1, (char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { + if (prev_in_left == in_left) { + break; + } + } + + if (cnt >= (unsigned int)offset) { + if (cd2 == (iconv_t)NULL) { + cd2 = iconv_open(enc, GENERIC_SUPERSET_NAME); + + if (cd2 == (iconv_t)(-1)) { + cd2 = (iconv_t)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; + } + } + + if (_php_iconv_appendl(pretval, buf, sizeof(buf), cd2) != PHP_ICONV_ERR_SUCCESS) { + break; + } + --len; + } + + } + +#if ICONV_SUPPORTS_ERRNO + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + break; + + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + break; + + case E2BIG: + break; + } +#endif + if (err == PHP_ICONV_ERR_SUCCESS) { + if (cd2 != (iconv_t)NULL) { + _php_iconv_appendl(pretval, NULL, 0, cd2); + } + smart_str_0(pretval); + } + + if (cd1 != (iconv_t)NULL) { + iconv_close(cd1); + } + + if (cd2 != (iconv_t)NULL) { + iconv_close(cd2); + } + return err; +} + +/* }}} */ + +/* {{{ _php_iconv_strpos() */ +static php_iconv_err_t _php_iconv_strpos(unsigned int *pretval, + const char *haystk, size_t haystk_nbytes, + const char *ndl, size_t ndl_nbytes, + int offset, const char *enc) +{ + char buf[GENERIC_SUPERSET_NBYTES]; + + php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; + + iconv_t cd; + + const char *in_p; + size_t in_left; + + char *out_p; + size_t out_left; + + unsigned int cnt; + + char *ndl_buf; + const char *ndl_buf_p; + size_t ndl_buf_len, ndl_buf_left; + + unsigned int match_ofs; + + *pretval = (unsigned int)-1; + + err = php_iconv_string(ndl, ndl_nbytes, + &ndl_buf, &ndl_buf_len, GENERIC_SUPERSET_NAME, enc); + + if (err != PHP_ICONV_ERR_SUCCESS) { + if (ndl_buf != NULL) { + efree(ndl_buf); + } + return err; + } + + cd = iconv_open(GENERIC_SUPERSET_NAME, enc); + + if (cd == (iconv_t)(-1)) { + if (ndl_buf != NULL) { + efree(ndl_buf); + } +#if ICONV_SUPPORTS_ERRNO + if (errno == EINVAL) { + return PHP_ICONV_ERR_WRONG_CHARSET; + } else { + return PHP_ICONV_ERR_CONVERTER; + } +#else + return PHP_ICONV_ERR_UNKNOWN; +#endif + } + + ndl_buf_p = ndl_buf; + ndl_buf_left = ndl_buf_len; + match_ofs = (unsigned int)-1; + + for (in_p = haystk, in_left = haystk_nbytes, cnt = 0; in_left > 0; ++cnt) { + size_t prev_in_left; + out_p = buf; + out_left = sizeof(buf); + + prev_in_left = in_left; + + if (iconv(cd, (char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { + if (prev_in_left == in_left) { +#if ICONV_SUPPORTS_ERRNO + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + break; + + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + break; + + case E2BIG: + break; + + default: + err = PHP_ICONV_ERR_UNKNOWN; + break; + } +#endif + break; + } + } + if (offset >= 0) { + if (cnt >= (unsigned int)offset) { + if (_php_iconv_memequal(buf, ndl_buf_p, sizeof(buf))) { + if (match_ofs == (unsigned int)-1) { + match_ofs = cnt; + } + ndl_buf_p += GENERIC_SUPERSET_NBYTES; + ndl_buf_left -= GENERIC_SUPERSET_NBYTES; + if (ndl_buf_left == 0) { + *pretval = match_ofs; + break; + } + } else { + unsigned int i, j, lim; + + i = 0; + j = GENERIC_SUPERSET_NBYTES; + lim = (unsigned int)(ndl_buf_p - ndl_buf); + + while (j < lim) { + if (_php_iconv_memequal(&ndl_buf[j], &ndl_buf[i], + GENERIC_SUPERSET_NBYTES)) { + i += GENERIC_SUPERSET_NBYTES; + } else { + j -= i; + i = 0; + } + j += GENERIC_SUPERSET_NBYTES; + } + + if (_php_iconv_memequal(buf, &ndl_buf[i], sizeof(buf))) { + match_ofs += (lim - i) / GENERIC_SUPERSET_NBYTES; + i += GENERIC_SUPERSET_NBYTES; + ndl_buf_p = &ndl_buf[i]; + ndl_buf_left = ndl_buf_len - i; + } else { + match_ofs = (unsigned int)-1; + ndl_buf_p = ndl_buf; + ndl_buf_left = ndl_buf_len; + } + } + } + } else { + if (_php_iconv_memequal(buf, ndl_buf_p, sizeof(buf))) { + if (match_ofs == (unsigned int)-1) { + match_ofs = cnt; + } + ndl_buf_p += GENERIC_SUPERSET_NBYTES; + ndl_buf_left -= GENERIC_SUPERSET_NBYTES; + if (ndl_buf_left == 0) { + *pretval = match_ofs; + ndl_buf_p = ndl_buf; + ndl_buf_left = ndl_buf_len; + match_ofs = -1; + } + } else { + unsigned int i, j, lim; + + i = 0; + j = GENERIC_SUPERSET_NBYTES; + lim = (unsigned int)(ndl_buf_p - ndl_buf); + + while (j < lim) { + if (_php_iconv_memequal(&ndl_buf[j], &ndl_buf[i], + GENERIC_SUPERSET_NBYTES)) { + i += GENERIC_SUPERSET_NBYTES; + } else { + j -= i; + i = 0; + } + j += GENERIC_SUPERSET_NBYTES; + } + + if (_php_iconv_memequal(buf, &ndl_buf[i], sizeof(buf))) { + match_ofs += (lim - i) / GENERIC_SUPERSET_NBYTES; + i += GENERIC_SUPERSET_NBYTES; + ndl_buf_p = &ndl_buf[i]; + ndl_buf_left = ndl_buf_len - i; + } else { + match_ofs = (unsigned int)-1; + ndl_buf_p = ndl_buf; + ndl_buf_left = ndl_buf_len; + } + } + } + } + + if (ndl_buf) { + efree(ndl_buf); + } + + iconv_close(cd); + + return err; +} +/* }}} */ + +/* {{{ _php_iconv_mime_encode() */ +static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fname, size_t fname_nbytes, const char *fval, size_t fval_nbytes, unsigned int max_line_len, const char *lfchars, php_iconv_enc_scheme_t enc_scheme, const char *out_charset, const char *enc) +{ + php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; + iconv_t cd = (iconv_t)(-1), cd_pl = (iconv_t)(-1); + unsigned int char_cnt = 0; + size_t out_charset_len; + size_t lfchars_len; + char *buf = NULL; + char *encoded = NULL; + size_t encoded_len; + const char *in_p; + size_t in_left; + char *out_p; + size_t out_left; + static int qp_table[256] = { + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x00 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 */ + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x20 */ + 1, 1, 1, 1, 1, 1, 1 ,1, 1, 1, 1, 1, 1, 3, 1, 3, /* 0x30 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, /* 0x50 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, /* 0x70 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x80 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x90 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xA0 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xB0 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xC0 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xD0 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xE0 */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 /* 0xF0 */ + }; + + out_charset_len = strlen(out_charset); + lfchars_len = strlen(lfchars); + + if ((fname_nbytes + 2) >= max_line_len + || (out_charset_len + 12) >= max_line_len) { + /* field name is too long */ + err = PHP_ICONV_ERR_TOO_BIG; + goto out; + } + + cd_pl = iconv_open(ICONV_ASCII_ENCODING, enc); + if (cd_pl == (iconv_t)(-1)) { +#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 + goto out; + } + + cd = iconv_open(out_charset, enc); + if (cd == (iconv_t)(-1)) { +#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 + goto out; + } + + buf = safe_emalloc(1, max_line_len, 5); + + char_cnt = max_line_len; + + _php_iconv_appendl(pretval, fname, fname_nbytes, cd_pl); + char_cnt -= fname_nbytes; + smart_str_appendl(pretval, ": ", sizeof(": ") - 1); + char_cnt -= 2; + + in_p = fval; + in_left = fval_nbytes; + + do { + size_t prev_in_left; + size_t out_size; + + if (char_cnt < (out_charset_len + 12)) { + /* lfchars must be encoded in ASCII here*/ + smart_str_appendl(pretval, lfchars, lfchars_len); + smart_str_appendc(pretval, ' '); + char_cnt = max_line_len - 1; + } + + smart_str_appendl(pretval, "=?", sizeof("=?") - 1); + char_cnt -= 2; + smart_str_appendl(pretval, out_charset, out_charset_len); + char_cnt -= out_charset_len; + smart_str_appendc(pretval, '?'); + char_cnt --; + + switch (enc_scheme) { + case PHP_ICONV_ENC_SCHEME_BASE64: { + size_t ini_in_left; + const char *ini_in_p; + size_t out_reserved = 4; + int dummy; + + smart_str_appendc(pretval, 'B'); + char_cnt--; + smart_str_appendc(pretval, '?'); + char_cnt--; + + prev_in_left = ini_in_left = in_left; + ini_in_p = in_p; + + out_size = (char_cnt - 2) / 4 * 3; + + for (;;) { + out_p = buf; + + if (out_size <= out_reserved) { + err = PHP_ICONV_ERR_TOO_BIG; + goto out; + } + + out_left = out_size - out_reserved; + + if (iconv(cd, (char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { +#if ICONV_SUPPORTS_ERRNO + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + goto out; + + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + goto out; + + case E2BIG: + if (prev_in_left == in_left) { + err = PHP_ICONV_ERR_TOO_BIG; + goto out; + } + break; + + default: + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } +#else + if (prev_in_left == in_left) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } +#endif + } + + out_left += out_reserved; + + if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)-1) { +#if ICONV_SUPPORTS_ERRNO + if (errno != E2BIG) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } +#else + if (out_left != 0) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } +#endif + } else { + break; + } + + if (iconv(cd, NULL, NULL, NULL, NULL) == (size_t)-1) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } + + out_reserved += 4; + in_left = ini_in_left; + in_p = ini_in_p; + } + + prev_in_left = in_left; + + encoded = (char *) php_base64_encode((unsigned char *) buf, (int)(out_size - out_left), &dummy); + encoded_len = (size_t)dummy; + + if (char_cnt < encoded_len) { + /* something went wrong! */ + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } + + smart_str_appendl(pretval, encoded, encoded_len); + char_cnt -= encoded_len; + smart_str_appendl(pretval, "?=", sizeof("?=") - 1); + char_cnt -= 2; + + efree(encoded); + encoded = NULL; + } break; /* case PHP_ICONV_ENC_SCHEME_BASE64: */ + + case PHP_ICONV_ENC_SCHEME_QPRINT: { + size_t ini_in_left; + const char *ini_in_p; + const unsigned char *p; + size_t nbytes_required; + + smart_str_appendc(pretval, 'Q'); + char_cnt--; + smart_str_appendc(pretval, '?'); + char_cnt--; + + prev_in_left = ini_in_left = in_left; + ini_in_p = in_p; + + for (out_size = (char_cnt - 2) / 3; out_size > 0;) { + size_t prev_out_left; + + nbytes_required = 0; + + out_p = buf; + out_left = out_size; + + if (iconv(cd, (char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { +#if ICONV_SUPPORTS_ERRNO + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + goto out; + + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + goto out; + + case E2BIG: + if (prev_in_left == in_left) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } + break; + + default: + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } +#else + if (prev_in_left == in_left) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } +#endif + } + + prev_out_left = out_left; + if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)-1) { +#if ICONV_SUPPORTS_ERRNO + if (errno != E2BIG) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } +#else + if (out_left == prev_out_left) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } +#endif + } + + for (p = (unsigned char *)buf; p < (unsigned char *)out_p; p++) { + nbytes_required += qp_table[*p]; + } + + if (nbytes_required <= char_cnt - 2) { + break; + } + + out_size -= ((nbytes_required - (char_cnt - 2)) + 1) / 3; + in_left = ini_in_left; + in_p = ini_in_p; + } + + for (p = (unsigned char *)buf; p < (unsigned char *)out_p; p++) { + if (qp_table[*p] == 1) { + smart_str_appendc(pretval, *(char *)p); + char_cnt--; + } else { + static char qp_digits[] = "0123456789ABCDEF"; + smart_str_appendc(pretval, '='); + smart_str_appendc(pretval, qp_digits[(*p >> 4) & 0x0f]); + smart_str_appendc(pretval, qp_digits[(*p & 0x0f)]); + char_cnt -= 3; + } + } + + smart_str_appendl(pretval, "?=", sizeof("?=") - 1); + char_cnt -= 2; + + if (iconv(cd, NULL, NULL, NULL, NULL) == (size_t)-1) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } + + } break; /* case PHP_ICONV_ENC_SCHEME_QPRINT: */ + } + } while (in_left > 0); + + smart_str_0(pretval); + +out: + if (cd != (iconv_t)(-1)) { + iconv_close(cd); + } + if (cd_pl != (iconv_t)(-1)) { + iconv_close(cd_pl); + } + if (encoded != NULL) { + efree(encoded); + } + if (buf != NULL) { + efree(buf); + } + return err; +} +/* }}} */ + +/* {{{ _php_iconv_mime_decode() */ +static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *str, size_t str_nbytes, const char *enc, const char **next_pos, int mode) +{ + php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; + + iconv_t cd = (iconv_t)(-1), cd_pl = (iconv_t)(-1); + + const char *p1; + size_t str_left; + unsigned int scan_stat = 0; + const char *csname = NULL; + size_t csname_len; + const char *encoded_text = NULL; + size_t encoded_text_len = 0; + const char *encoded_word = NULL; + const char *spaces = NULL; + + php_iconv_enc_scheme_t enc_scheme = PHP_ICONV_ENC_SCHEME_BASE64; + + if (next_pos != NULL) { + *next_pos = NULL; + } + + cd_pl = iconv_open(enc, ICONV_ASCII_ENCODING); + + if (cd_pl == (iconv_t)(-1)) { +#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 + goto out; + } + + p1 = str; + for (str_left = str_nbytes; str_left > 0; str_left--, p1++) { + int eos = 0; + + switch (scan_stat) { + case 0: /* expecting any character */ + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; + + case '\n': + scan_stat = 8; + break; + + case '=': /* first letter of an encoded chunk */ + encoded_word = p1; + scan_stat = 1; + break; + + case ' ': case '\t': /* a chunk of whitespaces */ + spaces = p1; + scan_stat = 11; + break; + + default: /* first letter of a non-encoded word */ + _php_iconv_appendc(pretval, *p1, cd_pl); + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } + break; + } + break; + + case 1: /* expecting a delimiter */ + if (*p1 != '?') { + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out; + } + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } + csname = p1 + 1; + scan_stat = 2; + break; + + case 2: /* expecting a charset name */ + switch (*p1) { + case '?': /* normal delimiter: encoding scheme follows */ + scan_stat = 3; + break; + + case '*': /* new style delimiter: locale id follows */ + scan_stat = 10; + break; + } + if (scan_stat != 2) { + char tmpbuf[80]; + + if (csname == NULL) { + err = PHP_ICONV_ERR_MALFORMED; + goto out; + } + + csname_len = (size_t)(p1 - csname); + + if (csname_len > sizeof(tmpbuf) - 1) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out; + } + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out; + } + } + + memcpy(tmpbuf, csname, csname_len); + tmpbuf[csname_len] = '\0'; + + if (cd != (iconv_t)(-1)) { + iconv_close(cd); + } + + cd = iconv_open(enc, tmpbuf); + + if (cd == (iconv_t)(-1)) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* Bad character set, but the user wants us to + * press on. In this case, we'll just insert the + * undecoded encoded word, since there isn't really + * a more sensible behaviour available; the only + * other options are to swallow the encoded word + * entirely or decode it with an arbitrarily chosen + * single byte encoding, both of which seem to have + * a higher WTF factor than leaving it undecoded. + * + * Given this approach, we need to skip ahead to + * the end of the encoded word. */ + int qmarks = 2; + while (qmarks > 0 && str_left > 1) { + if (*(++p1) == '?') { + --qmarks; + } + --str_left; + } + + /* Look ahead to check for the terminating = that + * should be there as well; if it's there, we'll + * also include that. If it's not, there isn't much + * we can do at this point. */ + if (*(p1 + 1) == '=') { + ++p1; + --str_left; + } + + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out; + } + + /* Let's go back and see if there are further + * encoded words or bare content, and hope they + * might actually have a valid character set. */ + scan_stat = 12; + break; + } else { +#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 + goto out; + } + } + } + break; + + case 3: /* expecting a encoding scheme specifier */ + switch (*p1) { + case 'b': + case 'B': + enc_scheme = PHP_ICONV_ENC_SCHEME_BASE64; + scan_stat = 4; + break; + + case 'q': + case 'Q': + enc_scheme = PHP_ICONV_ENC_SCHEME_QPRINT; + scan_stat = 4; + break; + + default: + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out; + } + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out; + } + } + break; + + case 4: /* expecting a delimiter */ + if (*p1 != '?') { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out; + } + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out; + } + } + encoded_text = p1 + 1; + scan_stat = 5; + break; + + case 5: /* expecting an encoded portion */ + if (*p1 == '?') { + encoded_text_len = (size_t)(p1 - encoded_text); + scan_stat = 6; + } + break; + + case 7: /* expecting a "\n" character */ + if (*p1 == '\n') { + scan_stat = 8; + } else { + /* bare CR */ + _php_iconv_appendc(pretval, '\r', cd_pl); + _php_iconv_appendc(pretval, *p1, cd_pl); + scan_stat = 0; + } + break; + + case 8: /* checking whether the following line is part of a + folded header */ + if (*p1 != ' ' && *p1 != '\t') { + --p1; + str_left = 1; /* quit_loop */ + break; + } + if (encoded_word == NULL) { + _php_iconv_appendc(pretval, ' ', cd_pl); + } + spaces = NULL; + scan_stat = 11; + break; + + case 6: /* expecting a End-Of-Chunk character "=" */ + if (*p1 != '=') { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out; + } + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out; + } + } + scan_stat = 9; + if (str_left == 1) { + eos = 1; + } else { + break; + } + + case 9: /* choice point, seeing what to do next.*/ + switch (*p1) { + default: + /* Handle non-RFC-compliant formats + * + * RFC2047 requires the character that comes right + * after an encoded word (chunk) to be a whitespace, + * while there are lots of broken implementations that + * generate such malformed headers that don't fulfill + * that requirement. + */ + if (!eos) { + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out; + } + scan_stat = 12; + break; + } + } + /* break is omitted intentionally */ + + case '\r': case '\n': case ' ': case '\t': { + char *decoded_text; + size_t decoded_text_len; + int dummy; + + switch (enc_scheme) { + case PHP_ICONV_ENC_SCHEME_BASE64: + decoded_text = (char *)php_base64_decode((unsigned char*)encoded_text, (int)encoded_text_len, &dummy); + decoded_text_len = (size_t)dummy; + break; + + case PHP_ICONV_ENC_SCHEME_QPRINT: + decoded_text = (char *)php_quot_print_decode((unsigned char*)encoded_text, (int)encoded_text_len, &decoded_text_len, 1); + break; + default: + decoded_text = NULL; + break; + } + + if (decoded_text == NULL) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out; + } + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } else { + err = PHP_ICONV_ERR_UNKNOWN; + goto out; + } + } + + err = _php_iconv_appendl(pretval, decoded_text, decoded_text_len, cd); + efree(decoded_text); + + if (err != PHP_ICONV_ERR_SUCCESS) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)(p1 - encoded_word), cd_pl); + encoded_word = NULL; + if (err != PHP_ICONV_ERR_SUCCESS) { + break; + } + } else { + goto out; + } + } + + if (eos) { /* reached end-of-string. done. */ + scan_stat = 0; + break; + } + + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; + + case '\n': + scan_stat = 8; + break; + + case '=': /* first letter of an encoded chunk */ + scan_stat = 1; + break; + + case ' ': case '\t': /* medial whitespaces */ + spaces = p1; + scan_stat = 11; + break; + + default: /* first letter of a non-encoded word */ + _php_iconv_appendc(pretval, *p1, cd_pl); + scan_stat = 12; + break; + } + } break; + } + break; + + case 10: /* expects a language specifier. dismiss it for now */ + if (*p1 == '?') { + scan_stat = 3; + } + break; + + case 11: /* expecting a chunk of whitespaces */ + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; + + case '\n': + scan_stat = 8; + break; + + case '=': /* first letter of an encoded chunk */ + if (spaces != NULL && encoded_word == NULL) { + _php_iconv_appendl(pretval, spaces, (size_t)(p1 - spaces), cd_pl); + spaces = NULL; + } + encoded_word = p1; + scan_stat = 1; + break; + + case ' ': case '\t': + break; + + default: /* first letter of a non-encoded word */ + if (spaces != NULL) { + _php_iconv_appendl(pretval, spaces, (size_t)(p1 - spaces), cd_pl); + spaces = NULL; + } + _php_iconv_appendc(pretval, *p1, cd_pl); + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } + break; + + case 12: /* expecting a non-encoded word */ + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; + + case '\n': + scan_stat = 8; + break; + + case ' ': case '\t': + spaces = p1; + scan_stat = 11; + break; + + case '=': /* first letter of an encoded chunk */ + if (!(mode & PHP_ICONV_MIME_DECODE_STRICT)) { + encoded_word = p1; + scan_stat = 1; + break; + } + /* break is omitted intentionally */ + + default: + _php_iconv_appendc(pretval, *p1, cd_pl); + break; + } + break; + } + } + switch (scan_stat) { + case 0: case 8: case 11: case 12: + break; + default: + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + if (scan_stat == 1) { + _php_iconv_appendc(pretval, '=', cd_pl); + } + err = PHP_ICONV_ERR_SUCCESS; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out; + } + } + + if (next_pos != NULL) { + *next_pos = p1; + } + + smart_str_0(pretval); +out: + if (cd != (iconv_t)(-1)) { + iconv_close(cd); + } + if (cd_pl != (iconv_t)(-1)) { + iconv_close(cd_pl); + } + return err; +} +/* }}} */ + +/* {{{ php_iconv_show_error() */ +static void _php_iconv_show_error(php_iconv_err_t err, const char *out_charset, const char *in_charset TSRMLS_DC) +{ + switch (err) { + case PHP_ICONV_ERR_SUCCESS: + break; + + case PHP_ICONV_ERR_CONVERTER: + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot open converter"); + break; + + case PHP_ICONV_ERR_WRONG_CHARSET: + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Wrong charset, conversion from `%s' to `%s' is not allowed", + in_charset, out_charset); + break; + + case PHP_ICONV_ERR_ILLEGAL_CHAR: + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected an incomplete multibyte character in input string"); + break; + + case PHP_ICONV_ERR_ILLEGAL_SEQ: + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected an illegal character in input string"); + break; + + case PHP_ICONV_ERR_TOO_BIG: + /* should not happen */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Buffer length exceeded"); + break; + + case PHP_ICONV_ERR_MALFORMED: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Malformed string"); + break; + + default: + /* other error */ + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown error (%d)", errno); + break; + } +} +/* }}} */ + +/* {{{ proto int iconv_strlen(string str [, string charset]) + Returns the character count of str */ +PHP_FUNCTION(iconv_strlen) +{ + char *charset = ICONVG(internal_encoding); + int charset_len = 0; + char *str; + int str_len; + + php_iconv_err_t err; + + unsigned int retval; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", + &str, &str_len, &charset, &charset_len) == FAILURE) { + RETURN_FALSE; + } + + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + + err = _php_iconv_strlen(&retval, str, str_len, charset); + _php_iconv_show_error(err, GENERIC_SUPERSET_NAME, charset TSRMLS_CC); + if (err == PHP_ICONV_ERR_SUCCESS) { + RETVAL_LONG(retval); + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +/* {{{ proto string iconv_substr(string str, int offset, [int length, string charset]) + Returns specified part of a string */ +PHP_FUNCTION(iconv_substr) +{ + char *charset = ICONVG(internal_encoding); + int charset_len = 0; + char *str; + int str_len; + long offset, length = 0; + + php_iconv_err_t err; + + smart_str retval = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ls", + &str, &str_len, &offset, &length, + &charset, &charset_len) == FAILURE) { + RETURN_FALSE; + } + + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + + if (ZEND_NUM_ARGS() < 3) { + length = str_len; + } + + err = _php_iconv_substr(&retval, str, str_len, offset, length, charset); + _php_iconv_show_error(err, GENERIC_SUPERSET_NAME, charset TSRMLS_CC); + + if (err == PHP_ICONV_ERR_SUCCESS && str != NULL && retval.c != NULL) { + RETURN_STRINGL(retval.c, retval.len, 0); + } + smart_str_free(&retval); + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto int iconv_strpos(string haystack, string needle [, int offset [, string charset]]) + Finds position of first occurrence of needle within part of haystack beginning with offset */ +PHP_FUNCTION(iconv_strpos) +{ + char *charset = ICONVG(internal_encoding); + int charset_len = 0; + char *haystk; + int haystk_len; + char *ndl; + int ndl_len; + long offset = 0; + + php_iconv_err_t err; + + unsigned int retval; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ls", + &haystk, &haystk_len, &ndl, &ndl_len, + &offset, &charset, &charset_len) == FAILURE) { + RETURN_FALSE; + } + + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + + if (offset < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string."); + RETURN_FALSE; + } + + if (ndl_len < 1) { + RETURN_FALSE; + } + + err = _php_iconv_strpos(&retval, haystk, haystk_len, ndl, ndl_len, + offset, charset); + _php_iconv_show_error(err, GENERIC_SUPERSET_NAME, charset TSRMLS_CC); + + if (err == PHP_ICONV_ERR_SUCCESS && retval != (unsigned int)-1) { + RETVAL_LONG((long)retval); + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +/* {{{ proto int iconv_strrpos(string haystack, string needle [, string charset]) + Finds position of last occurrence of needle within part of haystack beginning with offset */ +PHP_FUNCTION(iconv_strrpos) +{ + char *charset = ICONVG(internal_encoding); + int charset_len = 0; + char *haystk; + int haystk_len; + char *ndl; + int ndl_len; + + php_iconv_err_t err; + + unsigned int retval; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", + &haystk, &haystk_len, &ndl, &ndl_len, + &charset, &charset_len) == FAILURE) { + RETURN_FALSE; + } + + if (ndl_len < 1) { + RETURN_FALSE; + } + + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + + err = _php_iconv_strpos(&retval, haystk, haystk_len, ndl, ndl_len, + -1, charset); + _php_iconv_show_error(err, GENERIC_SUPERSET_NAME, charset TSRMLS_CC); + + if (err == PHP_ICONV_ERR_SUCCESS && retval != (unsigned int)-1) { + RETVAL_LONG((long)retval); + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +/* {{{ proto string iconv_mime_encode(string field_name, string field_value [, array preference]) + Composes a mime header field with field_name and field_value in a specified scheme */ +PHP_FUNCTION(iconv_mime_encode) +{ + const char *field_name = NULL; + int field_name_len; + const char *field_value = NULL; + int field_value_len; + zval *pref = NULL; + zval tmp_zv, *tmp_zv_p = NULL; + smart_str retval = {0}; + php_iconv_err_t err; + + const char *in_charset = ICONVG(internal_encoding); + const char *out_charset = in_charset; + long line_len = 76; + const char *lfchars = "\r\n"; + php_iconv_enc_scheme_t scheme_id = PHP_ICONV_ENC_SCHEME_BASE64; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a", + &field_name, &field_name_len, &field_value, &field_value_len, + &pref) == FAILURE) { + + RETURN_FALSE; + } + + if (pref != NULL) { + zval **ppval; + + if (zend_hash_find(Z_ARRVAL_P(pref), "scheme", sizeof("scheme"), (void **)&ppval) == SUCCESS) { + if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { + switch (Z_STRVAL_PP(ppval)[0]) { + case 'B': case 'b': + scheme_id = PHP_ICONV_ENC_SCHEME_BASE64; + break; + + case 'Q': case 'q': + scheme_id = PHP_ICONV_ENC_SCHEME_QPRINT; + break; + } + } + } + + if (zend_hash_find(Z_ARRVAL_P(pref), "input-charset", sizeof("input-charset"), (void **)&ppval) == SUCCESS) { + if (Z_STRLEN_PP(ppval) >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + + if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { + in_charset = Z_STRVAL_PP(ppval); + } + } + + + if (zend_hash_find(Z_ARRVAL_P(pref), "output-charset", sizeof("output-charset"), (void **)&ppval) == SUCCESS) { + if (Z_STRLEN_PP(ppval) >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + + if (Z_TYPE_PP(ppval) == IS_STRING && Z_STRLEN_PP(ppval) > 0) { + out_charset = Z_STRVAL_PP(ppval); + } + } + + if (zend_hash_find(Z_ARRVAL_P(pref), "line-length", sizeof("line-length"), (void **)&ppval) == SUCCESS) { + zval val, *pval = *ppval; + + if (Z_TYPE_P(pval) != IS_LONG) { + val = *pval; + zval_copy_ctor(&val); + convert_to_long(&val); + pval = &val; + } + + line_len = Z_LVAL_P(pval); + + if (pval == &val) { + zval_dtor(&val); + } + } + + if (zend_hash_find(Z_ARRVAL_P(pref), "line-break-chars", sizeof("line-break-chars"), (void **)&ppval) == SUCCESS) { + if (Z_TYPE_PP(ppval) != IS_STRING) { + tmp_zv = **ppval; + zval_copy_ctor(&tmp_zv); + convert_to_string(&tmp_zv); + + lfchars = Z_STRVAL(tmp_zv); + + tmp_zv_p = &tmp_zv; + } else { + lfchars = Z_STRVAL_PP(ppval); + } + } + } + + err = _php_iconv_mime_encode(&retval, field_name, field_name_len, + field_value, field_value_len, line_len, lfchars, scheme_id, + out_charset, in_charset); + _php_iconv_show_error(err, out_charset, in_charset TSRMLS_CC); + + if (err == PHP_ICONV_ERR_SUCCESS) { + if (retval.c != NULL) { + RETVAL_STRINGL(retval.c, retval.len, 0); + } else { + RETVAL_EMPTY_STRING(); + } + } else { + smart_str_free(&retval); + RETVAL_FALSE; + } + + if (tmp_zv_p != NULL) { + zval_dtor(tmp_zv_p); + } +} +/* }}} */ + +/* {{{ proto string iconv_mime_decode(string encoded_string [, int mode, string charset]) + Decodes a mime header field */ +PHP_FUNCTION(iconv_mime_decode) +{ + char *encoded_str; + int encoded_str_len; + char *charset = ICONVG(internal_encoding); + int charset_len = 0; + long mode = 0; + + smart_str retval = {0}; + + php_iconv_err_t err; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls", + &encoded_str, &encoded_str_len, &mode, &charset, &charset_len) == FAILURE) { + + RETURN_FALSE; + } + + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + + err = _php_iconv_mime_decode(&retval, encoded_str, encoded_str_len, charset, NULL, mode); + _php_iconv_show_error(err, charset, "???" TSRMLS_CC); + + if (err == PHP_ICONV_ERR_SUCCESS) { + if (retval.c != NULL) { + RETVAL_STRINGL(retval.c, retval.len, 0); + } else { + RETVAL_EMPTY_STRING(); + } + } else { + smart_str_free(&retval); + RETVAL_FALSE; + } +} +/* }}} */ + +/* {{{ proto array iconv_mime_decode_headers(string headers [, int mode, string charset]) + Decodes multiple mime header fields */ +PHP_FUNCTION(iconv_mime_decode_headers) +{ + const char *encoded_str; + int encoded_str_len; + char *charset = ICONVG(internal_encoding); + int charset_len = 0; + long mode = 0; + + php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls", + &encoded_str, &encoded_str_len, &mode, &charset, &charset_len) == FAILURE) { + + RETURN_FALSE; + } + + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + + array_init(return_value); + + while (encoded_str_len > 0) { + smart_str decoded_header = {0}; + char *header_name = NULL; + size_t header_name_len = 0; + char *header_value = NULL; + size_t header_value_len = 0; + char *p, *limit; + const char *next_pos; + + if (PHP_ICONV_ERR_SUCCESS != (err = _php_iconv_mime_decode(&decoded_header, encoded_str, encoded_str_len, charset, &next_pos, mode))) { + smart_str_free(&decoded_header); + break; + } + + if (decoded_header.c == NULL) { + break; + } + + limit = decoded_header.c + decoded_header.len; + for (p = decoded_header.c; p < limit; p++) { + if (*p == ':') { + *p = '\0'; + header_name = decoded_header.c; + header_name_len = (p - decoded_header.c) + 1; + + while (++p < limit) { + if (*p != ' ' && *p != '\t') { + break; + } + } + + header_value = p; + header_value_len = limit - p; + + break; + } + } + + if (header_name != NULL) { + zval **elem, *new_elem; + + if (zend_hash_find(Z_ARRVAL_P(return_value), header_name, header_name_len, (void **)&elem) == SUCCESS) { + if (Z_TYPE_PP(elem) != IS_ARRAY) { + MAKE_STD_ZVAL(new_elem); + array_init(new_elem); + + Z_ADDREF_PP(elem); + add_next_index_zval(new_elem, *elem); + + zend_hash_update(Z_ARRVAL_P(return_value), header_name, header_name_len, (void *)&new_elem, sizeof(new_elem), NULL); + + elem = &new_elem; + } + add_next_index_stringl(*elem, header_value, header_value_len, 1); + } else { + add_assoc_stringl_ex(return_value, header_name, header_name_len, header_value, header_value_len, 1); + } + } + encoded_str_len -= next_pos - encoded_str; + encoded_str = next_pos; + + smart_str_free(&decoded_header); + } + + if (err != PHP_ICONV_ERR_SUCCESS) { + _php_iconv_show_error(err, charset, "???" TSRMLS_CC); + zval_dtor(return_value); + RETVAL_FALSE; + } +} +/* }}} */ + +/* {{{ proto string iconv(string in_charset, string out_charset, string str) + Returns str converted to the out_charset character set */ +PHP_NAMED_FUNCTION(php_if_iconv) +{ + char *in_charset, *out_charset, *in_buffer, *out_buffer; + size_t out_len; + int in_charset_len = 0, out_charset_len = 0, in_buffer_len; + php_iconv_err_t err; + + 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 (in_charset_len >= ICONV_CSNMAXLEN || out_charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + + err = php_iconv_string(in_buffer, (size_t)in_buffer_len, + &out_buffer, &out_len, out_charset, in_charset); + _php_iconv_show_error(err, out_charset, in_charset TSRMLS_CC); + if (err == PHP_ICONV_ERR_SUCCESS && out_buffer != NULL) { + RETVAL_STRINGL(out_buffer, out_len, 0); + } else { + if (out_buffer != NULL) { + efree(out_buffer); + } + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto bool iconv_set_encoding(string type, string charset) + Sets internal encoding and output encoding for ob_iconv_handler() */ +PHP_FUNCTION(iconv_set_encoding) +{ + char *type, *charset; + int type_len, charset_len =0, retval; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &type, &type_len, &charset, &charset_len) == FAILURE) + return; + + if (charset_len >= ICONV_CSNMAXLEN) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Charset parameter exceeds the maximum allowed length of %d characters", ICONV_CSNMAXLEN); + RETURN_FALSE; + } + + 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; + } + + if (retval == SUCCESS) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto mixed iconv_get_encoding([string type]) + Get internal encoding and output encoding for ob_iconv_handler() */ +PHP_FUNCTION(iconv_get_encoding) +{ + char *type = "all"; + int type_len = sizeof("all")-1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &type, &type_len) == FAILURE) + return; + + if (!strcasecmp("all", type)) { + array_init(return_value); + add_assoc_string(return_value, "input_encoding", ICONVG(input_encoding), 1); + add_assoc_string(return_value, "output_encoding", ICONVG(output_encoding), 1); + add_assoc_string(return_value, "internal_encoding", ICONVG(internal_encoding), 1); + } else if (!strcasecmp("input_encoding", type)) { + RETVAL_STRING(ICONVG(input_encoding), 1); + } else if (!strcasecmp("output_encoding", type)) { + RETVAL_STRING(ICONVG(output_encoding), 1); + } else if (!strcasecmp("internal_encoding", type)) { + RETVAL_STRING(ICONVG(internal_encoding), 1); + } else { + RETURN_FALSE; + } + +} +/* }}} */ + +/* {{{ iconv stream filter */ +typedef struct _php_iconv_stream_filter { + iconv_t cd; + int persistent; + char *to_charset; + size_t to_charset_len; + char *from_charset; + size_t from_charset_len; + char stub[128]; + size_t stub_len; +} php_iconv_stream_filter; +/* }}} iconv stream filter */ + +/* {{{ php_iconv_stream_filter_dtor */ +static void php_iconv_stream_filter_dtor(php_iconv_stream_filter *self) +{ + iconv_close(self->cd); + pefree(self->to_charset, self->persistent); + pefree(self->from_charset, self->persistent); +} +/* }}} */ + +/* {{{ php_iconv_stream_filter_ctor() */ +static php_iconv_err_t php_iconv_stream_filter_ctor(php_iconv_stream_filter *self, + const char *to_charset, size_t to_charset_len, + const char *from_charset, size_t from_charset_len, int persistent) +{ + if (NULL == (self->to_charset = pemalloc(to_charset_len + 1, persistent))) { + return PHP_ICONV_ERR_ALLOC; + } + self->to_charset_len = to_charset_len; + if (NULL == (self->from_charset = pemalloc(from_charset_len + 1, persistent))) { + pefree(self->to_charset, persistent); + return PHP_ICONV_ERR_ALLOC; + } + self->from_charset_len = from_charset_len; + + memcpy(self->to_charset, to_charset, to_charset_len); + self->to_charset[to_charset_len] = '\0'; + memcpy(self->from_charset, from_charset, from_charset_len); + self->from_charset[from_charset_len] = '\0'; + + if ((iconv_t)-1 == (self->cd = iconv_open(self->to_charset, self->from_charset))) { + pefree(self->from_charset, persistent); + pefree(self->to_charset, persistent); + return PHP_ICONV_ERR_UNKNOWN; + } + self->persistent = persistent; + self->stub_len = 0; + return PHP_ICONV_ERR_SUCCESS; +} +/* }}} */ + +/* {{{ php_iconv_stream_filter_append_bucket */ +static int php_iconv_stream_filter_append_bucket( + php_iconv_stream_filter *self, + php_stream *stream, php_stream_filter *filter, + php_stream_bucket_brigade *buckets_out, + const char *ps, size_t buf_len, size_t *consumed, + int persistent TSRMLS_DC) +{ + php_stream_bucket *new_bucket; + char *out_buf = NULL; + size_t out_buf_size; + char *pd, *pt; + size_t ocnt, prev_ocnt, icnt, tcnt; + size_t initial_out_buf_size; + + if (ps == NULL) { + initial_out_buf_size = 64; + icnt = 1; + } else { + initial_out_buf_size = buf_len; + icnt = buf_len; + } + + out_buf_size = ocnt = prev_ocnt = initial_out_buf_size; + if (NULL == (out_buf = pemalloc(out_buf_size, persistent))) { + return FAILURE; + } + + pd = out_buf; + + if (self->stub_len > 0) { + pt = self->stub; + tcnt = self->stub_len; + + while (tcnt > 0) { + if (iconv(self->cd, &pt, &tcnt, &pd, &ocnt) == (size_t)-1) { +#if ICONV_SUPPORTS_ERRNO + switch (errno) { + case EILSEQ: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "iconv stream filter (\"%s\"=>\"%s\"): invalid multibyte sequence", self->from_charset, self->to_charset); + goto out_failure; + + case EINVAL: + if (ps != NULL) { + if (icnt > 0) { + if (self->stub_len >= sizeof(self->stub)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "iconv stream filter (\"%s\"=>\"%s\"): insufficient buffer", self->from_charset, self->to_charset); + goto out_failure; + } + self->stub[self->stub_len++] = *(ps++); + icnt--; + pt = self->stub; + tcnt = self->stub_len; + } else { + tcnt = 0; + break; + } + } + break; + + case E2BIG: { + char *new_out_buf; + size_t new_out_buf_size; + + new_out_buf_size = out_buf_size << 1; + + if (new_out_buf_size < out_buf_size) { + /* whoa! no bigger buckets are sold anywhere... */ + if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent TSRMLS_CC))) { + goto out_failure; + } + + php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); + + out_buf_size = ocnt = initial_out_buf_size; + if (NULL == (out_buf = pemalloc(out_buf_size, persistent))) { + return FAILURE; + } + pd = out_buf; + } else { + if (NULL == (new_out_buf = perealloc(out_buf, new_out_buf_size, persistent))) { + if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent TSRMLS_CC))) { + goto out_failure; + } + + php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); + return FAILURE; + } + pd = new_out_buf + (pd - out_buf); + ocnt += (new_out_buf_size - out_buf_size); + out_buf = new_out_buf; + out_buf_size = new_out_buf_size; + } + } break; + + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "iconv stream filter (\"%s\"=>\"%s\"): unknown error", self->from_charset, self->to_charset); + goto out_failure; + } +#else + if (ocnt == prev_ocnt) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "iconv stream filter (\"%s\"=>\"%s\"): unknown error", self->from_charset, self->to_charset); + goto out_failure; + } +#endif + } + prev_ocnt = ocnt; + } + memmove(self->stub, pt, tcnt); + self->stub_len = tcnt; + } + + while (icnt > 0) { + if ((ps == NULL ? iconv(self->cd, NULL, NULL, &pd, &ocnt): + iconv(self->cd, (char **)&ps, &icnt, &pd, &ocnt)) == (size_t)-1) { +#if ICONV_SUPPORTS_ERRNO + switch (errno) { + case EILSEQ: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "iconv stream filter (\"%s\"=>\"%s\"): invalid multibyte sequence", self->from_charset, self->to_charset); + goto out_failure; + + case EINVAL: + if (ps != NULL) { + if (icnt > sizeof(self->stub)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "iconv stream filter (\"%s\"=>\"%s\"): insufficient buffer", self->from_charset, self->to_charset); + goto out_failure; + } + memcpy(self->stub, ps, icnt); + self->stub_len = icnt; + ps += icnt; + icnt = 0; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "iconv stream filter (\"%s\"=>\"%s\"): unexpected octet values", self->from_charset, self->to_charset); + goto out_failure; + } + break; + + case E2BIG: { + char *new_out_buf; + size_t new_out_buf_size; + + new_out_buf_size = out_buf_size << 1; + + if (new_out_buf_size < out_buf_size) { + /* whoa! no bigger buckets are sold anywhere... */ + if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent TSRMLS_CC))) { + goto out_failure; + } + + php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); + + out_buf_size = ocnt = initial_out_buf_size; + if (NULL == (out_buf = pemalloc(out_buf_size, persistent))) { + return FAILURE; + } + pd = out_buf; + } else { + if (NULL == (new_out_buf = perealloc(out_buf, new_out_buf_size, persistent))) { + if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent TSRMLS_CC))) { + goto out_failure; + } + + php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); + return FAILURE; + } + pd = new_out_buf + (pd - out_buf); + ocnt += (new_out_buf_size - out_buf_size); + out_buf = new_out_buf; + out_buf_size = new_out_buf_size; + } + } break; + + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "iconv stream filter (\"%s\"=>\"%s\"): unknown error", self->from_charset, self->to_charset); + goto out_failure; + } +#else + if (ocnt == prev_ocnt) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "iconv stream filter (\"%s\"=>\"%s\"): unknown error", self->from_charset, self->to_charset); + goto out_failure; + } +#endif + } else { + if (ps == NULL) { + break; + } + } + prev_ocnt = ocnt; + } + + if (out_buf_size - ocnt > 0) { + if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent TSRMLS_CC))) { + goto out_failure; + } + php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC); + } else { + pefree(out_buf, persistent); + } + *consumed += buf_len - icnt; + + return SUCCESS; + +out_failure: + pefree(out_buf, persistent); + return FAILURE; +} +/* }}} php_iconv_stream_filter_append_bucket */ + +/* {{{ php_iconv_stream_filter_do_filter */ +static php_stream_filter_status_t php_iconv_stream_filter_do_filter( + php_stream *stream, php_stream_filter *filter, + php_stream_bucket_brigade *buckets_in, + php_stream_bucket_brigade *buckets_out, + size_t *bytes_consumed, int flags TSRMLS_DC) +{ + php_stream_bucket *bucket = NULL; + size_t consumed = 0; + php_iconv_stream_filter *self = (php_iconv_stream_filter *)filter->abstract; + + while (buckets_in->head != NULL) { + bucket = buckets_in->head; + + php_stream_bucket_unlink(bucket TSRMLS_CC); + + if (php_iconv_stream_filter_append_bucket(self, stream, filter, + buckets_out, bucket->buf, bucket->buflen, &consumed, + php_stream_is_persistent(stream) TSRMLS_CC) != SUCCESS) { + goto out_failure; + } + + php_stream_bucket_delref(bucket TSRMLS_CC); + } + + if (flags != PSFS_FLAG_NORMAL) { + if (php_iconv_stream_filter_append_bucket(self, stream, filter, + buckets_out, NULL, 0, &consumed, + php_stream_is_persistent(stream) TSRMLS_CC) != SUCCESS) { + goto out_failure; + } + } + + if (bytes_consumed != NULL) { + *bytes_consumed = consumed; + } + + return PSFS_PASS_ON; + +out_failure: + if (bucket != NULL) { + php_stream_bucket_delref(bucket TSRMLS_CC); + } + return PSFS_ERR_FATAL; +} +/* }}} */ + +/* {{{ php_iconv_stream_filter_cleanup */ +static void php_iconv_stream_filter_cleanup(php_stream_filter *filter TSRMLS_DC) +{ + php_iconv_stream_filter_dtor((php_iconv_stream_filter *)filter->abstract); + pefree(filter->abstract, ((php_iconv_stream_filter *)filter->abstract)->persistent); +} +/* }}} */ + +static php_stream_filter_ops php_iconv_stream_filter_ops = { + php_iconv_stream_filter_do_filter, + php_iconv_stream_filter_cleanup, + "convert.iconv.*" +}; + +/* {{{ php_iconv_stream_filter_create */ +static php_stream_filter *php_iconv_stream_filter_factory_create(const char *name, zval *params, int persistent TSRMLS_DC) +{ + php_stream_filter *retval = NULL; + php_iconv_stream_filter *inst; + char *from_charset = NULL, *to_charset = NULL; + size_t from_charset_len, to_charset_len; + + if ((from_charset = strchr(name, '.')) == NULL) { + return NULL; + } + ++from_charset; + if ((from_charset = strchr(from_charset, '.')) == NULL) { + return NULL; + } + ++from_charset; + if ((to_charset = strpbrk(from_charset, "/.")) == NULL) { + return NULL; + } + from_charset_len = to_charset - from_charset; + ++to_charset; + to_charset_len = strlen(to_charset); + + if (from_charset_len >= ICONV_CSNMAXLEN || to_charset_len >= ICONV_CSNMAXLEN) { + return NULL; + } + + if (NULL == (inst = pemalloc(sizeof(php_iconv_stream_filter), persistent))) { + return NULL; + } + + if (php_iconv_stream_filter_ctor(inst, to_charset, to_charset_len, from_charset, from_charset_len, persistent) != PHP_ICONV_ERR_SUCCESS) { + pefree(inst, persistent); + return NULL; + } + + if (NULL == (retval = php_stream_filter_alloc(&php_iconv_stream_filter_ops, inst, persistent))) { + php_iconv_stream_filter_dtor(inst); + pefree(inst, persistent); + } + + return retval; +} +/* }}} */ + +/* {{{ php_iconv_stream_register_factory */ +static php_iconv_err_t php_iconv_stream_filter_register_factory(TSRMLS_D) +{ + static php_stream_filter_factory filter_factory = { + php_iconv_stream_filter_factory_create + }; + + if (FAILURE == php_stream_filter_register_factory( + php_iconv_stream_filter_ops.label, + &filter_factory TSRMLS_CC)) { + return PHP_ICONV_ERR_UNKNOWN; + } + return PHP_ICONV_ERR_SUCCESS; +} +/* }}} */ + +/* {{{ php_iconv_stream_unregister_factory */ +static php_iconv_err_t php_iconv_stream_filter_unregister_factory(TSRMLS_D) +{ + if (FAILURE == php_stream_filter_unregister_factory( + php_iconv_stream_filter_ops.label TSRMLS_CC)) { + return PHP_ICONV_ERR_UNKNOWN; + } + return PHP_ICONV_ERR_SUCCESS; +} +/* }}} */ +/* }}} */ +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/ext/iconv/iconv.dsp b/ext/iconv/iconv.dsp new file mode 100644 index 0000000..2d66cf0 --- /dev/null +++ b/ext/iconv/iconv.dsp @@ -0,0 +1,107 @@ +# Microsoft Developer Studio Project File - Name="iconv" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=iconv - Win32 Debug_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "iconv.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "iconv.mak" CFG="iconv - Win32 Debug_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "iconv - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "iconv - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "iconv - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ICONV_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /I "..\..\win32" /I "..\..\..\php_build\iconv\include" /D "WIN32" /D "PHP_EXPORTS" /D "COMPILE_DL_ICONV" /D "HAVE_ICONV" /D ZEND_DEBUG=0 /D "NDEBUG" /D "_WINDOWS" /D "ZEND_WIN32" /D "PHP_WIN32" /D ZTS=1 /D "ICONV_SUPPORTS_ERRNO" /D "HAVE_LIBICONV" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 php5ts.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_iconv.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
+
+!ELSEIF "$(CFG)" == "iconv - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ICONV_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /I "..\..\win32" /I "..\..\..\php_build\iconv\include" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PHP_EXPORTS" /D "COMPILE_DL_ICONV" /D "ZEND_WIN32" /D "PHP_WIN32" /D "HAVE_ICONV" /D ZTS=1 /D "HAVE_LIBICONV" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "_DEBUG"
+# ADD RSC /l 0x407 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 php5ts_debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_iconv.dll" /pdbtype:sept /libpath:"..\..\Debug_TS"
+
+!ENDIF
+
+# Begin Target
+
+# Name "iconv - Win32 Release_TS"
+# Name "iconv - Win32 Debug_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\iconv.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\php_iconv.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/ext/iconv/php_iconv.def b/ext/iconv/php_iconv.def new file mode 100644 index 0000000..2f77aa4 --- /dev/null +++ b/ext/iconv/php_iconv.def @@ -0,0 +1,6 @@ +EXPORTS +_libiconv_version +libiconv_close +libiconv +libiconv_open +libiconv_set_relocation_prefix diff --git a/ext/iconv/php_iconv.h b/ext/iconv/php_iconv.h new file mode 100644 index 0000000..4753c78 --- /dev/null +++ b/ext/iconv/php_iconv.h @@ -0,0 +1,130 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Rui Hirokawa <rui_hirokawa@ybb.ne.jp> | + | Stig Bakken <ssb@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id: 04fa6ef5343d7bcc71d249670b2771f096bda5bf $ */ + +#ifndef PHP_ICONV_H +#define PHP_ICONV_H + +#ifdef PHP_WIN32 +# ifdef PHP_ICONV_EXPORTS +# define PHP_ICONV_API __declspec(dllexport) +# else +# define PHP_ICONV_API __declspec(dllimport) +# endif +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define PHP_ICONV_API __attribute__ ((visibility("default"))) +#else +# define PHP_ICONV_API +#endif + +#ifdef PHP_ATOM_INC +#include "ext/iconv/php_have_iconv.h" +#include "ext/iconv/php_have_libiconv.h" +#include "ext/iconv/php_iconv_aliased_libiconv.h" +#include "ext/iconv/php_have_glibc_iconv.h" +#include "ext/iconv/php_have_bsd_iconv.h" +#include "ext/iconv/php_have_ibm_iconv.h" +#include "ext/iconv/php_iconv_supports_errno.h" +#include "ext/iconv/php_php_iconv_impl.h" +#include "ext/iconv/php_php_iconv_h_path.h" +#endif + +#ifdef HAVE_ICONV +extern zend_module_entry iconv_module_entry; +#define iconv_module_ptr &iconv_module_entry + +PHP_MINIT_FUNCTION(miconv); +PHP_MSHUTDOWN_FUNCTION(miconv); +PHP_MINFO_FUNCTION(miconv); + +PHP_NAMED_FUNCTION(php_if_iconv); +PHP_FUNCTION(ob_iconv_handler); +PHP_FUNCTION(iconv_get_encoding); +PHP_FUNCTION(iconv_set_encoding); +PHP_FUNCTION(iconv_strlen); +PHP_FUNCTION(iconv_substr); +PHP_FUNCTION(iconv_strpos); +PHP_FUNCTION(iconv_strrpos); +PHP_FUNCTION(iconv_mime_encode); +PHP_FUNCTION(iconv_mime_decode); +PHP_FUNCTION(iconv_mime_decode_headers); + +ZEND_BEGIN_MODULE_GLOBALS(iconv) + char *input_encoding; + char *internal_encoding; + char *output_encoding; +ZEND_END_MODULE_GLOBALS(iconv) + +#ifdef ZTS +# define ICONVG(v) TSRMG(iconv_globals_id, zend_iconv_globals *, v) +#else +# define ICONVG(v) (iconv_globals.v) +#endif + +#ifdef HAVE_IBM_ICONV +# define ICONV_INPUT_ENCODING "ISO8859-1" +# define ICONV_OUTPUT_ENCODING "ISO8859-1" +# define ICONV_INTERNAL_ENCODING "ISO8859-1" +# define ICONV_ASCII_ENCODING "IBM-850" +# define ICONV_UCS4_ENCODING "UCS-4" +#else +# define ICONV_INPUT_ENCODING "ISO-8859-1" +# define ICONV_OUTPUT_ENCODING "ISO-8859-1" +# define ICONV_INTERNAL_ENCODING "ISO-8859-1" +# define ICONV_ASCII_ENCODING "ASCII" +# define ICONV_UCS4_ENCODING "UCS-4LE" +#endif + +#ifndef ICONV_CSNMAXLEN +#define ICONV_CSNMAXLEN 64 +#endif + +/* {{{ typedef enum php_iconv_err_t */ +typedef enum _php_iconv_err_t { + PHP_ICONV_ERR_SUCCESS = SUCCESS, + PHP_ICONV_ERR_CONVERTER = 1, + PHP_ICONV_ERR_WRONG_CHARSET = 2, + PHP_ICONV_ERR_TOO_BIG = 3, + PHP_ICONV_ERR_ILLEGAL_SEQ = 4, + PHP_ICONV_ERR_ILLEGAL_CHAR = 5, + PHP_ICONV_ERR_UNKNOWN = 6, + PHP_ICONV_ERR_MALFORMED = 7, + PHP_ICONV_ERR_ALLOC = 8 +} php_iconv_err_t; +/* }}} */ + +PHP_ICONV_API php_iconv_err_t php_iconv_string(const char * in_p, size_t in_len, char **out, size_t *out_len, const char *out_charset, const char *in_charset); + +#else + +#define iconv_module_ptr NULL + +#endif /* HAVE_ICONV */ + +#define phpext_iconv_ptr iconv_module_ptr + +#endif /* PHP_ICONV_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/iconv/tests/Quotes.UTF-8 b/ext/iconv/tests/Quotes.UTF-8 new file mode 100644 index 0000000..3d48ee9 --- /dev/null +++ b/ext/iconv/tests/Quotes.UTF-8 @@ -0,0 +1,4 @@ +Hello +Hello +Hello +Hello diff --git a/ext/iconv/tests/bug37176.phpt b/ext/iconv/tests/bug37176.phpt new file mode 100644 index 0000000..70242fe --- /dev/null +++ b/ext/iconv/tests/bug37176.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #37176 (iconv_strpos() fails to find a string) +--SKIPIF-- +<?php +include('skipif.inc'); + +$test = @iconv_strpos("abbttt","ttt",0,"UTF-8"); +if ($test === false) { + die("skip UTF-8 is not supported?"); +} + +?> +--FILE-- +<?php +var_dump(iconv_strpos('11--','1-',0,'UTF-8')); +var_dump(iconv_strpos('-11--','1-',0,'UTF-8')); +?> +--EXPECT-- +int(1) +int(2) diff --git a/ext/iconv/tests/bug37773.phpt b/ext/iconv/tests/bug37773.phpt new file mode 100644 index 0000000..d21e6fd --- /dev/null +++ b/ext/iconv/tests/bug37773.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #37773 (iconv_substr() gives "Unknown error" when string length = 1") +--SKIPIF-- +<?php +include('skipif.inc'); + +$test = @iconv_strpos("abbttt","ttt",0,"UTF-8"); +if ($test === false) { + die("skip UTF-8 is not supported?"); +} + +?> +--FILE-- +<?php + var_dump(iconv_substr('x', 0, 1, 'UTF-8')); +?> +--EXPECT-- +string(1) "x" diff --git a/ext/iconv/tests/bug48289.phpt b/ext/iconv/tests/bug48289.phpt new file mode 100644 index 0000000..fc2cd36 --- /dev/null +++ b/ext/iconv/tests/bug48289.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #48289 (iconv_mime_encode() quoted-printable scheme is broken) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$text = "\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88"; +$options = array( + 'scheme' => 'Q', + 'input-charset' => 'UTF-8', + 'output-charset' => 'UTF-8', + 'line-length' => 30, +); + +echo iconv_mime_encode('Subject', $text, $options); +--EXPECT-- +Subject: =?UTF-8?Q?=E3=83=86?= + =?UTF-8?Q?=E3=82=B9?= + =?UTF-8?Q?=E3=83=88?= + =?UTF-8?Q?=E3=83=86?= + =?UTF-8?Q?=E3=82=B9?= + =?UTF-8?Q?=E3=83=88?= diff --git a/ext/iconv/tests/bug51250.phpt b/ext/iconv/tests/bug51250.phpt new file mode 100644 index 0000000..fd2e53b --- /dev/null +++ b/ext/iconv/tests/bug51250.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #51250 (iconv_mime_decode() does not ignore malformed Q-encoded words) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$m = ICONV_MIME_DECODE_CONTINUE_ON_ERROR; + +var_dump(iconv_mime_decode("Legal encoded-word: =?utf-8?B?Kg==?= .", $m)); +var_dump(iconv_mime_decode("Legal encoded-word: =?utf-8?Q?*?= .", $m)); +var_dump(iconv_mime_decode("Illegal encoded-word: =?utf-8?B?".chr(0xA1)."?= .", $m)); +var_dump(iconv_mime_decode("Illegal encoded-word: =?utf-8?Q?".chr(0xA1)."?= .", $m)); + +var_dump(iconv_mime_decode("Legal encoded-word: =?utf-8?B?Kg==?= .")); +var_dump(iconv_mime_decode("Legal encoded-word: =?utf-8?Q?*?= .")); +var_dump(iconv_mime_decode("Illegal encoded-word: =?utf-8?B?".chr(0xA1)."?= .")); +var_dump(iconv_mime_decode("Illegal encoded-word: =?utf-8?Q?".chr(0xA1)."?= .")); +?> +--EXPECTF-- +string(23) "Legal encoded-word: * ." +string(23) "Legal encoded-word: * ." +string(24) "Illegal encoded-word: ." +string(23) "Illegal encoded-word: ." +string(23) "Legal encoded-word: * ." +string(23) "Legal encoded-word: * ." +string(24) "Illegal encoded-word: ." + +Notice: iconv_mime_decode(): Detected an illegal character in input string in %s on line %d +bool(false) diff --git a/ext/iconv/tests/bug52211.phpt b/ext/iconv/tests/bug52211.phpt new file mode 100644 index 0000000..c851cba --- /dev/null +++ b/ext/iconv/tests/bug52211.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #52211 (iconv() returns part of string on error) +--SKIPIF-- +<?php +include('skipif.inc'); +?> +--FILE-- +<?php + +$str = "PATHOLOGIES MDICO-CHIRUR. ADUL. PL"; +$str_iconv = iconv('CP850', 'ISO-8859-1', $str ); +var_dump($str_iconv); + +?> +--EXPECTF-- +Notice: iconv(): Detected an illegal character in input string in %s on line %d +bool(false) diff --git a/ext/iconv/tests/bug52941.phpt b/ext/iconv/tests/bug52941.phpt new file mode 100644 index 0000000..b336d40 --- /dev/null +++ b/ext/iconv/tests/bug52941.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #52941 (The 'iconv_mime_decode_headers' function is skipping headers) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$headers = <<<HEADERS +From: =?UTF-8?B?PGZvb0BleGFtcGxlLmNvbT4=?= +Subject: =?ks_c_5601-1987?B?UkU6odk=?= +X-Foo: =?ks_c_5601-1987?B?UkU6odk=?= Foo +X-Bar: =?ks_c_5601-1987?B?UkU6odk=?= =?UTF-8?Q?Foo?= +To: <test@example.com> +HEADERS; + +$decoded = iconv_mime_decode_headers($headers, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8'); + +var_dump($decoded['From']); +var_dump($decoded['Subject']); +var_dump($decoded['X-Foo']); +var_dump($decoded['X-Bar']); +var_dump($decoded['To']); + +$decoded = iconv_mime_decode_headers($headers, ICONV_MIME_DECODE_CONTINUE_ON_ERROR | ICONV_MIME_DECODE_STRICT, 'UTF-8'); + +var_dump($decoded['From']); +var_dump($decoded['Subject']); +var_dump($decoded['X-Foo']); +var_dump($decoded['X-Bar']); +var_dump($decoded['To']); +?> +--EXPECTF-- +string(17) "<foo@example.com>" +string(%d) "%s" +string(%d) "%sFoo" +string(%d) "%sFoo" +string(18) "<test@example.com>" +string(17) "<foo@example.com>" +string(%d) "%s" +string(%d) "%sFoo" +string(%d) "%sFoo" +string(18) "<test@example.com>" diff --git a/ext/iconv/tests/bug53304.phpt b/ext/iconv/tests/bug53304.phpt new file mode 100644 index 0000000..7eb6c41 --- /dev/null +++ b/ext/iconv/tests/bug53304.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #53304 (quot_print_decode does not handle lower-case hex digits) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +echo iconv_mime_decode('=?utf-8?Q?Nachricht_=c3=bcber_Kontaktformular_www.inexio.net?=', 0, 'UTF-8') . "\n"; +echo iconv_mime_decode('=?utf-8?Q?Nachricht_=C3=BCber_Kontaktformular_www.inexio.net?=', 0, 'UTF-8') . "\n"; + +?> +--EXPECT-- +Nachricht 端ber Kontaktformular www.inexio.net +Nachricht 端ber Kontaktformular www.inexio.net diff --git a/ext/iconv/tests/eucjp2iso2022jp.phpt b/ext/iconv/tests/eucjp2iso2022jp.phpt new file mode 100644 index 0000000..9318c60 --- /dev/null +++ b/ext/iconv/tests/eucjp2iso2022jp.phpt @@ -0,0 +1,27 @@ +--TEST-- +EUC-JP to ISO-2022-JP +--SKIPIF-- +<?php include('skipif.inc'); ?> +--INI-- +error_reporting=2039 +--FILE-- +<?php +/* include('test.inc'); */ +/* charset=EUC-JP */ + +function hexdump($str) { + $len = strlen($str); + for ($i = 0; $i < $len; ++$i) { + printf("%02x", ord($str{$i})); + } + print "\n"; +} + +$str = str_repeat("日本語テキストと English text", 30); +$str .= "日本語"; + +echo hexdump(iconv("EUC-JP", "ISO-2022-JP", $str)); +?> +--EXPECT-- +1b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c2546252d2539254824481b284220456e676c69736820746578741b2442467c4b5c386c1b2842 + diff --git a/ext/iconv/tests/eucjp2sjis.phpt b/ext/iconv/tests/eucjp2sjis.phpt new file mode 100644 index 0000000..a995125 --- /dev/null +++ b/ext/iconv/tests/eucjp2sjis.phpt @@ -0,0 +1,58 @@ +--TEST-- +EUC-JP to SJIS +--SKIPIF-- +<?php include('skipif.inc'); ?> +--INI-- +error_reporting=2039 +--FILE-- +<?php +/* include('test.inc'); */ +/* charset=EUC-JP */ + +$str = " +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +"; + +$str = iconv("EUC-JP", "SJIS", $str); +$str = base64_encode($str); +echo $str."\n"; + +?> +--EXPECT-- +CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0CpP6lnuM6oNlg0yDWINngsZFbmdsaXNoIFRleHQKk/qWe4zqg2WDTINYg2eCxkVuZ2xpc2ggVGV4dAqT+pZ7jOqDZYNMg1iDZ4LGRW5nbGlzaCBUZXh0Cg== + diff --git a/ext/iconv/tests/eucjp2utf8.phpt b/ext/iconv/tests/eucjp2utf8.phpt new file mode 100644 index 0000000..4ffcfef --- /dev/null +++ b/ext/iconv/tests/eucjp2utf8.phpt @@ -0,0 +1,58 @@ +--TEST-- +EUC-JP to UTF8 +--SKIPIF-- +<?php include('skipif.inc'); ?> +--INI-- +error_reporting=2039 +--FILE-- +<?php +/* include('test.inc'); */ +/* charset=EUC-JP */ + +$str = " +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +日本語テキストとEnglish Text +"; + +$str = iconv("EUC-JP", "UTF-8", $str); /* libiconv(1.8) doesn't know "UTF8" but "UTF-8". */ +$str = base64_encode($str); +echo $str."\n"; + +?> +--EXPECT-- +CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0CuaXpeacrOiqnuODhuOCreOCueODiOOBqEVuZ2xpc2ggVGV4dArml6XmnKzoqp7jg4bjgq3jgrnjg4jjgahFbmdsaXNoIFRleHQK5pel5pys6Kqe44OG44Kt44K544OI44GoRW5nbGlzaCBUZXh0Cg== + diff --git a/ext/iconv/tests/iconv-charset-length-cve-2007-4840.phpt b/ext/iconv/tests/iconv-charset-length-cve-2007-4840.phpt new file mode 100644 index 0000000..03b3574 --- /dev/null +++ b/ext/iconv/tests/iconv-charset-length-cve-2007-4840.phpt @@ -0,0 +1,17 @@ +--TEST-- +iconv() charset parameter length checks (CVE-2007-4840) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$a = str_repeat("/", 9000000); +var_dump(iconv($a, "b", "test")); +var_dump(iconv("x", $a, "test")); +?> +--EXPECTF-- + +Warning: iconv(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) + +Warning: iconv(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) diff --git a/ext/iconv/tests/iconv001.phpt b/ext/iconv/tests/iconv001.phpt new file mode 100644 index 0000000..3ef4924 --- /dev/null +++ b/ext/iconv/tests/iconv001.phpt @@ -0,0 +1,18 @@ +--TEST-- +iconv() test 1 +--SKIPIF-- +<?php include('skipif.inc'); ?> +--INI-- +error_reporting=2039 +--FILE-- +<?php +/* include('test.inc'); */ +echo "iconv extension is available\n"; +$test = "胯"; +var_dump("ISO-8859-1: $test"); +var_dump("UTF-8: ".iconv( "ISO-8859-1", "UTF-8", $test ) ); +?> +--EXPECT-- +iconv extension is available +string(15) "ISO-8859-1: 胯" +string(13) "UTF-8: 脱淡奪" diff --git a/ext/iconv/tests/iconv002.phpt b/ext/iconv/tests/iconv002.phpt new file mode 100644 index 0000000..034b376 --- /dev/null +++ b/ext/iconv/tests/iconv002.phpt @@ -0,0 +1,30 @@ +--TEST-- +iconv() test 2 (UCS4BE to ASCII) +--SKIPIF-- +<?php +include('skipif.inc'); +if (@iconv("ascii","UCS-4LE", "abcd") == '') { + die("skip conversion to UCS-4LE not supported"); +} +?> +--INI-- +error_reporting=2039 +--FILE-- +<?php +/* include('test.inc'); */ +/* +Expected output: +abcd +abcd +*/ + + $s = unpack("V*", iconv("ascii","UCS-4LE", "abcd")); + foreach($s as $c) { print "&#$c;"; } print "\n"; + + $s = pack("NNNN", 97, 98, 99, 100); + $q = iconv("UCS-4BE", "ascii", $s); + print $q; print "\n"; +?> +--EXPECT-- +abcd +abcd diff --git a/ext/iconv/tests/iconv003.phpt b/ext/iconv/tests/iconv003.phpt new file mode 100644 index 0000000..9642cf1 --- /dev/null +++ b/ext/iconv/tests/iconv003.phpt @@ -0,0 +1,15 @@ +--TEST-- +iconv() test 3 +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +for ($i = 0; $i < 3; ++$i) { + if (@iconv('blah', 'blah', 'blah') != '') { + die("failed\n"); + } +} +echo "success\n"; +?> +--EXPECT-- +success diff --git a/ext/iconv/tests/iconv004.phpt b/ext/iconv/tests/iconv004.phpt new file mode 100644 index 0000000..6c86065 --- /dev/null +++ b/ext/iconv/tests/iconv004.phpt @@ -0,0 +1,16 @@ +--TEST-- +iconv_mime_encode() sanity cheeck. +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--INI-- +iconv.input_encoding = ISO-8859-1 +iconv.internal_encoding = ISO-8859-1 +iconv.output_encoding = ISO-8859-1 +--FILE-- +<?php +var_dump(iconv_mime_encode('', '')); +var_dump(iconv_mime_encode('', '', array('line-break-chars' => 1))); +?> +--EXPECT-- +string(19) ": =?ISO-8859-1?B??=" +string(19) ": =?ISO-8859-1?B??=" diff --git a/ext/iconv/tests/iconv_basic.phpt b/ext/iconv/tests/iconv_basic.phpt new file mode 100644 index 0000000..e0e2cb2 --- /dev/null +++ b/ext/iconv/tests/iconv_basic.phpt @@ -0,0 +1,72 @@ +--TEST-- +Test iconv() function : basic functionality +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv') or die("skip iconv() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : string iconv(string in_charset, string out_charset, string str) + * Description: Returns converted string in desired encoding + * Source code: ext/iconv/iconv.c + */ + +/* + * Test basic functionality of iconv() + */ + +echo "*** Testing iconv() : basic functionality ***\n"; + +//All strings are the same when displayed in their respective encodings +$sjis_string = base64_decode(b'k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg=='); +$euc_jp_string = base64_decode(b'xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow=='); +$utf8_string = base64_decode(b'5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII='); + +echo "\n-- Convert to EUC-JP --\n"; +echo "Expected EUC-JP encoded string in base64:\n"; +var_dump(bin2hex($euc_jp_string)); +echo "Converted Strings:\n"; +var_dump(bin2hex(iconv('SJIS', 'EUC-JP', $sjis_string ))); +var_dump(bin2hex(iconv('UTF-8', 'EUC-JP', $utf8_string))); + +echo "\n-- Convert to SJIS --\n"; +echo "Expected SJIS encoded string in base64:\n"; +var_dump(bin2hex($sjis_string)); +echo "Converted Strings:\n"; +var_dump(bin2hex(iconv('EUC-JP', 'SJIS', $euc_jp_string))); +var_dump(bin2hex(iconv('UTF-8', 'SJIS', $utf8_string))); + +echo "\n-- Convert to UTF-8 --\n"; +echo "Expected UTF-8 encoded string in base64:\n"; +var_dump(bin2hex($utf8_string)); +echo "Converted Strings:\n"; +var_dump(bin2hex(iconv('SJIS', 'UTF-8', $sjis_string))); +var_dump(bin2hex(iconv('EUC-JP', 'UTF-8', $euc_jp_string))); + +echo "Done"; +?> +--EXPECT-- +*** Testing iconv() : basic functionality *** + +-- Convert to EUC-JP -- +Expected EUC-JP encoded string in base64: +string(74) "c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3" +Converted Strings: +string(74) "c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3" +string(74) "c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3" + +-- Convert to SJIS -- +Expected SJIS encoded string in base64: +string(74) "93fa967b8cea8365834c8358836782c582b781423031323334825482558256825782588142" +Converted Strings: +string(74) "93fa967b8cea8365834c8358836782c582b781423031323334825482558256825782588142" +string(74) "93fa967b8cea8365834c8358836782c582b781423031323334825482558256825782588142" + +-- Convert to UTF-8 -- +Expected UTF-8 encoded string in base64: +string(106) "e697a5e69cace8aa9ee38386e382ade382b9e38388e381a7e38199e380823031323334efbc95efbc96efbc97efbc98efbc99e38082" +Converted Strings: +string(106) "e697a5e69cace8aa9ee38386e382ade382b9e38388e381a7e38199e380823031323334efbc95efbc96efbc97efbc98efbc99e38082" +string(106) "e697a5e69cace8aa9ee38386e382ade382b9e38388e381a7e38199e380823031323334efbc95efbc96efbc97efbc98efbc99e38082" +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_encoding_basic.phpt b/ext/iconv/tests/iconv_encoding_basic.phpt new file mode 100644 index 0000000..7468581 --- /dev/null +++ b/ext/iconv/tests/iconv_encoding_basic.phpt @@ -0,0 +1,98 @@ +--TEST-- +Test iconv_get_encoding()/iconv_set_encoding() function : basic functionality +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_get_encoding') or die("skip iconv_get_encoding() is not available in this build"); +?> +--INI-- +iconv.input_encoding=ISO-8859-1 +iconv.internal_encoding=ISO-8859-1 +iconv.output_encoding=ISO-8859-1 +--FILE-- +<?php +/* Prototype : mixed iconv_get_encoding([string type]) + * Description: Get internal encoding and output encoding for ob_iconv_handler() + * Prototype : bool iconv_set_encoding(string type, string charset) + * Description: Sets internal encoding and output encoding for ob_iconv_handler() + * Source code: ext/iconv/iconv.c + */ + +/* + * Test Basic functionality of iconv_get_encoding/iconv_set_encoding + */ + +echo "*** Testing iconv_get_encoding()/iconv_set_encoding() : basic functionality ***\n"; + +echo "--- Default get_encoding ---\n"; +var_dump(iconv_get_encoding()); +var_dump(iconv_get_encoding("input_encoding")); +var_dump(iconv_get_encoding("output_encoding")); +var_dump(iconv_get_encoding("internal_encoding")); +var_dump(iconv_get_encoding("all")); + +echo "\n--- Altering encodings ---\n"; +var_dump(iconv_set_encoding("input_encoding", "UTF-8")); +var_dump(iconv_set_encoding("output_encoding", "UTF-8")); +var_dump(iconv_set_encoding("internal_encoding", "UTF-8")); + + +echo "\n--- results of alterations ---\n"; +var_dump(iconv_get_encoding()); +var_dump(iconv_get_encoding("input_encoding")); +var_dump(iconv_get_encoding("output_encoding")); +var_dump(iconv_get_encoding("internal_encoding")); +var_dump(iconv_get_encoding("all")); + + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_get_encoding()/iconv_set_encoding() : basic functionality *** +--- Default get_encoding --- +array(3) { + ["input_encoding"]=> + string(10) "ISO-8859-1" + ["output_encoding"]=> + string(10) "ISO-8859-1" + ["internal_encoding"]=> + string(10) "ISO-8859-1" +} +string(10) "ISO-8859-1" +string(10) "ISO-8859-1" +string(10) "ISO-8859-1" +array(3) { + ["input_encoding"]=> + string(10) "ISO-8859-1" + ["output_encoding"]=> + string(10) "ISO-8859-1" + ["internal_encoding"]=> + string(10) "ISO-8859-1" +} + +--- Altering encodings --- +bool(true) +bool(true) +bool(true) + +--- results of alterations --- +array(3) { + ["input_encoding"]=> + string(5) "UTF-8" + ["output_encoding"]=> + string(5) "UTF-8" + ["internal_encoding"]=> + string(5) "UTF-8" +} +string(5) "UTF-8" +string(5) "UTF-8" +string(5) "UTF-8" +array(3) { + ["input_encoding"]=> + string(5) "UTF-8" + ["output_encoding"]=> + string(5) "UTF-8" + ["internal_encoding"]=> + string(5) "UTF-8" +} +Done diff --git a/ext/iconv/tests/iconv_get_encoding_basic.phpt b/ext/iconv/tests/iconv_get_encoding_basic.phpt new file mode 100644 index 0000000..83efd15 --- /dev/null +++ b/ext/iconv/tests/iconv_get_encoding_basic.phpt @@ -0,0 +1,76 @@ +--TEST-- +iconv_get_encoding() parameter tests +--CREDITS-- +Oystein Rose <orose@redpill-linpro.com> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php if (!extension_loaded("iconv")) { echo 'skip extension not available'; } ?> +--FILE-- +<?php + +iconv_set_encoding("internal_encoding", "UTF-8"); +iconv_set_encoding("output_encoding", "UTF-8"); +iconv_set_encoding("input_encoding", "UTF-8"); + +var_dump( iconv_get_encoding('internal_encoding') ); +var_dump( iconv_get_encoding('output_encoding') ); +var_dump( iconv_get_encoding('input_encoding') ); +var_dump( iconv_get_encoding('all') ); +var_dump( iconv_get_encoding('foo') ); +var_dump( iconv_get_encoding() ); + + + +iconv_set_encoding("internal_encoding", "ISO-8859-1"); +iconv_set_encoding("output_encoding", "ISO-8859-1"); +iconv_set_encoding("input_encoding", "ISO-8859-1"); + +var_dump( iconv_get_encoding('internal_encoding') ); +var_dump( iconv_get_encoding('output_encoding') ); +var_dump( iconv_get_encoding('input_encoding') ); +var_dump( iconv_get_encoding('all') ); +var_dump( iconv_get_encoding('foo') ); +var_dump( iconv_get_encoding() ); + +?> +--EXPECT-- +string(5) "UTF-8" +string(5) "UTF-8" +string(5) "UTF-8" +array(3) { + ["input_encoding"]=> + string(5) "UTF-8" + ["output_encoding"]=> + string(5) "UTF-8" + ["internal_encoding"]=> + string(5) "UTF-8" +} +bool(false) +array(3) { + ["input_encoding"]=> + string(5) "UTF-8" + ["output_encoding"]=> + string(5) "UTF-8" + ["internal_encoding"]=> + string(5) "UTF-8" +} +string(10) "ISO-8859-1" +string(10) "ISO-8859-1" +string(10) "ISO-8859-1" +array(3) { + ["input_encoding"]=> + string(10) "ISO-8859-1" + ["output_encoding"]=> + string(10) "ISO-8859-1" + ["internal_encoding"]=> + string(10) "ISO-8859-1" +} +bool(false) +array(3) { + ["input_encoding"]=> + string(10) "ISO-8859-1" + ["output_encoding"]=> + string(10) "ISO-8859-1" + ["internal_encoding"]=> + string(10) "ISO-8859-1" +} diff --git a/ext/iconv/tests/iconv_get_encoding_error.phpt b/ext/iconv/tests/iconv_get_encoding_error.phpt new file mode 100644 index 0000000..b0c3e07 --- /dev/null +++ b/ext/iconv/tests/iconv_get_encoding_error.phpt @@ -0,0 +1,177 @@ +--TEST-- +Test iconv_get_encoding() function : basic functionality +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_get_encoding') or die("skip iconv_get_encoding() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : mixed iconv_get_encoding([string type]) + * Description: Get internal encoding and output encoding for ob_iconv_handler() + * Source code: ext/iconv/iconv.c + */ + +/* + * Test Error functionality of iconv_get_encoding + */ + +echo "*** Testing iconv_get_encoding() : error functionality ***\n"; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "UTF-8"; + } +} + +// heredoc string +$heredoc = <<<EOT +Nothing +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $encoding argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // invalid string data +/*18*/ "Nothing", + 'Nothing', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of mb_regex_encoding() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_get_encoding($input) ); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_get_encoding() : error functionality *** + +-- Iteration 1 -- +bool(false) + +-- Iteration 2 -- +bool(false) + +-- Iteration 3 -- +bool(false) + +-- Iteration 4 -- +bool(false) + +-- Iteration 5 -- +bool(false) + +-- Iteration 6 -- +bool(false) + +-- Iteration 7 -- +bool(false) + +-- Iteration 8 -- +bool(false) + +-- Iteration 9 -- +bool(false) + +-- Iteration 10 -- +bool(false) + +-- Iteration 11 -- +bool(false) + +-- Iteration 12 -- +bool(false) + +-- Iteration 13 -- +bool(false) + +-- Iteration 14 -- +bool(false) + +-- Iteration 15 -- +bool(false) + +-- Iteration 16 -- +bool(false) + +-- Iteration 17 -- +bool(false) + +-- Iteration 18 -- +bool(false) + +-- Iteration 19 -- +bool(false) + +-- Iteration 20 -- +bool(false) + +-- Iteration 21 -- +bool(false) + +-- Iteration 22 -- +bool(false) + +-- Iteration 23 -- +bool(false) + +-- Iteration 24 -- + +Warning: iconv_get_encoding() expects parameter 1 to be string, resource given in %s on line %d +NULL +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_mime_decode-charset-length-cve-2007-4840.phpt b/ext/iconv/tests/iconv_mime_decode-charset-length-cve-2007-4840.phpt new file mode 100644 index 0000000..d4ed01d --- /dev/null +++ b/ext/iconv/tests/iconv_mime_decode-charset-length-cve-2007-4840.phpt @@ -0,0 +1,13 @@ +--TEST-- +iconv_mime_decode() charset parameter length checks (CVE-2007-4840) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$a = str_repeat("/", 9000000); +var_dump(iconv_mime_decode("a", null, $a)); +?> +--EXPECTF-- + +Warning: iconv_mime_decode(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) diff --git a/ext/iconv/tests/iconv_mime_decode.phpt b/ext/iconv/tests/iconv_mime_decode.phpt new file mode 100644 index 0000000..24d1794 --- /dev/null +++ b/ext/iconv/tests/iconv_mime_decode.phpt @@ -0,0 +1,90 @@ +--TEST-- +iconv_mime_decode() +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--INI-- +iconv.internal_charset=iso-8859-1 +--FILE-- +<?php +function my_error_handler($errno, $errmsg, $filename, $linenum, $vars) +{ + echo "$errno: $errmsg\n"; +} +set_error_handler('my_error_handler'); + +function do_single_test($header) +{ + global $mode; + + $result = iconv_mime_decode($header, $mode, "UTF-8"); + printf("(%d) \"%s\"\n", iconv_strlen($result, "UTF-8"), $result); +} + +function do_regression_test() +{ + do_single_test(<<< HERE +Subject: =?ISO-8859-1?Q?Pr=FCfung?= + =?ISO-8859-1*de_DE?Q?Pr=FCfung?=\t + =?ISO-8859-2?Q?k=F9=D4=F1=D3let?= +HERE +); + do_single_test(<<< HERE +Subject: =?ISO-8859-1?Q?Pr=FCfung?= =?ISO-8859-1*de_DE?Q?=20Pr=FCfung?= \t =?ISO-8859-2?Q?k=F9=D4=F1=D3let?= +HERE +); + do_single_test(<<< HERE +Subject: =?ISO-8859-1?Q?Pr=FCfung?==?ISO-8859-1*de_DE?Q?Pr=FCfung?==?ISO-8859-2?Q?k=F9=D4=F1=D3let?= +HERE +); + do_single_test(<<< HERE +Subject: =?ISO-8859-1?Q?Pr=FCfung?= =?ISO-8859-1*de_DE?Q?Pr=FCfung?? =?ISO-8859-2?X?k=F9=D4=F1=D3let?= +HERE +); + do_single_test(<<< HERE +From: =?ISO-2022-JP?B?GyRCJTUbKEI=?= + =?ISO-2022-JP?B?GyRCJXMlVxsoQg==?= + =?ISO-2022-JP?B?GyRCJWtKOBsoQg==?= + =?ISO-2022-JP?B?GyRCO3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVclaxsoQg==?= + =?ISO-2022-JP?B?GyRCSjg7ehsoQg==?= + =?ISO-2022-JP?B?GyRCTnNGfBsoQg==?= + =?ISO-2022-JP?B?GyRCS1w4bBsoQg==?= + =?ISO-2022-JP?B?GyRCJUYlLRsoQg==?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?= +HERE +); +} + +$mode = 0; +do_regression_test(); +$mode = ICONV_MIME_DECODE_STRICT; +do_regression_test(); +$mode = ICONV_MIME_DECODE_CONTINUE_ON_ERROR; +do_regression_test(); +$mode = ICONV_MIME_DECODE_STRICT | ICONV_MIME_DECODE_CONTINUE_ON_ERROR; +do_regression_test(); +--EXPECT-- +(31) "Subject: Pr端fungPr端fungk哲let" +(32) "Subject: Pr端fung Pr端fungk哲let" +(31) "Subject: Pr端fungPr端fungk哲let" +2: iconv_mime_decode(): Malformed string +(0) "" +(27) "From: 泣潟絖泣潟絖ユ茯鴻" +(31) "Subject: Pr端fungPr端fungk哲let" +(32) "Subject: Pr端fung Pr端fungk哲let" +(100) "Subject: =?ISO-8859-1?Q?Pr=FCfung?==?ISO-8859-1*de_DE?Q?Pr=FCfung?==?ISO-8859-2?Q?k=F9=D4=F1=D3let?=" +2: iconv_mime_decode(): Malformed string +(0) "" +(27) "From: 泣潟絖泣潟絖ユ茯鴻" +(31) "Subject: Pr端fungPr端fungk哲let" +(32) "Subject: Pr端fung Pr端fungk哲let" +(31) "Subject: Pr端fungPr端fungk哲let" +(84) "Subject: Pr端fung=?ISO-8859-1*de_DE?Q?Pr=FCfung?? =?ISO-8859-2?X?k=F9=D4=F1=D3let?=" +(27) "From: 泣潟絖泣潟絖ユ茯鴻" +(31) "Subject: Pr端fungPr端fungk哲let" +(32) "Subject: Pr端fung Pr端fungk哲let" +(100) "Subject: =?ISO-8859-1?Q?Pr=FCfung?==?ISO-8859-1*de_DE?Q?Pr=FCfung?==?ISO-8859-2?Q?k=F9=D4=F1=D3let?=" +(84) "Subject: Pr端fung=?ISO-8859-1*de_DE?Q?Pr=FCfung?? =?ISO-8859-2?X?k=F9=D4=F1=D3let?=" +(27) "From: 泣潟絖泣潟絖ユ茯鴻" + diff --git a/ext/iconv/tests/iconv_mime_decode_headers-charset-length-cve-2007-4840.phpt b/ext/iconv/tests/iconv_mime_decode_headers-charset-length-cve-2007-4840.phpt new file mode 100644 index 0000000..48d664d --- /dev/null +++ b/ext/iconv/tests/iconv_mime_decode_headers-charset-length-cve-2007-4840.phpt @@ -0,0 +1,13 @@ +--TEST-- +iconv_mime_decode_headers() charset parameter length checks (CVE-2007-4840) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$a = str_repeat("/", 9000000); +var_dump(iconv_mime_decode_headers("a", null, $a)); +?> +--EXPECTF-- + +Warning: iconv_mime_decode_headers(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) diff --git a/ext/iconv/tests/iconv_mime_decode_headers.phpt b/ext/iconv/tests/iconv_mime_decode_headers.phpt new file mode 100644 index 0000000..71431f7 --- /dev/null +++ b/ext/iconv/tests/iconv_mime_decode_headers.phpt @@ -0,0 +1,89 @@ +--TEST-- +iconv_mime_decode_headers() +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--INI-- +iconv.internal_charset=iso-8859-1 +--FILE-- +<?php +$headers = <<<HERE +Return-Path: <internals-return-5651-***=***.example.com@lists.php.net> +Received: from pb1.pair.com (pb1.pair.com [16.92.131.4]) by ***.example.com + (8.12.10/8.12.10/1970-09-30) with SMTP id hALLmpea023899 for + <***@***.example.com>; Sat, 22 Jan 1970 06:48:51 +0900 (JST) + (envelope-from + internals-return-5651-***=***.example.com@lists.php.net) +Received: (qmail 63472 invoked by uid 1010); 1 Jan 1970 0:00:00 -0000 +Mailing-List: contact internals-help@lists.php.net; run by ezmlm +Precedence: bulk +List-Help: <mailto:internals-help@lists.php.net> +List-Unsubscribe: <mailto:internals-unsubscribe@lists.php.net> +List-Post: <mailto:internals@lists.php.net> +Delivered-To: mailing list internals@lists.php.net +Received: (qmail 63459 invoked by uid 1010); 1 Jan 1970 0:00:00 -0000 +Delivered-To: ezmlm-scan-internals@lists.php.net +Delivered-To: ezmlm-internals@lists.php.net +Date: Thu, 1 Jan 1970 00:00:00 -0000 (GMT) +From: *** *** *** <***@***.example.com> +X-X-Sender: ***@***.example.com +To: internals@lists.php.net +Message-Id: <Pine.LNX.4.58.************@***.example.com> +MIME-Version: 1.0 +Content-Type: TEXT/PLAIN; charset=US-ASCII +Subject: [PHP-DEV] [ICONV] test for =?US-ASCII?Q?iconv_mime_decode_headers=28=29?= +X-UIDL: @eH!!h2:!!EOS!!A_c"! +HERE; +var_dump(iconv_mime_decode_headers($headers)); +?> +--EXPECT-- +array(17) { + ["Return-Path"]=> + string(57) "<internals-return-5651-***=***.example.com@lists.php.net>" + ["Received"]=> + array(3) { + [0]=> + string(259) "from pb1.pair.com (pb1.pair.com [16.92.131.4]) by ***.example.com (8.12.10/8.12.10/1970-09-30) with SMTP id hALLmpea023899 for <***@***.example.com>; Sat, 22 Jan 1970 06:48:51 +0900 (JST) (envelope-from internals-return-5651-***=***.example.com@lists.php.net)" + [1]=> + string(59) "(qmail 63472 invoked by uid 1010); 1 Jan 1970 0:00:00 -0000" + [2]=> + string(59) "(qmail 63459 invoked by uid 1010); 1 Jan 1970 0:00:00 -0000" + } + ["Mailing-List"]=> + string(50) "contact internals-help@lists.php.net; run by ezmlm" + ["Precedence"]=> + string(4) "bulk" + ["List-Help"]=> + string(37) "<mailto:internals-help@lists.php.net>" + ["List-Unsubscribe"]=> + string(44) "<mailto:internals-unsubscribe@lists.php.net>" + ["List-Post"]=> + string(32) "<mailto:internals@lists.php.net>" + ["Delivered-To"]=> + array(3) { + [0]=> + string(36) "mailing list internals@lists.php.net" + [1]=> + string(34) "ezmlm-scan-internals@lists.php.net" + [2]=> + string(29) "ezmlm-internals@lists.php.net" + } + ["Date"]=> + string(36) "Thu, 1 Jan 1970 00:00:00 -0000 (GMT)" + ["From"]=> + string(33) "*** *** *** <***@***.example.com>" + ["X-X-Sender"]=> + string(19) "***@***.example.com" + ["To"]=> + string(23) "internals@lists.php.net" + ["Message-Id"]=> + string(44) "<Pine.LNX.4.58.************@***.example.com>" + ["MIME-Version"]=> + string(3) "1.0" + ["Content-Type"]=> + string(28) "TEXT/PLAIN; charset=US-ASCII" + ["Subject"]=> + string(54) "[PHP-DEV] [ICONV] test for iconv mime decode headers()" + ["X-UIDL"]=> + string(20) "@eH!!h2:!!EOS!!A_c"!" +} + diff --git a/ext/iconv/tests/iconv_mime_decode_headers_variation1.phpt b/ext/iconv/tests/iconv_mime_decode_headers_variation1.phpt new file mode 100644 index 0000000..7cc32c7 --- /dev/null +++ b/ext/iconv/tests/iconv_mime_decode_headers_variation1.phpt @@ -0,0 +1,218 @@ +--TEST-- +Test iconv_mime_encode() function : usage variations - Pass different data types to headers arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_mime_decode_headers') or die("skip iconv_mime_decode_headers() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : array iconv_mime_decode_headers(string headers [, int mode, string charset]) + * Description: Decodes multiple mime header fields + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass different data types to $str argument to see how iconv_mime_decode_headers() behaves + */ + +echo "*** Testing iconv_mime_decode_headers() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$headers = <<<EOF +Subject: =?UTF-8?B?UHLDvGZ1bmcgUHLDvGZ1bmc=?= +To: example@example.com +Date: Thu, 1 Jan 1970 00:00:00 +0000 +Message-Id: <example@example.com> +Received: from localhost (localhost [127.0.0.1]) by localhost + with SMTP id example for <example@example.com>; + Thu, 1 Jan 1970 00:00:00 +0000 (UTC) + (envelope-from example-return-0000-example=example.com@example.com) +Received: (qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000 + +EOF; + +$mode = ICONV_MIME_DECODE_CONTINUE_ON_ERROR; +$charset = 'ISO-8859-1'; + + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $str argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "string", + 'string', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_mime_decode_headers() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_mime_decode_headers($input, $mode, $charset)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_mime_decode_headers() : usage variations *** + +-- Iteration 1 -- +array(0) { +} + +-- Iteration 2 -- +array(0) { +} + +-- Iteration 3 -- +array(0) { +} + +-- Iteration 4 -- +array(0) { +} + +-- Iteration 5 -- +array(0) { +} + +-- Iteration 6 -- +array(0) { +} + +-- Iteration 7 -- +array(0) { +} + +-- Iteration 8 -- +array(0) { +} + +-- Iteration 9 -- +array(0) { +} + +-- Iteration 10 -- +array(0) { +} + +-- Iteration 11 -- +array(0) { +} + +-- Iteration 12 -- +array(0) { +} + +-- Iteration 13 -- +array(0) { +} + +-- Iteration 14 -- +array(0) { +} + +-- Iteration 15 -- +array(0) { +} + +-- Iteration 16 -- +array(0) { +} + +-- Iteration 17 -- +array(0) { +} + +-- Iteration 18 -- +array(0) { +} + +-- Iteration 19 -- +array(0) { +} + +-- Iteration 20 -- +array(0) { +} + +-- Iteration 21 -- +array(0) { +} + +-- Iteration 22 -- +array(0) { +} + +-- Iteration 23 -- +array(0) { +} + +-- Iteration 24 -- + +Warning: iconv_mime_decode_headers() expects parameter 1 to be string, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_mime_decode_headers_variation2.phpt b/ext/iconv/tests/iconv_mime_decode_headers_variation2.phpt new file mode 100644 index 0000000..5ceb801 --- /dev/null +++ b/ext/iconv/tests/iconv_mime_decode_headers_variation2.phpt @@ -0,0 +1,479 @@ +--TEST-- +Test iconv_mime_encode() function : usage variations - Pass different data types to mode arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_mime_decode_headers') or die("skip iconv_mime_decode_headers() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : array iconv_mime_decode_headers(string headers [, int mode, string charset]) + * Description: Decodes multiple mime header fields + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass different data types to $str argument to see how iconv_mime_decode_headers() behaves + */ + +echo "*** Testing iconv_mime_decode_headers() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$headers = <<<EOF +Subject: =?UTF-8?B?QSBTYW1wbGUgVGVzdA==?= +To: example@example.com +Date: Thu, 1 Jan 1970 00:00:00 +0000 +Message-Id: <example@example.com> +Received: from localhost (localhost [127.0.0.1]) by localhost + with SMTP id example for <example@example.com>; + Thu, 1 Jan 1970 00:00:00 +0000 (UTC) + (envelope-from example-return-0000-example=example.com@example.com) +Received: (qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000 + +EOF; + +$mode = ICONV_MIME_DECODE_CONTINUE_ON_ERROR; +$charset = 'UTF-8'; + + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $str argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "string", + 'string', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_mime_decode_headers() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_mime_decode_headers($headers, $input, $charset)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_mime_decode_headers() : usage variations *** + +-- Iteration 1 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 2 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 3 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 4 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 5 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 6 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 7 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 8 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 9 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 10 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 11 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 12 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 13 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 14 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 15 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 16 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, string given in %s on line %d +bool(false) + +-- Iteration 17 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, string given in %s on line %d +bool(false) + +-- Iteration 18 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, string given in %s on line %d +bool(false) + +-- Iteration 19 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, string given in %s on line %d +bool(false) + +-- Iteration 20 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, string given in %s on line %d +bool(false) + +-- Iteration 21 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, object given in %s on line %d +bool(false) + +-- Iteration 22 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 23 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 24 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_mime_decode_headers_variation3.phpt b/ext/iconv/tests/iconv_mime_decode_headers_variation3.phpt new file mode 100644 index 0000000..c4a9cc4 --- /dev/null +++ b/ext/iconv/tests/iconv_mime_decode_headers_variation3.phpt @@ -0,0 +1,482 @@ +--TEST-- +Test iconv_mime_encode() function : usage variations - Pass different data types to charset arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_mime_decode_headers') or die("skip iconv_mime_decode_headers() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : array iconv_mime_decode_headers(string headers [, int mode, string charset]) + * Description: Decodes multiple mime header fields + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass different data types to $str argument to see how iconv_mime_decode_headers() behaves + */ + +echo "*** Testing iconv_mime_decode_headers() : usage variations ***\n"; + +// Some of the parameters actually passed to charset will request to use +// a default charset determined by the platform. In order for this test to +// run on both linux and windows, the subject will have to be ascii only. +// Initialise function arguments not being substituted +$headers = <<<EOF +Subject: =?UTF-8?B?QSBTYW1wbGUgVGVzdA==?= +To: example@example.com +Date: Thu, 1 Jan 1970 00:00:00 +0000 +Message-Id: <example@example.com> +Received: from localhost (localhost [127.0.0.1]) by localhost + with SMTP id example for <example@example.com>; + Thu, 1 Jan 1970 00:00:00 +0000 (UTC) + (envelope-from example-return-0000-example=example.com@example.com) +Received: (qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000 + +EOF; + +$mode = ICONV_MIME_DECODE_CONTINUE_ON_ERROR; +$charset = 'UTF-8'; + + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $str argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "string", + 'string', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_mime_decode_headers() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_mime_decode_headers($headers, $input, $charset)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_mime_decode_headers() : usage variations *** + +-- Iteration 1 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 2 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 3 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 4 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 5 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 6 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 7 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 8 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 9 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 10 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 11 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 12 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 13 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 14 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 15 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 16 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, string given in %s on line %d +bool(false) + +-- Iteration 17 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, string given in %s on line %d +bool(false) + +-- Iteration 18 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, string given in %s on line %d +bool(false) + +-- Iteration 19 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, string given in %s on line %d +bool(false) + +-- Iteration 20 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, string given in %s on line %d +bool(false) + +-- Iteration 21 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, object given in %s on line %d +bool(false) + +-- Iteration 22 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 23 -- +array(5) { + ["Subject"]=> + string(13) "A Sample Test" + ["To"]=> + string(19) "example@example.com" + ["Date"]=> + string(30) "Thu, 1 Jan 1970 00:00:00 +0000" + ["Message-Id"]=> + string(21) "<example@example.com>" + ["Received"]=> + array(2) { + [0]=> + string(204) "from localhost (localhost [127.0.0.1]) by localhost with SMTP id example for <example@example.com>; Thu, 1 Jan 1970 00:00:00 +0000 (UTC) (envelope-from example-return-0000-example=example.com@example.com)" + [1]=> + string(57) "(qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000" + } +} + +-- Iteration 24 -- + +Warning: iconv_mime_decode_headers() expects parameter 2 to be long, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_mime_decode_variation1.phpt b/ext/iconv/tests/iconv_mime_decode_variation1.phpt new file mode 100644 index 0000000..a42b0de --- /dev/null +++ b/ext/iconv/tests/iconv_mime_decode_variation1.phpt @@ -0,0 +1,183 @@ +--TEST-- +Test iconv_mime_decode() function : usage variations - Pass different data types to header arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_mime_decode') or die("skip iconv_mime_decode() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : string iconv_mime_decode(string encoded_string [, int mode, string charset]) + * Description: Decodes a mime header field + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass different data types to $str argument to see how iconv_mime_decode() behaves + */ + +echo "*** Testing iconv_mime_decode() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$header = b'Subject: =?UTF-8?B?UHLDvGZ1bmcgUHLDvGZ1bmc=?='; +$mode = ICONV_MIME_DECODE_CONTINUE_ON_ERROR; +$charset = 'ISO-8859-1'; + + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $str argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "string", + 'string', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_mime_decode() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_mime_decode($input, $mode, $charset)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_mime_decode() : usage variations *** + +-- Iteration 1 -- +string(1) "0" + +-- Iteration 2 -- +string(1) "1" + +-- Iteration 3 -- +string(5) "12345" + +-- Iteration 4 -- +string(5) "-2345" + +-- Iteration 5 -- +string(4) "10.5" + +-- Iteration 6 -- +string(5) "-10.5" + +-- Iteration 7 -- +string(12) "123456789000" + +-- Iteration 8 -- +string(13) "1.23456789E-9" + +-- Iteration 9 -- +string(3) "0.5" + +-- Iteration 10 -- +string(0) "" + +-- Iteration 11 -- +string(0) "" + +-- Iteration 12 -- +string(1) "1" + +-- Iteration 13 -- +string(0) "" + +-- Iteration 14 -- +string(1) "1" + +-- Iteration 15 -- +string(0) "" + +-- Iteration 16 -- +string(0) "" + +-- Iteration 17 -- +string(0) "" + +-- Iteration 18 -- +string(6) "string" + +-- Iteration 19 -- +string(6) "string" + +-- Iteration 20 -- +string(11) "hello world" + +-- Iteration 21 -- +string(14) "Class A object" + +-- Iteration 22 -- +string(0) "" + +-- Iteration 23 -- +string(0) "" + +-- Iteration 24 -- + +Warning: iconv_mime_decode() expects parameter 1 to be string, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_mime_decode_variation2.phpt b/ext/iconv/tests/iconv_mime_decode_variation2.phpt new file mode 100644 index 0000000..1d82822 --- /dev/null +++ b/ext/iconv/tests/iconv_mime_decode_variation2.phpt @@ -0,0 +1,195 @@ +--TEST-- +Test iconv_mime_decode() function : usage variations - Pass different data types to mode arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_mime_decode') or die("skip iconv_mime_decode() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : string iconv_mime_decode(string encoded_string [, int mode, string charset]) + * Description: Decodes a mime header field + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass different data types to $str argument to see how iconv_mime_decode() behaves + */ + +echo "*** Testing iconv_mime_decode() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$header = b'Subject: =?UTF-8?B?UHLDvGZ1bmcgUHLDvGZ1bmc=?='; +$mode = ICONV_MIME_DECODE_CONTINUE_ON_ERROR; +$charset = 'UTF-8'; + + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $str argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "string", + 'string', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_mime_decode() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( bin2hex(iconv_mime_decode($header, $input, $charset))); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_mime_decode() : usage variations *** + +-- Iteration 1 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 2 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 3 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 4 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 5 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 6 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 7 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 8 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 9 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 10 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 11 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 12 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 13 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 14 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 15 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 16 -- + +Warning: iconv_mime_decode() expects parameter 2 to be long, string given in %s on line %d +string(0) "" + +-- Iteration 17 -- + +Warning: iconv_mime_decode() expects parameter 2 to be long, string given in %s on line %d +string(0) "" + +-- Iteration 18 -- + +Warning: iconv_mime_decode() expects parameter 2 to be long, string given in %s on line %d +string(0) "" + +-- Iteration 19 -- + +Warning: iconv_mime_decode() expects parameter 2 to be long, string given in %s on line %d +string(0) "" + +-- Iteration 20 -- + +Warning: iconv_mime_decode() expects parameter 2 to be long, string given in %s on line %d +string(0) "" + +-- Iteration 21 -- + +Warning: iconv_mime_decode() expects parameter 2 to be long, object given in %s on line %d +string(0) "" + +-- Iteration 22 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 23 -- +string(52) "5375626a6563743a205072c3bc66756e67205072c3bc66756e67" + +-- Iteration 24 -- + +Warning: iconv_mime_decode() expects parameter 2 to be long, resource given in %s on line %d +string(0) "" +Done diff --git a/ext/iconv/tests/iconv_mime_decode_variation3.phpt b/ext/iconv/tests/iconv_mime_decode_variation3.phpt new file mode 100644 index 0000000..cd5c719 --- /dev/null +++ b/ext/iconv/tests/iconv_mime_decode_variation3.phpt @@ -0,0 +1,222 @@ +--TEST-- +Test iconv_mime_decode() function : usage variations - Pass different data types to charset arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_mime_decode') or die("skip iconv_mime_decode() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : string iconv_mime_decode(string encoded_string [, int mode, string charset]) + * Description: Decodes a mime header field + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass different data types to $str argument to see how iconv_mime_decode() behaves + */ + +echo "*** Testing iconv_mime_decode() : usage variations ***\n"; + +// Initialise function arguments not being substituted +// Some of the parameters actually passed to charset will request to use +// a default charset determined by the platform. In order for this test to +// run on both linux and windows, the subject will have to be ascii only. +$header = b'Subject: =?UTF-8?B?QSBTYW1wbGUgVGVzdA==?='; +$mode = ICONV_MIME_DECODE_CONTINUE_ON_ERROR; +$charset = 'UTF-8'; + + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $str argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "string", + 'string', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_mime_decode() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + $res = iconv_mime_decode($header, $mode, $input); + if ($res !== false) { + var_dump(bin2hex($res)); + } + else { + var_dump($res); + } + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_mime_decode() : usage variations *** + +-- Iteration 1 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `0' is not allowed in %s on line %d +bool(false) + +-- Iteration 2 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `1' is not allowed in %s on line %d +bool(false) + +-- Iteration 3 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `12345' is not allowed in %s on line %d +bool(false) + +-- Iteration 4 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `-2345' is not allowed in %s on line %d +bool(false) + +-- Iteration 5 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `10.5' is not allowed in %s on line %d +bool(false) + +-- Iteration 6 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `-10.5' is not allowed in %s on line %d +bool(false) + +-- Iteration 7 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `123456789000' is not allowed in %s on line %d +bool(false) + +-- Iteration 8 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `1.23456789E-9' is not allowed in %s on line %d +bool(false) + +-- Iteration 9 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `0.5' is not allowed in %s on line %d +bool(false) + +-- Iteration 10 -- +string(44) "5375626a6563743a20412053616d706c652054657374" + +-- Iteration 11 -- +string(44) "5375626a6563743a20412053616d706c652054657374" + +-- Iteration 12 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `1' is not allowed in %s on line %d +bool(false) + +-- Iteration 13 -- +string(44) "5375626a6563743a20412053616d706c652054657374" + +-- Iteration 14 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `1' is not allowed in %s on line %d +bool(false) + +-- Iteration 15 -- +string(44) "5375626a6563743a20412053616d706c652054657374" + +-- Iteration 16 -- +string(44) "5375626a6563743a20412053616d706c652054657374" + +-- Iteration 17 -- +string(44) "5375626a6563743a20412053616d706c652054657374" + +-- Iteration 18 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `string' is not allowed in %s on line %d +bool(false) + +-- Iteration 19 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `string' is not allowed in %s on line %d +bool(false) + +-- Iteration 20 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `hello world' is not allowed in %s on line %d +bool(false) + +-- Iteration 21 -- + +Notice: iconv_mime_decode(): Wrong charset, conversion from `???' to `Class A object' is not allowed in %s on line %d +bool(false) + +-- Iteration 22 -- +string(44) "5375626a6563743a20412053616d706c652054657374" + +-- Iteration 23 -- +string(44) "5375626a6563743a20412053616d706c652054657374" + +-- Iteration 24 -- + +Warning: iconv_mime_decode() expects parameter 3 to be string, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_mime_encode.phpt b/ext/iconv/tests/iconv_mime_encode.phpt new file mode 100644 index 0000000..bd090e4 --- /dev/null +++ b/ext/iconv/tests/iconv_mime_encode.phpt @@ -0,0 +1,426 @@ +--TEST-- +iconv_mime_encode() +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--INI-- +iconv.internal_charset=iso-8859-1 +--FILE-- +<?php +function my_error_handler($errno, $errmsg, $filename, $linenum, $vars) +{ + echo "$errno: $errmsg\n"; +} +set_error_handler('my_error_handler'); +$preference = array( + "scheme" => "B", + "output-charset" => "ISO-2022-JP", + "input-charset" => "EUC-JP", + "line-break-chars" => "\n" +); +for ($line_len= 0; $line_len < 80; ++$line_len) { + print "-------- line length=$line_len\n"; + $preference["line-length"] = $line_len; + $result = iconv_mime_encode("From", "サンプル文字列サンプル文字列日本語テキスト", $preference); + var_dump($result); + if ($result !== false) { + $max = max(array_map("strlen", explode("\n", $result))); + print "-------- "; + var_dump(($max <= $line_len)); + } else { + print "-------- \n"; + } +} +?> +--EXPECTF-- +-------- line length=0 +2: %s +bool(false) +-------- +-------- line length=1 +2: %s +bool(false) +-------- +-------- line length=2 +2: %s +bool(false) +-------- +-------- line length=3 +2: %s +bool(false) +-------- +-------- line length=4 +2: %s +bool(false) +-------- +-------- line length=5 +2: %s +bool(false) +-------- +-------- line length=6 +2: %s +bool(false) +-------- +-------- line length=7 +2: %s +bool(false) +-------- +-------- line length=8 +2: %s +bool(false) +-------- +-------- line length=9 +2: %s +bool(false) +-------- +-------- line length=10 +2: %s +bool(false) +-------- +-------- line length=11 +2: %s +bool(false) +-------- +-------- line length=12 +2: %s +bool(false) +-------- +-------- line length=13 +2: %s +bool(false) +-------- +-------- line length=14 +2: %s +bool(false) +-------- +-------- line length=15 +2: %s +bool(false) +-------- +-------- line length=16 +2: %s +bool(false) +-------- +-------- line length=17 +2: %s +bool(false) +-------- +-------- line length=18 +2: %s +bool(false) +-------- +-------- line length=19 +2: %s +bool(false) +-------- +-------- line length=20 +2: %s +bool(false) +-------- +-------- line length=21 +2: %s +bool(false) +-------- +-------- line length=22 +2: %s +bool(false) +-------- +-------- line length=23 +2: %s +bool(false) +-------- +-------- line length=24 +2: %s +bool(false) +-------- +-------- line length=25 +2: %s +bool(false) +-------- +-------- line length=26 +2: %s +bool(false) +-------- +-------- line length=27 +2: %s +bool(false) +-------- +-------- line length=28 +2: %s +bool(false) +-------- +-------- line length=29 +2: %s +bool(false) +-------- +-------- line length=30 +2: %s +bool(false) +-------- +-------- line length=31 +2: %s +bool(false) +-------- +-------- line length=32 +2: %s +bool(false) +-------- +-------- line length=33 +2: %s +bool(false) +-------- +-------- line length=34 +2: %s +bool(false) +-------- +-------- line length=35 +2: %s +bool(false) +-------- +-------- line length=36 +string(396) "From: =?ISO-2022-JP?B?GyRCJTUbKEI=?= + =?ISO-2022-JP?B?GyRCJXMlVxsoQg==?= + =?ISO-2022-JP?B?GyRCJWtKOBsoQg==?= + =?ISO-2022-JP?B?GyRCO3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVclaxsoQg==?= + =?ISO-2022-JP?B?GyRCSjg7ehsoQg==?= + =?ISO-2022-JP?B?GyRCTnNGfBsoQg==?= + =?ISO-2022-JP?B?GyRCS1w4bBsoQg==?= + =?ISO-2022-JP?B?GyRCJUYlLRsoQg==?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?=" +-------- bool(true) +-------- line length=37 +string(396) "From: =?ISO-2022-JP?B?GyRCJTUbKEI=?= + =?ISO-2022-JP?B?GyRCJXMlVxsoQg==?= + =?ISO-2022-JP?B?GyRCJWtKOBsoQg==?= + =?ISO-2022-JP?B?GyRCO3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVclaxsoQg==?= + =?ISO-2022-JP?B?GyRCSjg7ehsoQg==?= + =?ISO-2022-JP?B?GyRCTnNGfBsoQg==?= + =?ISO-2022-JP?B?GyRCS1w4bBsoQg==?= + =?ISO-2022-JP?B?GyRCJUYlLRsoQg==?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?=" +-------- bool(true) +-------- line length=38 +string(396) "From: =?ISO-2022-JP?B?GyRCJTUbKEI=?= + =?ISO-2022-JP?B?GyRCJXMlVxsoQg==?= + =?ISO-2022-JP?B?GyRCJWtKOBsoQg==?= + =?ISO-2022-JP?B?GyRCO3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVclaxsoQg==?= + =?ISO-2022-JP?B?GyRCSjg7ehsoQg==?= + =?ISO-2022-JP?B?GyRCTnNGfBsoQg==?= + =?ISO-2022-JP?B?GyRCS1w4bBsoQg==?= + =?ISO-2022-JP?B?GyRCJUYlLRsoQg==?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?=" +-------- bool(true) +-------- line length=39 +string(236) "From: =?ISO-2022-JP?B?GyRCJTUbKEI=?= + =?ISO-2022-JP?B?GyRCJXMlVyVrSjgbKEI=?= + =?ISO-2022-JP?B?GyRCO3pOcyU1JXMbKEI=?= + =?ISO-2022-JP?B?GyRCJVcla0o4O3obKEI=?= + =?ISO-2022-JP?B?GyRCTnNGfEtcOGwbKEI=?= + =?ISO-2022-JP?B?GyRCJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=40 +string(236) "From: =?ISO-2022-JP?B?GyRCJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVcla0o4O3obKEI=?= + =?ISO-2022-JP?B?GyRCTnMlNSVzJVcbKEI=?= + =?ISO-2022-JP?B?GyRCJWtKODt6TnMbKEI=?= + =?ISO-2022-JP?B?GyRCRnxLXDhsJUYbKEI=?= + =?ISO-2022-JP?B?GyRCJS0lOSVIGyhC?=" +-------- bool(true) +-------- line length=41 +string(236) "From: =?ISO-2022-JP?B?GyRCJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVcla0o4O3obKEI=?= + =?ISO-2022-JP?B?GyRCTnMlNSVzJVcbKEI=?= + =?ISO-2022-JP?B?GyRCJWtKODt6TnMbKEI=?= + =?ISO-2022-JP?B?GyRCRnxLXDhsJUYbKEI=?= + =?ISO-2022-JP?B?GyRCJS0lOSVIGyhC?=" +-------- bool(true) +-------- line length=42 +string(236) "From: =?ISO-2022-JP?B?GyRCJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVcla0o4O3obKEI=?= + =?ISO-2022-JP?B?GyRCTnMlNSVzJVcbKEI=?= + =?ISO-2022-JP?B?GyRCJWtKODt6TnMbKEI=?= + =?ISO-2022-JP?B?GyRCRnxLXDhsJUYbKEI=?= + =?ISO-2022-JP?B?GyRCJS0lOSVIGyhC?=" +-------- bool(true) +-------- line length=43 +string(212) "From: =?ISO-2022-JP?B?GyRCJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVcla0o4O3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKOBsoQg==?= + =?ISO-2022-JP?B?GyRCO3pOc0Z8S1w4bBsoQg==?= + =?ISO-2022-JP?B?GyRCJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=44 +string(212) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWsbKEI=?= + =?ISO-2022-JP?B?GyRCSjg7ek5zJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVcla0o4O3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCRnxLXDhsJUYlLRsoQg==?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?=" +-------- bool(true) +-------- line length=45 +string(212) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWsbKEI=?= + =?ISO-2022-JP?B?GyRCSjg7ek5zJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVcla0o4O3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCRnxLXDhsJUYlLRsoQg==?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?=" +-------- bool(true) +-------- line length=46 +string(212) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWsbKEI=?= + =?ISO-2022-JP?B?GyRCSjg7ek5zJTUlcxsoQg==?= + =?ISO-2022-JP?B?GyRCJVcla0o4O3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCRnxLXDhsJUYlLRsoQg==?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?=" +-------- bool(true) +-------- line length=47 +string(176) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWsbKEI=?= + =?ISO-2022-JP?B?GyRCSjg7ek5zJTUlcyVXJWsbKEI=?= + =?ISO-2022-JP?B?GyRCSjg7ek5zRnxLXDhsJUYbKEI=?= + =?ISO-2022-JP?B?GyRCJS0lOSVIGyhC?=" +-------- bool(true) +-------- line length=48 +string(180) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKOBsoQg==?= + =?ISO-2022-JP?B?GyRCO3pOcyU1JXMlVyVrSjgbKEI=?= + =?ISO-2022-JP?B?GyRCO3pOc0Z8S1w4bCVGJS0bKEI=?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?=" +-------- bool(true) +-------- line length=49 +string(180) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKOBsoQg==?= + =?ISO-2022-JP?B?GyRCO3pOcyU1JXMlVyVrSjgbKEI=?= + =?ISO-2022-JP?B?GyRCO3pOc0Z8S1w4bCVGJS0bKEI=?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?=" +-------- bool(true) +-------- line length=50 +string(180) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKOBsoQg==?= + =?ISO-2022-JP?B?GyRCO3pOcyU1JXMlVyVrSjgbKEI=?= + =?ISO-2022-JP?B?GyRCO3pOc0Z8S1w4bCVGJS0bKEI=?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?=" +-------- bool(true) +-------- line length=51 +string(152) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKOBsoQg==?= + =?ISO-2022-JP?B?GyRCO3pOcyU1JXMlVyVrSjg7ehsoQg==?= + =?ISO-2022-JP?B?GyRCTnNGfEtcOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=52 +string(148) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMbKEI=?= + =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnNGfBsoQg==?= + =?ISO-2022-JP?B?GyRCS1w4bCVGJS0lOSVIGyhC?=" +-------- bool(true) +-------- line length=53 +string(148) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMbKEI=?= + =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnNGfBsoQg==?= + =?ISO-2022-JP?B?GyRCS1w4bCVGJS0lOSVIGyhC?=" +-------- bool(true) +-------- line length=54 +string(148) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMbKEI=?= + =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnNGfBsoQg==?= + =?ISO-2022-JP?B?GyRCS1w4bCVGJS0lOSVIGyhC?=" +-------- bool(true) +-------- line length=55 +string(148) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMbKEI=?= + =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnNGfEtcOGwbKEI=?= + =?ISO-2022-JP?B?GyRCJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=56 +string(148) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNRsoQg==?= + =?ISO-2022-JP?B?GyRCJXMlVyVrSjg7ek5zRnxLXDhsJUYbKEI=?= + =?ISO-2022-JP?B?GyRCJS0lOSVIGyhC?=" +-------- bool(true) +-------- line length=57 +string(148) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNRsoQg==?= + =?ISO-2022-JP?B?GyRCJXMlVyVrSjg7ek5zRnxLXDhsJUYbKEI=?= + =?ISO-2022-JP?B?GyRCJS0lOSVIGyhC?=" +-------- bool(true) +-------- line length=58 +string(148) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNRsoQg==?= + =?ISO-2022-JP?B?GyRCJXMlVyVrSjg7ek5zRnxLXDhsJUYbKEI=?= + =?ISO-2022-JP?B?GyRCJS0lOSVIGyhC?=" +-------- bool(true) +-------- line length=59 +string(152) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNRsoQg==?= + =?ISO-2022-JP?B?GyRCJXMlVyVrSjg7ek5zRnxLXDhsJUYlLRsoQg==?= + =?ISO-2022-JP?B?GyRCJTklSBsoQg==?=" +-------- bool(true) +-------- line length=60 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcbKEI=?= + =?ISO-2022-JP?B?GyRCJWtKODt6TnNGfEtcOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=61 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcbKEI=?= + =?ISO-2022-JP?B?GyRCJWtKODt6TnNGfEtcOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=62 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcbKEI=?= + =?ISO-2022-JP?B?GyRCJWtKODt6TnNGfEtcOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=63 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcbKEI=?= + =?ISO-2022-JP?B?GyRCJWtKODt6TnNGfEtcOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=64 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVclaxsoQg==?= + =?ISO-2022-JP?B?GyRCSjg7ek5zRnxLXDhsJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=65 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVclaxsoQg==?= + =?ISO-2022-JP?B?GyRCSjg7ek5zRnxLXDhsJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=66 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVclaxsoQg==?= + =?ISO-2022-JP?B?GyRCSjg7ek5zRnxLXDhsJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=67 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVclaxsoQg==?= + =?ISO-2022-JP?B?GyRCSjg7ek5zRnxLXDhsJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=68 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3obKEI=?= + =?ISO-2022-JP?B?GyRCTnNGfEtcOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=69 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3obKEI=?= + =?ISO-2022-JP?B?GyRCTnNGfEtcOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=70 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3obKEI=?= + =?ISO-2022-JP?B?GyRCTnNGfEtcOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=71 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3obKEI=?= + =?ISO-2022-JP?B?GyRCTnNGfEtcOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=72 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCRnxLXDhsJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=73 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCRnxLXDhsJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=74 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCRnxLXDhsJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=75 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3pOcxsoQg==?= + =?ISO-2022-JP?B?GyRCRnxLXDhsJUYlLSU5JUgbKEI=?=" +-------- bool(true) +-------- line length=76 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3pOc0Z8S1wbKEI=?= + =?ISO-2022-JP?B?GyRCOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=77 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3pOc0Z8S1wbKEI=?= + =?ISO-2022-JP?B?GyRCOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=78 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3pOc0Z8S1wbKEI=?= + =?ISO-2022-JP?B?GyRCOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) +-------- line length=79 +string(120) "From: =?ISO-2022-JP?B?GyRCJTUlcyVXJWtKODt6TnMlNSVzJVcla0o4O3pOc0Z8S1wbKEI=?= + =?ISO-2022-JP?B?GyRCOGwlRiUtJTklSBsoQg==?=" +-------- bool(true) diff --git a/ext/iconv/tests/iconv_set_encoding-charset-length-cve-2007-4840.phpt b/ext/iconv/tests/iconv_set_encoding-charset-length-cve-2007-4840.phpt new file mode 100644 index 0000000..e6abca5 --- /dev/null +++ b/ext/iconv/tests/iconv_set_encoding-charset-length-cve-2007-4840.phpt @@ -0,0 +1,21 @@ +--TEST-- +iconv_set_encoding() charset parameter length checks (CVE-2007-4840) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$a = str_repeat("/", 9000000); +var_dump(iconv_set_encoding("input_encoding", $a)); +var_dump(iconv_set_encoding("output_encoding", $a)); +var_dump(iconv_set_encoding("internal_encoding", $a)); +?> +--EXPECTF-- + +Warning: iconv_set_encoding(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) + +Warning: iconv_set_encoding(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) + +Warning: iconv_set_encoding(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) diff --git a/ext/iconv/tests/iconv_set_encoding_error.phpt b/ext/iconv/tests/iconv_set_encoding_error.phpt new file mode 100644 index 0000000..4ba8400 --- /dev/null +++ b/ext/iconv/tests/iconv_set_encoding_error.phpt @@ -0,0 +1,177 @@ +--TEST-- +Test iconv_set_encoding() function : basic functionality +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_set_encoding') or die("skip iconv_set_encoding() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : bool iconv_set_encoding(string type, string charset) + * Description: Sets internal encoding and output encoding for ob_iconv_handler() + * Source code: ext/iconv/iconv.c + */ + +/* + * Test Error functionality of iconv_get_encoding + */ + +echo "*** Testing iconv_set_encoding() : error functionality ***\n"; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "UTF-8"; + } +} + +// heredoc string +$heredoc = <<<EOT +Nothing +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $encoding argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // invalid string data +/*18*/ "Nothing", + 'Nothing', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of mb_regex_encoding() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_set_encoding($input, "UTF-8") ); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_set_encoding() : error functionality *** + +-- Iteration 1 -- +bool(false) + +-- Iteration 2 -- +bool(false) + +-- Iteration 3 -- +bool(false) + +-- Iteration 4 -- +bool(false) + +-- Iteration 5 -- +bool(false) + +-- Iteration 6 -- +bool(false) + +-- Iteration 7 -- +bool(false) + +-- Iteration 8 -- +bool(false) + +-- Iteration 9 -- +bool(false) + +-- Iteration 10 -- +bool(false) + +-- Iteration 11 -- +bool(false) + +-- Iteration 12 -- +bool(false) + +-- Iteration 13 -- +bool(false) + +-- Iteration 14 -- +bool(false) + +-- Iteration 15 -- +bool(false) + +-- Iteration 16 -- +bool(false) + +-- Iteration 17 -- +bool(false) + +-- Iteration 18 -- +bool(false) + +-- Iteration 19 -- +bool(false) + +-- Iteration 20 -- +bool(false) + +-- Iteration 21 -- +bool(false) + +-- Iteration 22 -- +bool(false) + +-- Iteration 23 -- +bool(false) + +-- Iteration 24 -- + +Warning: iconv_set_encoding() expects parameter 1 to be string, resource given in %s on line %d +NULL +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_set_encoding_variation.phpt b/ext/iconv/tests/iconv_set_encoding_variation.phpt new file mode 100644 index 0000000..311a9f9 --- /dev/null +++ b/ext/iconv/tests/iconv_set_encoding_variation.phpt @@ -0,0 +1,307 @@ +--TEST-- +Test iconv_set_encoding() function : error functionality +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_set_encoding') or die("skip iconv_set_encoding() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : bool iconv_set_encoding(string type, string charset) + * Description: Sets internal encoding and output encoding for ob_iconv_handler() + * Source code: ext/iconv/iconv.c + */ + +/* + * Test Error functionality of iconv_get_encoding + */ + +echo "*** Testing iconv_set_encoding() : error functionality ***\n"; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "UTF-8"; + } +} + +// heredoc string +$heredoc = <<<EOT +Nothing +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $encoding argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // invalid string data +/*18*/ "Nothing", + 'Nothing', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of mb_regex_encoding() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_set_encoding("internal_encoding", $input) ); + var_dump( iconv_set_encoding("input_encoding", $input) ); + var_dump( iconv_set_encoding("output_encoding", $input) ); + var_dump( iconv_get_encoding("internal_encoding") ); + var_dump( iconv_get_encoding("input_encoding") ); + var_dump( iconv_get_encoding("output_encoding") ); + + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_set_encoding() : error functionality *** + +-- Iteration 1 -- +bool(true) +bool(true) +bool(true) +string(1) "0" +string(1) "0" +string(1) "0" + +-- Iteration 2 -- +bool(true) +bool(true) +bool(true) +string(1) "1" +string(1) "1" +string(1) "1" + +-- Iteration 3 -- +bool(true) +bool(true) +bool(true) +string(5) "12345" +string(5) "12345" +string(5) "12345" + +-- Iteration 4 -- +bool(true) +bool(true) +bool(true) +string(5) "-2345" +string(5) "-2345" +string(5) "-2345" + +-- Iteration 5 -- +bool(true) +bool(true) +bool(true) +string(4) "10.5" +string(4) "10.5" +string(4) "10.5" + +-- Iteration 6 -- +bool(true) +bool(true) +bool(true) +string(5) "-10.5" +string(5) "-10.5" +string(5) "-10.5" + +-- Iteration 7 -- +bool(true) +bool(true) +bool(true) +string(12) "123456789000" +string(12) "123456789000" +string(12) "123456789000" + +-- Iteration 8 -- +bool(true) +bool(true) +bool(true) +string(13) "1.23456789E-9" +string(13) "1.23456789E-9" +string(13) "1.23456789E-9" + +-- Iteration 9 -- +bool(true) +bool(true) +bool(true) +string(3) "0.5" +string(3) "0.5" +string(3) "0.5" + +-- Iteration 10 -- +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +string(0) "" + +-- Iteration 11 -- +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +string(0) "" + +-- Iteration 12 -- +bool(true) +bool(true) +bool(true) +string(1) "1" +string(1) "1" +string(1) "1" + +-- Iteration 13 -- +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +string(0) "" + +-- Iteration 14 -- +bool(true) +bool(true) +bool(true) +string(1) "1" +string(1) "1" +string(1) "1" + +-- Iteration 15 -- +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +string(0) "" + +-- Iteration 16 -- +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +string(0) "" + +-- Iteration 17 -- +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +string(0) "" + +-- Iteration 18 -- +bool(true) +bool(true) +bool(true) +string(7) "Nothing" +string(7) "Nothing" +string(7) "Nothing" + +-- Iteration 19 -- +bool(true) +bool(true) +bool(true) +string(7) "Nothing" +string(7) "Nothing" +string(7) "Nothing" + +-- Iteration 20 -- +bool(true) +bool(true) +bool(true) +string(7) "Nothing" +string(7) "Nothing" +string(7) "Nothing" + +-- Iteration 21 -- +bool(true) +bool(true) +bool(true) +string(5) "UTF-8" +string(5) "UTF-8" +string(5) "UTF-8" + +-- Iteration 22 -- +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +string(0) "" + +-- Iteration 23 -- +bool(true) +bool(true) +bool(true) +string(0) "" +string(0) "" +string(0) "" + +-- Iteration 24 -- + +Warning: iconv_set_encoding() expects parameter 2 to be string, resource given in %s on line %d +NULL + +Warning: iconv_set_encoding() expects parameter 2 to be string, resource given in %s on line %d +NULL + +Warning: iconv_set_encoding() expects parameter 2 to be string, resource given in %s on line %d +NULL +string(0) "" +string(0) "" +string(0) "" +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_stream_filter.phpt b/ext/iconv/tests/iconv_stream_filter.phpt new file mode 100644 index 0000000..79f6ad5 --- /dev/null +++ b/ext/iconv/tests/iconv_stream_filter.phpt @@ -0,0 +1,39 @@ +--TEST-- +iconv stream filter +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--INI-- +iconv.internal_charset=iso-8859-1 +--FILE-- +<?php +$fp = fopen(dirname(__FILE__).'/iconv_stream_filter.txt', 'rb'); +var_dump(bin2hex(fread($fp, 10))); +var_dump(bin2hex(fread($fp, 5))); +var_dump(bin2hex(fread($fp, 1))); +fclose($fp); + +$fp = fopen(dirname(__FILE__).'/iconv_stream_filter.txt', 'rb'); +stream_filter_append($fp, 'convert.iconv.ISO-2022-JP/EUC-JP'); +var_dump(bin2hex(fread($fp, 10))); +var_dump(bin2hex(fread($fp, 5))); +var_dump(bin2hex(fread($fp, 1))); +fclose($fp); + +$fp = fopen(dirname(__FILE__).'/iconv_stream_filter.txt', 'rb'); +stream_filter_append($fp, 'string.rot13'); // this will make conversion fail. +stream_filter_append($fp, 'convert.iconv.ISO-2022-JP/EUC-JP'); +var_dump(bin2hex(@fread($fp, 10)) != "a4b3a4f3a4cba4c1a4cf"); +var_dump(bin2hex(fread($fp, 5)) != "69636f6e76"); +var_dump(bin2hex(fread($fp, 1)) != "0a"); +fclose($fp); +?> +--EXPECTF-- +string(20) "1b244224332473244b24" +string(10) "41244f1b28" +string(2) "42" +string(20) "a4b3a4f3a4cba4c1a4cf" +string(10) "69636f6e76" +string(2) "0a" +bool(true) +bool(true) +bool(true) diff --git a/ext/iconv/tests/iconv_stream_filter.txt b/ext/iconv/tests/iconv_stream_filter.txt new file mode 100644 index 0000000..1074d2a --- /dev/null +++ b/ext/iconv/tests/iconv_stream_filter.txt @@ -0,0 +1 @@ +$B$3$s$K$A$O(Biconv diff --git a/ext/iconv/tests/iconv_stream_filter_delimiter.phpt b/ext/iconv/tests/iconv_stream_filter_delimiter.phpt new file mode 100644 index 0000000..895f614 --- /dev/null +++ b/ext/iconv/tests/iconv_stream_filter_delimiter.phpt @@ -0,0 +1,50 @@ +--TEST-- +iconv stream filter +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--INI-- +iconv.internal_charset=iso-8859-1 +--FILE-- +<?php +$fp = fopen(dirname(__FILE__).'/iconv_stream_filter.txt', 'rb'); +var_dump(bin2hex(fread($fp, 10))); +var_dump(bin2hex(fread($fp, 5))); +var_dump(bin2hex(fread($fp, 1))); +fclose($fp); + +$fp = fopen(dirname(__FILE__).'/iconv_stream_filter.txt', 'rb'); +stream_filter_append($fp, 'convert.iconv.ISO-2022-JP/EUC-JP'); +var_dump(bin2hex(fread($fp, 10))); +var_dump(bin2hex(fread($fp, 5))); +var_dump(bin2hex(fread($fp, 1))); +fclose($fp); + +$fp = fopen(dirname(__FILE__).'/iconv_stream_filter.txt', 'rb'); +stream_filter_append($fp, 'convert.iconv.ISO-2022-JP.EUC-JP'); +var_dump(bin2hex(fread($fp, 10))); +var_dump(bin2hex(fread($fp, 5))); +var_dump(bin2hex(fread($fp, 1))); +fclose($fp); + +$fp = fopen(dirname(__FILE__).'/iconv_stream_filter.txt', 'rb'); +stream_filter_append($fp, 'convert.iconv.ISO-2022-JP\0EUC-JP'); +var_dump(bin2hex(fread($fp, 10))); +var_dump(bin2hex(fread($fp, 5))); +var_dump(bin2hex(fread($fp, 1))); +fclose($fp); +?> +--EXPECTF-- +string(20) "1b244224332473244b24" +string(10) "41244f1b28" +string(2) "42" +string(20) "a4b3a4f3a4cba4c1a4cf" +string(10) "69636f6e76" +string(2) "0a" +string(20) "a4b3a4f3a4cba4c1a4cf" +string(10) "69636f6e76" +string(2) "0a" + +Warning: stream_filter_append(): unable to create or locate filter "convert.iconv.ISO-2022-JP\0EUC-JP" in %siconv_stream_filter_delimiter.php on line %d +string(20) "1b244224332473244b24" +string(10) "41244f1b28" +string(2) "42" diff --git a/ext/iconv/tests/iconv_strlen-charset-length-cve-2007-4840.phpt b/ext/iconv/tests/iconv_strlen-charset-length-cve-2007-4840.phpt new file mode 100644 index 0000000..348cfb1 --- /dev/null +++ b/ext/iconv/tests/iconv_strlen-charset-length-cve-2007-4840.phpt @@ -0,0 +1,13 @@ +--TEST-- +iconv_strlen() charset parameter length checks (CVE-2007-4840) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$a = str_repeat("/", 9791999); +var_dump(iconv_strlen(1, $a)); +?> +--EXPECTF-- + +Warning: iconv_strlen(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) diff --git a/ext/iconv/tests/iconv_strlen.phpt b/ext/iconv/tests/iconv_strlen.phpt new file mode 100644 index 0000000..2c815f4 --- /dev/null +++ b/ext/iconv/tests/iconv_strlen.phpt @@ -0,0 +1,19 @@ +--TEST-- +iconv_strlen() +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +function foo($str, $charset) { + var_dump(strlen($str)); + var_dump(iconv_strlen($str, $charset)); +} + +foo("abc", "ASCII"); +foo("日本語 EUC-JP", "EUC-JP"); +?> +--EXPECT-- +int(3) +int(3) +int(13) +int(10) diff --git a/ext/iconv/tests/iconv_strlen_basic.phpt b/ext/iconv/tests/iconv_strlen_basic.phpt new file mode 100644 index 0000000..5777435 --- /dev/null +++ b/ext/iconv/tests/iconv_strlen_basic.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test iconv_strlen() function : basic functionality +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strlen') or die("skip iconv_strlen() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strlen(string str [, string charset]) + * Description: Get character numbers of a string + * Source code: ext/iconv/iconv.c + */ + +/* + * Test basic functionality of iconv_strlen() + */ + +echo "*** Testing iconv_strlen() : basic functionality***\n"; + +$string_ascii = b'abc def'; +//Japanese string in UTF-8 +$string_mb = base64_decode(b'5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII='); + +echo "\n-- ASCII String --\n"; +var_dump(iconv_strlen($string_ascii)); + +echo "\n-- Multibyte String --\n"; +var_dump(iconv_strlen($string_mb, 'UTF-8')); +?> +===DONE=== +--EXPECTF-- +*** Testing iconv_strlen() : basic functionality*** + +-- ASCII String -- +int(7) + +-- Multibyte String -- +int(21) +===DONE=== diff --git a/ext/iconv/tests/iconv_strlen_error1.phpt b/ext/iconv/tests/iconv_strlen_error1.phpt new file mode 100644 index 0000000..3c63b20 --- /dev/null +++ b/ext/iconv/tests/iconv_strlen_error1.phpt @@ -0,0 +1,45 @@ +--TEST-- +Test iconv_strlen() function : error conditions - pass incorrect number of args +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strlen') or die("skip iconv_strlen() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strlen(string str [, string charset]) + * Description: Get character numbers of a string + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass iconv_strlen an incorrect number of arguments to test behaviour + */ + +echo "*** Testing iconv_strlen() : error conditions ***\n"; + +// Zero arguments +echo "\n-- Testing iconv_strlen() function with Zero arguments --\n"; +var_dump( iconv_strlen() ); + +//Test iconv_strlen with one more than the expected number of arguments +echo "\n-- Testing iconv_strlen() function with more than expected no. of arguments --\n"; +$str = 'string_val'; +$encoding = 'string_val'; +$extra_arg = 10; +var_dump( iconv_strlen($str, $encoding, $extra_arg) ); +?> +===DONE=== +--EXPECTF-- +*** Testing iconv_strlen() : error conditions *** + +-- Testing iconv_strlen() function with Zero arguments -- + +Warning: iconv_strlen() expects at least 1 parameter, 0 given in %s on line %d +bool(false) + +-- Testing iconv_strlen() function with more than expected no. of arguments -- + +Warning: iconv_strlen() expects at most 2 parameters, 3 given in %s on line %d +bool(false) +===DONE=== diff --git a/ext/iconv/tests/iconv_strlen_error2.phpt b/ext/iconv/tests/iconv_strlen_error2.phpt new file mode 100644 index 0000000..6c760b1 --- /dev/null +++ b/ext/iconv/tests/iconv_strlen_error2.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test iconv_strlen() function : error conditions - pass an unknown encoding +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strlen') or die("skip iconv_strlen() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strlen(string str [, string charset]) + * Description: Get character numbers of a string + * Source code: ext/iconv/iconv.c + */ + +/* + * Test iconv_strlen when passed an unknown encoding + */ + +echo "*** Testing iconv_strlen() : error ***\n"; + +$string = 'abcdef'; + +$encoding = 'unknown-encoding'; + +var_dump(iconv_strlen($string, $encoding)); + +?> +===DONE=== +--EXPECTF-- +*** Testing iconv_strlen() : error *** + +Notice: iconv_strlen(): Wrong charset, conversion from `unknown-encoding' to `UCS-4LE' is not allowed in %s on line %d +bool(false) +===DONE=== diff --git a/ext/iconv/tests/iconv_strlen_variation1.phpt b/ext/iconv/tests/iconv_strlen_variation1.phpt new file mode 100644 index 0000000..e3e25aa --- /dev/null +++ b/ext/iconv/tests/iconv_strlen_variation1.phpt @@ -0,0 +1,193 @@ +--TEST-- +Test iconv_strlen() function : usage variations - Pass different data types as $str arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strlen') or die("skip iconv_strlen() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strlen(string str [, string charset]) + * Description: Get character numbers of a string + * Source code: ext/iconv/iconv.c + */ + +/* + * Test iconv_strlen by passing different data types as $str argument + */ + +echo "*** Testing iconv_strlen() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$encoding = 'utf-8'; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $str argument +$inputs = array( + + // int data +/*1*/ + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -12345, + + // float data +/*5*/ + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 12.3456789000e10, + 'float 12.3456789000e-10' => 12.3456789000e-10, + 'float .5' => .5, + + // null data +/*10*/ + 'uppercase NULL' => NULL, + 'lowercase null' => null, + + // boolean data +/*12*/ + 'lowercase true' => true, + 'lowercase false' =>false, + 'uppercase TRUE' =>TRUE, + 'uppercase FALSE' =>FALSE, + + // empty data +/*16*/ + 'empty string DQ' => "", + 'empty string SQ' => '', + + // string data +/*18*/ + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + + // object data +/*21*/ + 'instance of class' => new classA(), + + // undefined data +/*22*/ + 'undefined var' => @$undefined_var, + + // unset data +/*23*/ + 'unset var' => @$unset_var, + + // resource variable +/*24*/ + 'resource' => $fp +); + +// loop through each element of $inputs to check the behavior of iconv_strlen() +$iterator = 1; +foreach($inputs as $key =>$value) { + echo "\n--$key--\n"; + var_dump( iconv_strlen($value, $encoding)); + $iterator++; +}; + +fclose($fp); +?> +===DONE=== +--EXPECTF-- +*** Testing iconv_strlen() : usage variations *** + +--int 0-- +int(1) + +--int 1-- +int(1) + +--int 12345-- +int(5) + +--int -12345-- +int(6) + +--float 10.5-- +int(4) + +--float -10.5-- +int(5) + +--float 12.3456789000e10-- +int(12) + +--float 12.3456789000e-10-- +int(13) + +--float .5-- +int(3) + +--uppercase NULL-- +int(0) + +--lowercase null-- +int(0) + +--lowercase true-- +int(1) + +--lowercase false-- +int(0) + +--uppercase TRUE-- +int(1) + +--uppercase FALSE-- +int(0) + +--empty string DQ-- +int(0) + +--empty string SQ-- +int(0) + +--string DQ-- +int(6) + +--string SQ-- +int(6) + +--mixed case string-- +int(6) + +--heredoc-- +int(11) + +--instance of class-- +int(14) + +--undefined var-- +int(0) + +--unset var-- +int(0) + +--resource-- + +Warning: iconv_strlen() expects parameter 1 to be string, resource given in %s on line %d +bool(false) +===DONE=== diff --git a/ext/iconv/tests/iconv_strlen_variation2.phpt b/ext/iconv/tests/iconv_strlen_variation2.phpt new file mode 100644 index 0000000..85dd048 --- /dev/null +++ b/ext/iconv/tests/iconv_strlen_variation2.phpt @@ -0,0 +1,204 @@ +--TEST-- +Test iconv_strlen() function : usage variations - Pass different data types as $encoding arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strlen') or die("skip iconv_strlen() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strlen(string str [, string charset]) + * Description: Get character numbers of a string + * Source code: ext/iconv/iconv.c + */ + +/* + * Test iconv_strlen() by passing different data types as $encoding argument. + * Where possible 'UTF-8' has been entered as a string value + */ + +echo "*** Testing iconv_strlen() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$str = 'string value'; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "UTF-8"; + } +} + +// heredoc string +$heredoc = <<<EOT +UTF-8 +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $input argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "UTF-8", + 'UTF-8', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_strlen() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_strlen($str, $input)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> + +--EXPECTF-- +*** Testing iconv_strlen() : usage variations *** + +-- Iteration 1 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `0' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 2 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `1' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 3 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `12345' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 4 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `-2345' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 5 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `10.5' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 6 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `-10.5' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 7 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `123456789000' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 8 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `1.23456789E-9' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 9 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `0.5' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 10 -- +int(12) + +-- Iteration 11 -- +int(12) + +-- Iteration 12 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `1' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 13 -- +int(12) + +-- Iteration 14 -- + +Notice: iconv_strlen(): Wrong charset, conversion from `1' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 15 -- +int(12) + +-- Iteration 16 -- +int(12) + +-- Iteration 17 -- +int(12) + +-- Iteration 18 -- +int(12) + +-- Iteration 19 -- +int(12) + +-- Iteration 20 -- +int(12) + +-- Iteration 21 -- +int(12) + +-- Iteration 22 -- +int(12) + +-- Iteration 23 -- +int(12) + +-- Iteration 24 -- + +Warning: iconv_strlen() expects parameter 2 to be string, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strpos-charset-length-cve-2007-4840.phpt b/ext/iconv/tests/iconv_strpos-charset-length-cve-2007-4840.phpt new file mode 100644 index 0000000..4cb858f --- /dev/null +++ b/ext/iconv/tests/iconv_strpos-charset-length-cve-2007-4840.phpt @@ -0,0 +1,13 @@ +--TEST-- +iconv_strpos() charset parameter length checks (CVE-2007-4840) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$a = str_repeat("/", 9000000); +var_dump(iconv_strpos("a", "b", 0, $a)); +?> +--EXPECTF-- + +Warning: iconv_strpos(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) diff --git a/ext/iconv/tests/iconv_strpos.phpt b/ext/iconv/tests/iconv_strpos.phpt new file mode 100644 index 0000000..6965f6f --- /dev/null +++ b/ext/iconv/tests/iconv_strpos.phpt @@ -0,0 +1,58 @@ +--TEST-- +iconv_strpos() +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--INI-- +iconv.internal_charset=ISO-8859-1 +--FILE-- +<?php +function my_error_handler($errno, $errmsg, $filename, $linenum, $vars) +{ + echo "$errno: $errmsg\n"; +} +set_error_handler('my_error_handler'); +function foo($haystk, $needle, $offset, $to_charset = false, $from_charset = false) +{ + if ($from_charset !== false) { + $haystk = iconv($from_charset, $to_charset, $haystk); + } + var_dump(strpos($haystk, $needle, $offset)); + if ($to_charset !== false) { + var_dump(iconv_strpos($haystk, $needle, $offset, $to_charset)); + } else { + var_dump(iconv_strpos($haystk, $needle, $offset)); + } +} +foo("abecdbcdabef", "bcd", -1); +foo("abecdbcdabef", "bcd", 100000); +foo("abcabcabcdabcababcdabc", "bcd", 0); +foo("abcabcabcdabcababcdabc", "bcd", 10); +foo(str_repeat("abcab", 60)."abcdb".str_repeat("adabc", 60), "abcd", 0); +foo(str_repeat("あいうえお", 30)."いうおえあ".str_repeat("あいえおう", 30), "うお", 0, "EUC-JP"); +$str = str_repeat("あいうえお", 60).'$'.str_repeat("あいえおう", 60); +foo($str, '$', 0, "ISO-2022-JP", "EUC-JP"); + +var_dump(iconv_strpos("string", "")); +var_dump(iconv_strpos("", "string")); + +?> +--EXPECTF-- +2: %s +bool(false) +2: %s +bool(false) +2: %s +bool(false) +bool(false) +int(7) +int(7) +int(16) +int(16) +int(300) +int(300) +int(302) +int(151) +int(1) +int(300) +bool(false) +bool(false) diff --git a/ext/iconv/tests/iconv_strpos_basic.phpt b/ext/iconv/tests/iconv_strpos_basic.phpt new file mode 100644 index 0000000..1604465 --- /dev/null +++ b/ext/iconv/tests/iconv_strpos_basic.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test iconv_strpos() function : basic functionality +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strpos') or die("skip iconv_strpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strpos(string haystack, string needle [, int offset [, string charset]]) + * Description: Find position of first occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Test basic functionality of iconv_strpos with ASCII and multibyte characters + */ + +echo "*** Testing iconv_strpos() : basic functionality***\n"; + +iconv_set_encoding("internal_encoding", "UTF-8"); + +$string_ascii = b'abc def'; +//Japanese string in UTF-8 +$string_mb = base64_decode(b'5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII='); + +echo "\n-- ASCII string 1 --\n"; +var_dump(iconv_strpos($string_ascii, b'd', 2, 'ISO-8859-1')); + +echo "\n-- ASCII string 2 --\n"; +var_dump(iconv_strpos($string_ascii, b'123')); + +echo "\n-- Multibyte string 1 --\n"; +$needle1 = base64_decode('5pel5pys6Kqe'); +var_dump(iconv_strpos($string_mb, $needle1)); + +echo "\n-- Multibyte string 2 --\n"; +$needle2 = base64_decode(b"44GT44KT44Gr44Gh44Gv44CB5LiW55WM"); +var_dump(iconv_strpos($string_mb, $needle2)); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_strpos() : basic functionality*** + +-- ASCII string 1 -- +int(4) + +-- ASCII string 2 -- +bool(false) + +-- Multibyte string 1 -- +int(0) + +-- Multibyte string 2 -- +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strpos_error1.phpt b/ext/iconv/tests/iconv_strpos_error1.phpt new file mode 100644 index 0000000..2324665 --- /dev/null +++ b/ext/iconv/tests/iconv_strpos_error1.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test iconv_strpos() function : error conditions - Pass incorrect number of args +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strpos') or die("skip iconv_strpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strpos(string haystack, string needle [, int offset [, string charset]]) + * Description: Find position of first occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Test how iconv_strpos behaves when passed an incorrect number of arguments + */ + +echo "*** Testing iconv_strpos() : error conditions ***\n"; + + +//Test iconv_strpos with one more than the expected number of arguments +echo "\n-- Testing iconv_strpos() function with more than expected no. of arguments --\n"; +$haystack = 'string_val'; +$needle = 'string_val'; +$offset = 10; +$encoding = 'string_val'; +$extra_arg = 10; +var_dump( iconv_strpos($haystack, $needle, $offset, $encoding, $extra_arg) ); + +// Testing iconv_strpos with one less than the expected number of arguments +echo "\n-- Testing iconv_strpos() function with less than expected no. of arguments --\n"; +$haystack = 'string_val'; +var_dump( iconv_strpos($haystack) ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_strpos() : error conditions *** + +-- Testing iconv_strpos() function with more than expected no. of arguments -- + +Warning: iconv_strpos() expects at most 4 parameters, 5 given in %s on line %d +bool(false) + +-- Testing iconv_strpos() function with less than expected no. of arguments -- + +Warning: iconv_strpos() expects at least 2 parameters, 1 given in %s on line %d +bool(false) +Done diff --git a/ext/iconv/tests/iconv_strpos_error2.phpt b/ext/iconv/tests/iconv_strpos_error2.phpt new file mode 100644 index 0000000..01e728a --- /dev/null +++ b/ext/iconv/tests/iconv_strpos_error2.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test iconv_strpos() function : error conditions - Pass unknown encoding +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strpos') or die("skip iconv_strpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strpos(string haystack, string needle [, int offset [, string charset]]) + * Description: Find position of first occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass an unknown encoding to iconv_strpos() to test behaviour + */ + +echo "*** Testing iconv_strpos() : error conditions ***\n"; +$haystack = 'Hello, world'; +$needle = 'world'; +$offset = 2; +$encoding = 'unknown-encoding'; + +var_dump( iconv_strpos($haystack, $needle, $offset, $encoding) ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_strpos() : error conditions *** + +Notice: iconv_strpos(): Wrong charset, conversion from `unknown-encoding' to `UCS-4LE' is not allowed in %s on line %d +bool(false) +Done diff --git a/ext/iconv/tests/iconv_strpos_variation1.phpt b/ext/iconv/tests/iconv_strpos_variation1.phpt new file mode 100644 index 0000000..38dc353 --- /dev/null +++ b/ext/iconv/tests/iconv_strpos_variation1.phpt @@ -0,0 +1,182 @@ +--TEST-- +Test iconv_strpos() function : usage variations - pass different data types to $haystack arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strpos') or die("skip iconv_strpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strpos(string haystack, string needle [, int offset [, string charset]]) + * Description: Find position of first occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass iconv_strpos different data types as $haystack arg to test behaviour + */ + +echo "*** Testing iconv_strpos() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$needle = 'string_val'; +$offset = 0; +$encoding = 'utf-8'; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $haystack argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "string", + 'string', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_strpos() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_strpos($input, $needle, $offset, $encoding)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_strpos() : usage variations *** + +-- Iteration 1 -- +bool(false) + +-- Iteration 2 -- +bool(false) + +-- Iteration 3 -- +bool(false) + +-- Iteration 4 -- +bool(false) + +-- Iteration 5 -- +bool(false) + +-- Iteration 6 -- +bool(false) + +-- Iteration 7 -- +bool(false) + +-- Iteration 8 -- +bool(false) + +-- Iteration 9 -- +bool(false) + +-- Iteration 10 -- +bool(false) + +-- Iteration 11 -- +bool(false) + +-- Iteration 12 -- +bool(false) + +-- Iteration 13 -- +bool(false) + +-- Iteration 14 -- +bool(false) + +-- Iteration 15 -- +bool(false) + +-- Iteration 16 -- +bool(false) + +-- Iteration 17 -- +bool(false) + +-- Iteration 18 -- +bool(false) + +-- Iteration 19 -- +bool(false) + +-- Iteration 20 -- +bool(false) + +-- Iteration 21 -- +bool(false) + +-- Iteration 22 -- +bool(false) + +-- Iteration 23 -- +bool(false) + +-- Iteration 24 -- + +Warning: iconv_strpos() expects parameter 1 to be string, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strpos_variation2.phpt b/ext/iconv/tests/iconv_strpos_variation2.phpt new file mode 100644 index 0000000..e702ca9 --- /dev/null +++ b/ext/iconv/tests/iconv_strpos_variation2.phpt @@ -0,0 +1,182 @@ +--TEST-- +Test iconv_strpos() function : usage variations - pass different data types as $needle arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strpos') or die("skip iconv_strpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strpos(string haystack, string needle [, int offset [, string charset]]) + * Description: Find position of first occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass iconv_strpos different data types as $needle arg to test behaviour + */ + +echo "*** Testing iconv_strpos() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$haystack = 'string_val'; +$offset = 0; +$encoding = 'utf-8'; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $needle argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "string", + 'string', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_strpos() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_strpos($haystack, $input, $offset, $encoding)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_strpos() : usage variations *** + +-- Iteration 1 -- +bool(false) + +-- Iteration 2 -- +bool(false) + +-- Iteration 3 -- +bool(false) + +-- Iteration 4 -- +bool(false) + +-- Iteration 5 -- +bool(false) + +-- Iteration 6 -- +bool(false) + +-- Iteration 7 -- +bool(false) + +-- Iteration 8 -- +bool(false) + +-- Iteration 9 -- +bool(false) + +-- Iteration 10 -- +bool(false) + +-- Iteration 11 -- +bool(false) + +-- Iteration 12 -- +bool(false) + +-- Iteration 13 -- +bool(false) + +-- Iteration 14 -- +bool(false) + +-- Iteration 15 -- +bool(false) + +-- Iteration 16 -- +bool(false) + +-- Iteration 17 -- +bool(false) + +-- Iteration 18 -- +int(0) + +-- Iteration 19 -- +int(0) + +-- Iteration 20 -- +bool(false) + +-- Iteration 21 -- +bool(false) + +-- Iteration 22 -- +bool(false) + +-- Iteration 23 -- +bool(false) + +-- Iteration 24 -- + +Warning: iconv_strpos() expects parameter 2 to be string, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strpos_variation3.phpt b/ext/iconv/tests/iconv_strpos_variation3.phpt new file mode 100644 index 0000000..3c333bf --- /dev/null +++ b/ext/iconv/tests/iconv_strpos_variation3.phpt @@ -0,0 +1,201 @@ +--TEST-- +Test iconv_strpos() function : usage variations - pass different data types as $offset arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strpos') or die("skip iconv_strpos() is not available in this build"); +if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strpos(string haystack, string needle [, int offset [, string charset]]) + * Description: Find position of first occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass iconv_strpos different data types as $offset arg to test behaviour + */ + +echo "*** Testing iconv_strpos() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$needle = b'a'; +$haystack = b'string_val'; +$encoding = 'utf-8'; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $offest argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "string", + 'string', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_strpos() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_strpos($haystack, $needle, $input, $encoding)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_strpos() : usage variations *** + +-- Iteration 1 -- +int(8) + +-- Iteration 2 -- +int(8) + +-- Iteration 3 -- +bool(false) + +-- Iteration 4 -- + +Warning: iconv_strpos(): Offset not contained in string. in %s on line %d +bool(false) + +-- Iteration 5 -- +bool(false) + +-- Iteration 6 -- + +Warning: iconv_strpos(): Offset not contained in string. in %s on line %d +bool(false) + +-- Iteration 7 -- + +Warning: iconv_strpos(): Offset not contained in string. in %s on line %d +bool(false) + +-- Iteration 8 -- +int(8) + +-- Iteration 9 -- +int(8) + +-- Iteration 10 -- +int(8) + +-- Iteration 11 -- +int(8) + +-- Iteration 12 -- +int(8) + +-- Iteration 13 -- +int(8) + +-- Iteration 14 -- +int(8) + +-- Iteration 15 -- +int(8) + +-- Iteration 16 -- + +Warning: iconv_strpos() expects parameter 3 to be long, string given in %s on line %d +bool(false) + +-- Iteration 17 -- + +Warning: iconv_strpos() expects parameter 3 to be long, string given in %s on line %d +bool(false) + +-- Iteration 18 -- + +Warning: iconv_strpos() expects parameter 3 to be long, string given in %s on line %d +bool(false) + +-- Iteration 19 -- + +Warning: iconv_strpos() expects parameter 3 to be long, string given in %s on line %d +bool(false) + +-- Iteration 20 -- + +Warning: iconv_strpos() expects parameter 3 to be long, string given in %s on line %d +bool(false) + +-- Iteration 21 -- + +Warning: iconv_strpos() expects parameter 3 to be long, object given in %s on line %d +bool(false) + +-- Iteration 22 -- +int(8) + +-- Iteration 23 -- +int(8) + +-- Iteration 24 -- + +Warning: iconv_strpos() expects parameter 3 to be long, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strpos_variation3_64bit.phpt b/ext/iconv/tests/iconv_strpos_variation3_64bit.phpt new file mode 100644 index 0000000..1cc8a84 --- /dev/null +++ b/ext/iconv/tests/iconv_strpos_variation3_64bit.phpt @@ -0,0 +1,199 @@ +--TEST-- +Test iconv_strpos() function : usage variations - pass different data types as $offset arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strpos') or die("skip iconv_strpos() is not available in this build"); +if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strpos(string haystack, string needle [, int offset [, string charset]]) + * Description: Find position of first occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass iconv_strpos different data types as $offset arg to test behaviour + */ + +echo "*** Testing iconv_strpos() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$needle = b'a'; +$haystack = b'string_val'; +$encoding = 'utf-8'; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "Class A object"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $offest argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "string", + 'string', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_strpos() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_strpos($haystack, $needle, $input, $encoding)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_strpos() : usage variations *** + +-- Iteration 1 -- +int(8) + +-- Iteration 2 -- +int(8) + +-- Iteration 3 -- +bool(false) + +-- Iteration 4 -- + +Warning: iconv_strpos(): Offset not contained in string. in %s on line %d +bool(false) + +-- Iteration 5 -- +bool(false) + +-- Iteration 6 -- + +Warning: iconv_strpos(): Offset not contained in string. in %s on line %d +bool(false) + +-- Iteration 7 -- +int(8) + +-- Iteration 8 -- +int(8) + +-- Iteration 9 -- +int(8) + +-- Iteration 10 -- +int(8) + +-- Iteration 11 -- +int(8) + +-- Iteration 12 -- +int(8) + +-- Iteration 13 -- +int(8) + +-- Iteration 14 -- +int(8) + +-- Iteration 15 -- +int(8) + +-- Iteration 16 -- + +Warning: iconv_strpos() expects parameter 3 to be long, string given in %s on line %d +bool(false) + +-- Iteration 17 -- + +Warning: iconv_strpos() expects parameter 3 to be long, string given in %s on line %d +bool(false) + +-- Iteration 18 -- + +Warning: iconv_strpos() expects parameter 3 to be long, string given in %s on line %d +bool(false) + +-- Iteration 19 -- + +Warning: iconv_strpos() expects parameter 3 to be long, string given in %s on line %d +bool(false) + +-- Iteration 20 -- + +Warning: iconv_strpos() expects parameter 3 to be long, string given in %s on line %d +bool(false) + +-- Iteration 21 -- + +Warning: iconv_strpos() expects parameter 3 to be long, object given in %s on line %d +bool(false) + +-- Iteration 22 -- +int(8) + +-- Iteration 23 -- +int(8) + +-- Iteration 24 -- + +Warning: iconv_strpos() expects parameter 3 to be long, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strpos_variation4.phpt b/ext/iconv/tests/iconv_strpos_variation4.phpt new file mode 100644 index 0000000..43ab3e5 --- /dev/null +++ b/ext/iconv/tests/iconv_strpos_variation4.phpt @@ -0,0 +1,207 @@ +--TEST-- +Test iconv_strpos() function : usage variations - pass different data types as $charset arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strpos') or die("skip iconv_strpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strpos(string haystack, string needle [, int offset [, string charset]]) + * Description: Find position of first occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + + +/* + * Pass iconv_strpos different data types as $encoding arg to test behaviour + * Where possible 'UTF-8' has been entered as a string value + */ + +echo "*** Testing iconv_strpos() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$haystack = b'string_val'; +$needle = b'val'; +$offset = 0; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "UTF-8"; + } +} + +// heredoc string +$heredoc = <<<EOT +UTF-8 +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $input argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "UTF-8", + 'UTF-8', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_strpos() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_strpos($haystack, $needle, $offset, $input)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> + +--EXPECTF-- +*** Testing iconv_strpos() : usage variations *** + +-- Iteration 1 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `0' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 2 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `1' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 3 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `12345' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 4 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `-2345' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 5 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `10.5' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 6 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `-10.5' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 7 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `123456789000' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 8 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `1.23456789E-9' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 9 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `0.5' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 10 -- +int(7) + +-- Iteration 11 -- +int(7) + +-- Iteration 12 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `1' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 13 -- +int(7) + +-- Iteration 14 -- + +Notice: iconv_strpos(): Wrong charset, conversion from `1' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 15 -- +int(7) + +-- Iteration 16 -- +int(7) + +-- Iteration 17 -- +int(7) + +-- Iteration 18 -- +int(7) + +-- Iteration 19 -- +int(7) + +-- Iteration 20 -- +int(7) + +-- Iteration 21 -- +int(7) + +-- Iteration 22 -- +int(7) + +-- Iteration 23 -- +int(7) + +-- Iteration 24 -- + +Warning: iconv_strpos() expects parameter 4 to be string, resource given in %s on line %d +bool(false) +Done diff --git a/ext/iconv/tests/iconv_strpos_variation5.phpt b/ext/iconv/tests/iconv_strpos_variation5.phpt new file mode 100644 index 0000000..57a7a90 --- /dev/null +++ b/ext/iconv/tests/iconv_strpos_variation5.phpt @@ -0,0 +1,101 @@ +--TEST-- +Test iconv_strpos() function : usage variations - Pass different integers as $offset argument +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strpos') or die("skip iconv_strpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : int iconv_strpos(string haystack, string needle [, int offset [, string charset]]) + * Description: Find position of first occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Test how iconv_strpos() behaves when passed different integers as $offset argument + * The character length of $string_ascii and $string_mb is the same, + * and the needle appears at the same positions in both strings + */ + +iconv_set_encoding("internal_encoding", "UTF-8"); + +echo "*** Testing iconv_strpos() : usage variations ***\n"; + +$string_ascii = b'+Is an English string'; //21 chars +$needle_ascii = b'g'; + +$string_mb = base64_decode(b'5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII='); //21 chars +$needle_mb = base64_decode(b'44CC'); + +/* + * Loop through integers as multiples of ten for $offset argument + * iconv_strpos should not be able to accept negative values as $offset. + * 60 is larger than *BYTE* count for $string_mb + */ +for ($i = -10; $i <= 60; $i += 10) { + echo "\n**-- Offset is: $i --**\n"; + echo "-- ASCII String --\n"; + var_dump(iconv_strpos($string_ascii, $needle_ascii, $i)); + echo "--Multibyte String --\n"; + var_dump(iconv_strpos($string_mb, $needle_mb, $i, 'UTF-8')); +} + +echo "Done"; +?> + +--EXPECTF-- +*** Testing iconv_strpos() : usage variations *** + +**-- Offset is: -10 --** +-- ASCII String -- + +Warning: iconv_strpos(): Offset not contained in string. in %s on line %d +bool(false) +--Multibyte String -- + +Warning: iconv_strpos(): Offset not contained in string. in %s on line %d +bool(false) + +**-- Offset is: 0 --** +-- ASCII String -- +int(9) +--Multibyte String -- +int(9) + +**-- Offset is: 10 --** +-- ASCII String -- +int(20) +--Multibyte String -- +int(20) + +**-- Offset is: 20 --** +-- ASCII String -- +int(20) +--Multibyte String -- +int(20) + +**-- Offset is: 30 --** +-- ASCII String -- +bool(false) +--Multibyte String -- +bool(false) + +**-- Offset is: 40 --** +-- ASCII String -- +bool(false) +--Multibyte String -- +bool(false) + +**-- Offset is: 50 --** +-- ASCII String -- +bool(false) +--Multibyte String -- +bool(false) + +**-- Offset is: 60 --** +-- ASCII String -- +bool(false) +--Multibyte String -- +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strrpos-charset-length-cve-2007-4840.phpt b/ext/iconv/tests/iconv_strrpos-charset-length-cve-2007-4840.phpt new file mode 100644 index 0000000..948cc67 --- /dev/null +++ b/ext/iconv/tests/iconv_strrpos-charset-length-cve-2007-4840.phpt @@ -0,0 +1,13 @@ +--TEST-- +iconv_strrpos() charset parameter length checks (CVE-2007-4840) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$a = str_repeat("/", 9000000); +var_dump(iconv_strrpos("a", "b", $a)); +?> +--EXPECTF-- + +Warning: iconv_strrpos(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) diff --git a/ext/iconv/tests/iconv_strrpos.phpt b/ext/iconv/tests/iconv_strrpos.phpt new file mode 100644 index 0000000..ee977f2 --- /dev/null +++ b/ext/iconv/tests/iconv_strrpos.phpt @@ -0,0 +1,62 @@ +--TEST-- +iconv_strrpos() +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--INI-- +iconv.internal_charset=ISO-8859-1 +--FILE-- +<?php +function my_error_handler($errno, $errmsg, $filename, $linenum, $vars) +{ + echo "$errno: $errmsg\n"; +} +set_error_handler('my_error_handler'); +function foo($haystk, $needle, $to_charset = false, $from_charset = false) +{ + if ($from_charset !== false) { + $haystk = iconv($from_charset, $to_charset, $haystk); + } + if ($to_charset !== false) { + var_dump(iconv_strlen($haystk, $to_charset)); + var_dump(iconv_strrpos($haystk, $needle, $to_charset)); + } else { + var_dump(iconv_strlen($haystk)); + var_dump(iconv_strrpos($haystk, $needle)); + } +} +foo("abecdbcdabcdef", "bcd"); +foo(str_repeat("abcab", 60)."abcdb".str_repeat("adabc", 60), "abcd"); +foo(str_repeat("あいうえお", 30)."いうおえあ".str_repeat("あいえおう", 30), "うお", "EUC-JP"); + +for ($i = 0; $i <=6; ++$i) { + $str = str_repeat("あいうえお", 60).str_repeat('$', $i).str_repeat("あいえおう", 60); + foo($str, '$', "ISO-2022-JP", "EUC-JP"); +} + +var_dump(iconv_strrpos("string", "")); +var_dump(iconv_strrpos("", "string")); + +?> +--EXPECT-- +int(14) +int(9) +int(605) +int(300) +int(305) +int(151) +int(600) +bool(false) +int(601) +int(300) +int(602) +int(301) +int(603) +int(302) +int(604) +int(303) +int(605) +int(304) +int(606) +int(305) +bool(false) +bool(false) diff --git a/ext/iconv/tests/iconv_strrpos_basic.phpt b/ext/iconv/tests/iconv_strrpos_basic.phpt new file mode 100644 index 0000000..e275681 --- /dev/null +++ b/ext/iconv/tests/iconv_strrpos_basic.phpt @@ -0,0 +1,58 @@ +--TEST-- +Test iconv_strrpos() function : basic functionality +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strrpos') or die("skip iconv_strrpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : proto int iconv_strrpos(string haystack, string needle [, string charset]) + * Description: Find position of last occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Test basic functionality of iconv_strrpos() + */ + +echo "*** Testing iconv_strrpos() : basic ***\n"; + +iconv_set_encoding("internal_encoding", "UTF-8"); + +$string_ascii = b'This is an English string. 0123456789.'; +//Japanese string in UTF-8 +$string_mb = base64_decode(b'5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII='); + +echo "\n-- ASCII string 1 --\n"; +var_dump(iconv_strrpos($string_ascii, b'is', 'ISO-8859-1')); + +echo "\n-- ASCII string 2 --\n"; +var_dump(iconv_strrpos($string_ascii, b'hello, world')); + +echo "\n-- Multibyte string 1 --\n"; +$needle1 = base64_decode(b'44CC'); +var_dump(iconv_strrpos($string_mb, $needle1)); + +echo "\n-- Multibyte string 2 --\n"; +$needle2 = base64_decode(b'44GT44KT44Gr44Gh44Gv44CB5LiW55WM'); +var_dump(iconv_strrpos($string_mb, $needle2)); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_strrpos() : basic *** + +-- ASCII string 1 -- +int(15) + +-- ASCII string 2 -- +bool(false) + +-- Multibyte string 1 -- +int(20) + +-- Multibyte string 2 -- +bool(false) +Done + diff --git a/ext/iconv/tests/iconv_strrpos_error1.phpt b/ext/iconv/tests/iconv_strrpos_error1.phpt new file mode 100644 index 0000000..9d185c7 --- /dev/null +++ b/ext/iconv/tests/iconv_strrpos_error1.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test iconv_strrpos() function : error conditions - pass incorrect number of args +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strrpos') or die("skip iconv_strrpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : proto int iconv_strrpos(string haystack, string needle [, string charset]) + * Description: Find position of last occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass iconv_strrpos() an incorrect number of arguments + */ + +echo "*** Testing iconv_strrpos() : error conditions ***\n"; + + +//Test iconv_strrpos with one more than the expected number of arguments +echo "\n-- Testing iconv_strrpos() function with more than expected no. of arguments --\n"; +$haystack = 'string_val'; +$needle = 'string_val'; +$encoding = 'string_val'; +$extra_arg = 10; +var_dump( iconv_strrpos($haystack, $needle, $encoding, $extra_arg) ); + +// Testing iconv_strrpos with one less than the expected number of arguments +echo "\n-- Testing iconv_strrpos() function with less than expected no. of arguments --\n"; +$haystack = 'string_val'; +var_dump( iconv_strrpos($haystack) ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_strrpos() : error conditions *** + +-- Testing iconv_strrpos() function with more than expected no. of arguments -- + +Warning: iconv_strrpos() expects at most 3 parameters, 4 given in %s on line %d +bool(false) + +-- Testing iconv_strrpos() function with less than expected no. of arguments -- + +Warning: iconv_strrpos() expects at least 2 parameters, 1 given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strrpos_error2.phpt b/ext/iconv/tests/iconv_strrpos_error2.phpt new file mode 100644 index 0000000..ea72322 --- /dev/null +++ b/ext/iconv/tests/iconv_strrpos_error2.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test iconv_strrpos() function : error conditions - pass an unknown encoding +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strrpos') or die("skip iconv_strrpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : proto int iconv_strrpos(string haystack, string needle [, string charset]) + * Description: Find position of last occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass iconv_strrpos() an encoding that doesn't exist + */ + +echo "*** Testing iconv_strrpos() : error conditions ***\n"; + +$haystack = 'This is an English string. 0123456789.'; +$needle = '123'; +$offset = 5; +$encoding = 'unknown-encoding'; + +var_dump(iconv_strrpos($haystack, $needle , $encoding)); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_strrpos() : error conditions *** + +Notice: iconv_strrpos(): Wrong charset, conversion from `unknown-encoding' to `UCS-4LE' is not allowed in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strrpos_variation1.phpt b/ext/iconv/tests/iconv_strrpos_variation1.phpt new file mode 100644 index 0000000..e4ed011 --- /dev/null +++ b/ext/iconv/tests/iconv_strrpos_variation1.phpt @@ -0,0 +1,180 @@ +--TEST-- +Test iconv_strrpos() function : usage variations - pass different data types to $haystack arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strrpos') or die("skip iconv_strrpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : proto int iconv_strrpos(string haystack, string needle [, string charset]) + * Description: Find position of last occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass iconv_strrpos() different data types as $haystack argument to test behaviour + */ + +echo "*** Testing iconv_strrpos() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$needle = 'world'; +$encoding = 'utf-8'; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "hello, world"; + } +} + +// heredoc string +$heredoc = <<<EOT +hello, world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $haystack argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "hello, world", + 'hello, world', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_strrpos() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_strrpos($input, $needle, $encoding)); + $iterator++; +}; + +echo "Done"; +?> + +--EXPECTF-- +*** Testing iconv_strrpos() : usage variations *** + +-- Iteration 1 -- +bool(false) + +-- Iteration 2 -- +bool(false) + +-- Iteration 3 -- +bool(false) + +-- Iteration 4 -- +bool(false) + +-- Iteration 5 -- +bool(false) + +-- Iteration 6 -- +bool(false) + +-- Iteration 7 -- +bool(false) + +-- Iteration 8 -- +bool(false) + +-- Iteration 9 -- +bool(false) + +-- Iteration 10 -- +bool(false) + +-- Iteration 11 -- +bool(false) + +-- Iteration 12 -- +bool(false) + +-- Iteration 13 -- +bool(false) + +-- Iteration 14 -- +bool(false) + +-- Iteration 15 -- +bool(false) + +-- Iteration 16 -- +bool(false) + +-- Iteration 17 -- +bool(false) + +-- Iteration 18 -- +int(7) + +-- Iteration 19 -- +int(7) + +-- Iteration 20 -- +int(7) + +-- Iteration 21 -- +int(7) + +-- Iteration 22 -- +bool(false) + +-- Iteration 23 -- +bool(false) + +-- Iteration 24 -- + +Warning: iconv_strrpos() expects parameter 1 to be string, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strrpos_variation2.phpt b/ext/iconv/tests/iconv_strrpos_variation2.phpt new file mode 100644 index 0000000..a0001f5 --- /dev/null +++ b/ext/iconv/tests/iconv_strrpos_variation2.phpt @@ -0,0 +1,182 @@ +--TEST-- +Test iconv_strrpos() function : usage variations - Pass different data types to $needle arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strrpos') or die("skip iconv_strrpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : proto int iconv_strrpos(string haystack, string needle [, string charset]) + * Description: Find position of last occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass iconv_strrpos() different data types as $needle argument to test behaviour + */ + +echo "*** Testing iconv_strrpos() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$haystack = 'hello, world'; +$encoding = 'utf-8'; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "world"; + } +} + +// heredoc string +$heredoc = <<<EOT +world +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $needle argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "world", + 'world', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_strrpos() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_strrpos($haystack, $input, $encoding)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> + +--EXPECTF-- +*** Testing iconv_strrpos() : usage variations *** + +-- Iteration 1 -- +bool(false) + +-- Iteration 2 -- +bool(false) + +-- Iteration 3 -- +bool(false) + +-- Iteration 4 -- +bool(false) + +-- Iteration 5 -- +bool(false) + +-- Iteration 6 -- +bool(false) + +-- Iteration 7 -- +bool(false) + +-- Iteration 8 -- +bool(false) + +-- Iteration 9 -- +bool(false) + +-- Iteration 10 -- +bool(false) + +-- Iteration 11 -- +bool(false) + +-- Iteration 12 -- +bool(false) + +-- Iteration 13 -- +bool(false) + +-- Iteration 14 -- +bool(false) + +-- Iteration 15 -- +bool(false) + +-- Iteration 16 -- +bool(false) + +-- Iteration 17 -- +bool(false) + +-- Iteration 18 -- +int(7) + +-- Iteration 19 -- +int(7) + +-- Iteration 20 -- +int(7) + +-- Iteration 21 -- +int(7) + +-- Iteration 22 -- +bool(false) + +-- Iteration 23 -- +bool(false) + +-- Iteration 24 -- + +Warning: iconv_strrpos() expects parameter 2 to be string, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_strrpos_variation3.phpt b/ext/iconv/tests/iconv_strrpos_variation3.phpt new file mode 100644 index 0000000..87a21bd --- /dev/null +++ b/ext/iconv/tests/iconv_strrpos_variation3.phpt @@ -0,0 +1,205 @@ +--TEST-- +Test iconv_strrpos() function : usage variations - pass different data types as $encoding arg +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_strrpos') or die("skip iconv_strrpos() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : proto int iconv_strrpos(string haystack, string needle [, string charset]) + * Description: Find position of last occurrence of a string within another + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass iconv_strrpos() different data types as $encoding argument to test behaviour + * Where possible 'UTF-8' has been entered as a string value + */ + +echo "*** Testing iconv_strrpos() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$haystack = b'hello, world'; +$needle = b'world'; + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// get a class +class classA +{ + public function __toString() { + return "UTF-8"; + } +} + +// heredoc string +$heredoc = <<<EOT +UTF-8 +EOT; + +// get a resource variable +$fp = fopen(__FILE__, "r"); + +// unexpected values to be passed to $encoding argument +$inputs = array( + + // int data +/*1*/ 0, + 1, + 12345, + -2345, + + // float data +/*5*/ 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5, + + // null data +/*10*/ NULL, + null, + + // boolean data +/*12*/ true, + false, + TRUE, + FALSE, + + // empty data +/*16*/ "", + '', + + // string data +/*18*/ "UTF-8", + 'UTF-8', + $heredoc, + + // object data +/*21*/ new classA(), + + // undefined data +/*22*/ @$undefined_var, + + // unset data +/*23*/ @$unset_var, + + // resource variable +/*24*/ $fp +); + +// loop through each element of $inputs to check the behavior of iconv_strrpos() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( iconv_strrpos($haystack, $needle, $input)); + $iterator++; +}; + +fclose($fp); + +echo "Done"; +?> + +--EXPECTF-- +*** Testing iconv_strrpos() : usage variations *** + +-- Iteration 1 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `0' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 2 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `1' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 3 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `12345' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 4 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `-2345' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 5 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `10.5' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 6 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `-10.5' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 7 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `123456789000' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 8 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `1.23456789E-9' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 9 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `0.5' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 10 -- +int(7) + +-- Iteration 11 -- +int(7) + +-- Iteration 12 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `1' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 13 -- +int(7) + +-- Iteration 14 -- + +Notice: iconv_strrpos(): Wrong charset, conversion from `1' to `UCS-4LE' is not allowed in %s on line %d +bool(false) + +-- Iteration 15 -- +int(7) + +-- Iteration 16 -- +int(7) + +-- Iteration 17 -- +int(7) + +-- Iteration 18 -- +int(7) + +-- Iteration 19 -- +int(7) + +-- Iteration 20 -- +int(7) + +-- Iteration 21 -- +int(7) + +-- Iteration 22 -- +int(7) + +-- Iteration 23 -- +int(7) + +-- Iteration 24 -- + +Warning: iconv_strrpos() expects parameter 3 to be string, resource given in %s on line %d +bool(false) +Done
\ No newline at end of file diff --git a/ext/iconv/tests/iconv_substr-charset-length-cve-2007-4783.phpt b/ext/iconv/tests/iconv_substr-charset-length-cve-2007-4783.phpt new file mode 100644 index 0000000..c27e60d --- /dev/null +++ b/ext/iconv/tests/iconv_substr-charset-length-cve-2007-4783.phpt @@ -0,0 +1,14 @@ +--TEST-- +iconv_substr() charset parameter length checks (CVE-2007-4783) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--FILE-- +<?php +$a = str_repeat('A', 99897); +$b = str_repeat('/', 2798349); +var_dump(iconv_substr($a, 0, 1, $b)); +?> +--EXPECTF-- + +Warning: iconv_substr(): Charset parameter exceeds the maximum allowed length of %d characters in %s on line %d +bool(false) diff --git a/ext/iconv/tests/iconv_substr.phpt b/ext/iconv/tests/iconv_substr.phpt new file mode 100644 index 0000000..6ca545b --- /dev/null +++ b/ext/iconv/tests/iconv_substr.phpt @@ -0,0 +1,59 @@ +--TEST-- +iconv_substr() +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--INI-- +iconv.internal_charset=ISO-8859-1 +--FILE-- +<?php +function hexdump($str) { + $len = strlen($str); + for ($i = 0; $i < $len; ++$i) { + printf("%02x", ord($str[$i])); + } + print "\n"; +} + +function foo($str, $offset, $len, $charset) { + hexdump(substr($str, $offset, $len)); + hexdump(iconv_substr($str, $offset, $len, $charset)); +} + +function bar($str, $offset, $len = false) { + if (is_bool($len)) { + var_dump(substr($str, $offset)); + var_dump(iconv_substr($str, $offset)); + } else { + var_dump(substr($str, $offset, $len)); + var_dump(iconv_substr($str, $offset, $len)); + } +} + +foo("abcdefghijklmnopqrstuvwxyz", 5, 7, "ASCII"); +foo("あいうえおかきくけこさしす", 5, 7, "EUC-JP"); +bar("This is a test", 100000); +bar("This is a test", 0, 100000); +bar("This is a test", -3); +bar("This is a test", 0, -9); +bar("This is a test", 0, -100000); +bar("This is a test", -9, -100000); +var_dump(iconv("ISO-2022-JP", "EUC-JP", iconv_substr(iconv("EUC-JP", "ISO-2022-JP", "こんにちは ISO-2022-JP"), 3, 8, "ISO-2022-JP"))); +?> +--EXPECT-- +666768696a6b6c +666768696a6b6c +a6a4a8a4aaa4ab +a4aba4ada4afa4b1a4b3a4b5a4b7 +bool(false) +bool(false) +string(14) "This is a test" +string(14) "This is a test" +string(3) "est" +string(3) "est" +string(5) "This " +string(5) "This " +bool(false) +bool(false) +bool(false) +bool(false) +string(10) "ちは ISO-2" diff --git a/ext/iconv/tests/iconv_substr_basic.phpt b/ext/iconv/tests/iconv_substr_basic.phpt new file mode 100644 index 0000000..0754fc8 --- /dev/null +++ b/ext/iconv/tests/iconv_substr_basic.phpt @@ -0,0 +1,59 @@ +--TEST-- +Test iconv_substr() function : basic functionality +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_substr') or die("skip iconv_substr() is not available in this build"); +?> +--INI-- +iconv.input_encoding=ISO-8859-1 +iconv.internal_encoding=ISO-8859-1 +iconv.output_encoding=ISO-8859-1 +--FILE-- +<?php +/* Prototype : string iconv_substr(string str, int offset, [int length, string charset]) + * Description: Returns part of a string + * Source code: ext/iconv/iconv.c + */ + +/* + * Test Basic Functionality of iconv_substr with ASCII characters and multibyte strings. + */ + +echo "*** Testing iconv_substr() : basic functionality ***\n"; + +$string_ascii = b'ABCDEF'; +//Japanese string in UTF-8 +$string_mb = base64_decode(b'5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII='); + +echo "\n-- ASCII string 1 --\n"; +var_dump(bin2hex(iconv_substr($string_ascii, 3))); + +echo "\n-- ASCII string 2 --\n"; +var_dump(bin2hex(iconv_substr($string_ascii, 3, 5, 'ISO-8859-1'))); + +echo "\n-- Multibyte string 1 --\n"; +$result_1 = iconv_substr($string_mb, 2, 7); +var_dump(bin2hex($result_1)); + +echo "\n-- Multibyte string 2 --\n"; +$result_2 = iconv_substr($string_mb, 2, 7, 'utf-8'); +var_dump(bin2hex($result_2)); + +echo "Done"; +?> +--EXPECT-- +*** Testing iconv_substr() : basic functionality *** + +-- ASCII string 1 -- +string(6) "444546" + +-- ASCII string 2 -- +string(6) "444546" + +-- Multibyte string 1 -- +string(14) "a5e69cace8aa9e" + +-- Multibyte string 2 -- +string(42) "e8aa9ee38386e382ade382b9e38388e381a7e38199" +Done diff --git a/ext/iconv/tests/iconv_substr_error1.phpt b/ext/iconv/tests/iconv_substr_error1.phpt new file mode 100644 index 0000000..7a30c7d --- /dev/null +++ b/ext/iconv/tests/iconv_substr_error1.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test iconv_substr() function : error conditions - Pass incorrect number of args +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_substr') or die("skip iconv_substr() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : string iconv_substr(string str, int offset, [int length, string charset]) + * Description: Returns part of a string + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass incorrect number of arguments to iconv_substr() to test behaviour + */ + +echo "*** Testing iconv_substr() : error conditions ***\n"; + +//Test iconv_substr with one more than the expected number of arguments +echo "\n-- Testing iconv_substr() function with more than expected no. of arguments --\n"; +$str = 'string_val'; +$start = 10; +$length = 10; +$encoding = 'string_val'; +$extra_arg = 10; +var_dump( iconv_substr($str, $start, $length, $encoding, $extra_arg) ); + +// Testing iconv_substr with one less than the expected number of arguments +echo "\n-- Testing iconv_substr() function with less than expected no. of arguments --\n"; +$str = 'string_val'; +var_dump( iconv_substr($str) ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_substr() : error conditions *** + +-- Testing iconv_substr() function with more than expected no. of arguments -- + +Warning: iconv_substr() expects at most 4 parameters, 5 given in %s on line %d +bool(false) + +-- Testing iconv_substr() function with less than expected no. of arguments -- + +Warning: iconv_substr() expects at least 2 parameters, 1 given in %s on line %d +bool(false) +Done + diff --git a/ext/iconv/tests/iconv_substr_error2.phpt b/ext/iconv/tests/iconv_substr_error2.phpt new file mode 100644 index 0000000..ac50813 --- /dev/null +++ b/ext/iconv/tests/iconv_substr_error2.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test iconv_substr() function : error conditions - Pass an unknown encoding +--SKIPIF-- +<?php +extension_loaded('iconv') or die('skip'); +function_exists('iconv_substr') or die("skip iconv_substr() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : string iconv_substr(string str, int offset, [int length, string charset]) + * Description: Returns part of a string + * Source code: ext/iconv/iconv.c + */ + +/* + * Pass an unknown encoding to iconv_substr() to test behaviour + */ + +echo "*** Testing iconv_substr() : error conditions ***\n"; + +$str = 'Hello, world'; +$start = 1; +$length = 5; +$encoding = 'unknown-encoding'; + +var_dump( iconv_substr($str, $start, $length, $encoding)); + +echo "Done"; +?> +--EXPECTF-- +*** Testing iconv_substr() : error conditions *** + +Notice: iconv_substr(): Wrong charset, conversion from `unknown-encoding' to `UCS-4LE' is not allowed in %s on line %d +bool(false) +Done + diff --git a/ext/iconv/tests/ob_iconv_handler-charset-length-cve-2007-4840.phpt b/ext/iconv/tests/ob_iconv_handler-charset-length-cve-2007-4840.phpt new file mode 100644 index 0000000..fd01d83 --- /dev/null +++ b/ext/iconv/tests/ob_iconv_handler-charset-length-cve-2007-4840.phpt @@ -0,0 +1,14 @@ +--TEST-- +ob_iconv_handler() charset parameter length checks (CVE-2007-4840) +--SKIPIF-- +<?php extension_loaded('iconv') or die('skip iconv extension is not available'); ?> +--INI-- +memory_limit=256M +--FILE-- +<?php +ini_set("iconv.output_encoding", str_repeat("a", 9000000)); +ob_start("ob_iconv_handler"); +print "done"; +?> +--EXPECT-- +done diff --git a/ext/iconv/tests/ob_iconv_handler.phpt b/ext/iconv/tests/ob_iconv_handler.phpt new file mode 100644 index 0000000..20f9169 --- /dev/null +++ b/ext/iconv/tests/ob_iconv_handler.phpt @@ -0,0 +1,17 @@ +--TEST-- +ob_iconv_handler() +--SKIPIF-- +<?php include('skipif.inc'); ?> +--INI-- +error_reporting=2039 +--FILE-- +<?php +/* include('test.inc'); */ +iconv_set_encoding('internal_encoding', 'EUC-JP'); +iconv_set_encoding('output_encoding', 'Shift_JIS'); +ob_start('ob_iconv_handler'); +print "あいうえお"; +ob_end_flush(); +?> +--EXPECT-- + diff --git a/ext/iconv/tests/skipif.inc b/ext/iconv/tests/skipif.inc new file mode 100644 index 0000000..70d0067 --- /dev/null +++ b/ext/iconv/tests/skipif.inc @@ -0,0 +1,5 @@ +<?php +if (!extension_loaded("iconv")) { + die("skip iconv extension not available\n"); +} +?> diff --git a/ext/iconv/tests/test.inc b/ext/iconv/tests/test.inc new file mode 100644 index 0000000..78f1804 --- /dev/null +++ b/ext/iconv/tests/test.inc @@ -0,0 +1,7 @@ +<?php +// Do not dl load extension +//if (!extension_loaded("iconv") && ini_get("enable_dl")) { +// $dlext = (substr(PHP_OS, 0, 3) == "WIN") ? ".dll" : ".so"; +// @dl("iconv$dlext"); +//} +?>
\ No newline at end of file diff --git a/ext/iconv/tests/translit-failure.phpt b/ext/iconv/tests/translit-failure.phpt new file mode 100644 index 0000000..d8b9fbf --- /dev/null +++ b/ext/iconv/tests/translit-failure.phpt @@ -0,0 +1,31 @@ +--TEST-- +Translit failure +--SKIPIF-- +<?php +include('skipif.inc'); +( ICONV_IMPL != "libiconv" ) and die("skip ICONV_IMPL != \"libiconv\""); +?> +--INI-- +error_reporting=2039 +--FILE-- +<?php +/* include('test.inc'); */ +// Should be ok. +// Content from file is from libiconv testkit. Tested both +// with a string as an implode, no difference. +// if at some point internal encoding changes, set correct one +// in INI section or use file 'TranslitFail1.ISO-8859-1'. + +set_time_limit(5); +/* + * The bug (fixed in libiconv 1.8) was confirmed that iconv goes into an + * infinite loop when ASCII//TRANSLIT is performed. We should stop it in + * some time. + */ + +$test = 'crit par %s.'; + +var_dump(iconv("ISO-8859-1", "ASCII//TRANSLIT", $test)); +?> +--EXPECT-- +string(14) "'Ecrit par %s." diff --git a/ext/iconv/tests/translit-utf8.phpt b/ext/iconv/tests/translit-utf8.phpt new file mode 100644 index 0000000..0151dc3 --- /dev/null +++ b/ext/iconv/tests/translit-utf8.phpt @@ -0,0 +1,27 @@ +--TEST-- +Translit UTF-8 quotes +--SKIPIF-- +<?php +include('skipif.inc'); +( ICONV_IMPL != "libiconv" ) and die("skip ICONV_IMPL != \"libiconv\""); +?> +--INI-- +error_reporting=2047 +--FILE-- +<?php // vim600: syn=php +/* include('test.inc'); */ +//error_reporting(E_ALL); +$utf = implode('', file(dirname(__FILE__).'/Quotes.UTF-8')); + +print(iconv("UTF-8", "ISO-8859-1//TRANSLIT", $utf)); +print(iconv("UTF-8", "ASCII//TRANSLIT", $utf)); +?> +--EXPECT-- +"Hello" +`Hello +"Hello" +`Hello +"Hello" +'Hello' +"Hello" +'Hello' |