Diff for /embedaddon/php/ext/mbstring/mbstring.c between versions 1.1.1.1 and 1.1.1.4

version 1.1.1.1, 2012/02/21 23:47:57 version 1.1.1.4, 2014/06/15 20:03:49
Line 2 Line 2
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | PHP Version 5                                                        |     | PHP Version 5                                                        |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
   | Copyright (c) 1997-2012 The PHP Group                                |   | Copyright (c) 1997-2014 The PHP Group                                |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | This source file is subject to version 3.01 of the PHP license,      |     | 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        |     | that is bundled with this package in the file LICENSE, and is        |
Line 62 Line 62
 #include "ext/standard/info.h"  #include "ext/standard/info.h"
   
 #include "libmbfl/mbfl/mbfl_allocators.h"  #include "libmbfl/mbfl/mbfl_allocators.h"
   #include "libmbfl/mbfl/mbfilter_pass.h"
   
 #include "php_variables.h"  #include "php_variables.h"
 #include "php_globals.h"  #include "php_globals.h"
Line 77 Line 78
 #include "php_mbregex.h"  #include "php_mbregex.h"
 #endif  #endif
   
 #ifdef ZEND_MULTIBYTE  
 #include "zend_multibyte.h"  #include "zend_multibyte.h"
 #endif /* ZEND_MULTIBYTE */  
   
 #if HAVE_ONIG  #if HAVE_ONIG
 #include "php_onig_compat.h"  #include "php_onig_compat.h"
Line 98  ZEND_DECLARE_MODULE_GLOBALS(mbstring) Line 97  ZEND_DECLARE_MODULE_GLOBALS(mbstring)
 static PHP_GINIT_FUNCTION(mbstring);  static PHP_GINIT_FUNCTION(mbstring);
 static PHP_GSHUTDOWN_FUNCTION(mbstring);  static PHP_GSHUTDOWN_FUNCTION(mbstring);
   
#ifdef ZEND_MULTIBYTEstatic void php_mb_populate_current_detect_order_list(TSRMLS_D);
static size_t php_mb_oddlen(const unsigned char *string, size_t length, const char *encoding TSRMLS_DC);
static int php_mb_encoding_converter(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length, const char *encoding_to, const char *encoding_from TSRMLS_DC);static int php_mb_encoding_translation(TSRMLS_D);
static char* php_mb_encoding_detector(const unsigned char *arg_string, size_t arg_length, char *arg_list TSRMLS_DC);
static int php_mb_set_zend_encoding(TSRMLS_D);static void php_mb_gpc_get_detect_order(const zend_encoding ***list, size_t *list_size TSRMLS_DC);
#endif
 static void php_mb_gpc_set_input_encoding(const zend_encoding *encoding TSRMLS_DC);
 
 /* }}} */  /* }}} */
   
 /* {{{ php_mb_default_identify_list */  /* {{{ php_mb_default_identify_list */
 typedef struct _php_mb_nls_ident_list {  typedef struct _php_mb_nls_ident_list {
         enum mbfl_no_language lang;          enum mbfl_no_language lang;
        const enum mbfl_no_encoding* list;        const enum mbfl_no_encoding *list;
        int list_size;        size_t list_size;
 } php_mb_nls_ident_list;  } php_mb_nls_ident_list;
   
 static const enum mbfl_no_encoding php_mb_default_identify_list_ja[] = {  static const enum mbfl_no_encoding php_mb_default_identify_list_ja[] = {
Line 411  ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_encode_numericentity Line 412  ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_encode_numericentity
         ZEND_ARG_INFO(0, string)          ZEND_ARG_INFO(0, string)
         ZEND_ARG_INFO(0, convmap)          ZEND_ARG_INFO(0, convmap)
         ZEND_ARG_INFO(0, encoding)          ZEND_ARG_INFO(0, encoding)
           ZEND_ARG_INFO(0, is_hex)
 ZEND_END_ARG_INFO()  ZEND_END_ARG_INFO()
   
 ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_decode_numericentity, 0, 0, 2)  ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_decode_numericentity, 0, 0, 2)
Line 465  ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_eregi_replace, 0, 0, Line 467  ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_eregi_replace, 0, 0,
         ZEND_ARG_INFO(0, string)          ZEND_ARG_INFO(0, string)
 ZEND_END_ARG_INFO()  ZEND_END_ARG_INFO()
   
   ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_replace_callback, 0, 0, 3)
           ZEND_ARG_INFO(0, pattern)
           ZEND_ARG_INFO(0, callback)
           ZEND_ARG_INFO(0, string)
           ZEND_ARG_INFO(0, option)
   ZEND_END_ARG_INFO()
    
 ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_split, 0, 0, 2)  ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_split, 0, 0, 2)
         ZEND_ARG_INFO(0, pattern)          ZEND_ARG_INFO(0, pattern)
         ZEND_ARG_INFO(0, string)          ZEND_ARG_INFO(0, string)
Line 563  const zend_function_entry mbstring_functions[] = { Line 572  const zend_function_entry mbstring_functions[] = {
   
 /* {{{ zend_module_entry mbstring_module_entry */  /* {{{ zend_module_entry mbstring_module_entry */
 zend_module_entry mbstring_module_entry = {  zend_module_entry mbstring_module_entry = {
    STANDARD_MODULE_HEADER,        STANDARD_MODULE_HEADER,
         "mbstring",          "mbstring",
         mbstring_functions,          mbstring_functions,
         PHP_MINIT(mbstring),          PHP_MINIT(mbstring),
Line 571  zend_module_entry mbstring_module_entry = { Line 580  zend_module_entry mbstring_module_entry = {
         PHP_RINIT(mbstring),          PHP_RINIT(mbstring),
         PHP_RSHUTDOWN(mbstring),          PHP_RSHUTDOWN(mbstring),
         PHP_MINFO(mbstring),          PHP_MINFO(mbstring),
    NO_VERSION_YET,        NO_VERSION_YET,
    PHP_MODULE_GLOBALS(mbstring),        PHP_MODULE_GLOBALS(mbstring),
    PHP_GINIT(mbstring),        PHP_GINIT(mbstring),
    PHP_GSHUTDOWN(mbstring),        PHP_GSHUTDOWN(mbstring),
    NULL,        NULL,
         STANDARD_MODULE_PROPERTIES_EX          STANDARD_MODULE_PROPERTIES_EX
 };  };
 /* }}} */  /* }}} */
Line 653  static sapi_post_entry mbstr_post_entries[] = { Line 662  static sapi_post_entry mbstr_post_entries[] = {
  *  of parsed encodings.   *  of parsed encodings.
  */   */
 static int  static int
php_mb_parse_encoding_list(const char *value, int value_length, enum mbfl_no_encoding **return_list, int *return_size, int persistent TSRMLS_DC)php_mb_parse_encoding_list(const char *value, size_t value_length, const mbfl_encoding ***return_list, size_t *return_size, int persistent TSRMLS_DC)
 {  {
        int n, l, size, bauto, ret = 1;        int size, bauto, ret = SUCCESS;
         size_t n;
         char *p, *p1, *p2, *endp, *tmpstr;          char *p, *p1, *p2, *endp, *tmpstr;
        enum mbfl_no_encoding no_encoding;        const mbfl_encoding **entry, **list;
        enum mbfl_no_encoding *src, *entry, *list; 
   
         list = NULL;          list = NULL;
         if (value == NULL || value_length <= 0) {          if (value == NULL || value_length <= 0) {
Line 668  php_mb_parse_encoding_list(const char *value, int valu Line 677  php_mb_parse_encoding_list(const char *value, int valu
                 if (return_size) {                  if (return_size) {
                         *return_size = 0;                          *return_size = 0;
                 }                  }
                return 0;                return FAILURE;
         } else {          } else {
                 enum mbfl_no_encoding *identify_list;  
                 int identify_list_size;  
   
                 identify_list = MBSTRG(default_detect_order_list);  
                 identify_list_size = MBSTRG(default_detect_order_list_size);  
   
                 /* copy the value string for work */                  /* copy the value string for work */
                 if (value[0]=='"' && value[value_length-1]=='"' && value_length>2) {                  if (value[0]=='"' && value[value_length-1]=='"' && value_length>2) {
                         tmpstr = (char *)estrndup(value+1, value_length-2);                          tmpstr = (char *)estrndup(value+1, value_length-2);
Line 684  php_mb_parse_encoding_list(const char *value, int valu Line 687  php_mb_parse_encoding_list(const char *value, int valu
                 else                  else
                         tmpstr = (char *)estrndup(value, value_length);                          tmpstr = (char *)estrndup(value, value_length);
                 if (tmpstr == NULL) {                  if (tmpstr == NULL) {
                        return 0;                        return FAILURE;
                 }                  }
                 /* count the number of listed encoding names */                  /* count the number of listed encoding names */
                 endp = tmpstr + value_length;                  endp = tmpstr + value_length;
Line 694  php_mb_parse_encoding_list(const char *value, int valu Line 697  php_mb_parse_encoding_list(const char *value, int valu
                         p1 = p2 + 1;                          p1 = p2 + 1;
                         n++;                          n++;
                 }                  }
                size = n + identify_list_size;                size = n + MBSTRG(default_detect_order_list_size);
                 /* make list */                  /* make list */
                list = (enum mbfl_no_encoding *)pecalloc(size, sizeof(int), persistent);                list = (const mbfl_encoding **)pecalloc(size, sizeof(mbfl_encoding*), persistent);
                 if (list != NULL) {                  if (list != NULL) {
                         entry = list;                          entry = list;
                         n = 0;                          n = 0;
Line 720  php_mb_parse_encoding_list(const char *value, int valu Line 723  php_mb_parse_encoding_list(const char *value, int valu
                                 /* convert to the encoding number and check encoding */                                  /* convert to the encoding number and check encoding */
                                 if (strcasecmp(p1, "auto") == 0) {                                  if (strcasecmp(p1, "auto") == 0) {
                                         if (!bauto) {                                          if (!bauto) {
                                                   const enum mbfl_no_encoding *src = MBSTRG(default_detect_order_list);
                                                   const size_t identify_list_size = MBSTRG(default_detect_order_list_size);
                                                   size_t i;
                                                 bauto = 1;                                                  bauto = 1;
                                                l = identify_list_size;                                                for (i = 0; i < identify_list_size; i++) {
                                                src = identify_list;                                                        *entry++ = mbfl_no2encoding(*src++);
                                                while (l > 0) { 
                                                        *entry++ = *src++; 
                                                        l--; 
                                                         n++;                                                          n++;
                                                 }                                                  }
                                         }                                          }
                                 } else {                                  } else {
                                        no_encoding = mbfl_name2no_encoding(p1);                                        const mbfl_encoding *encoding = mbfl_name2encoding(p1);
                                        if (no_encoding != mbfl_no_encoding_invalid) {                                        if (encoding) {
                                                *entry++ = no_encoding;                                                *entry++ = encoding;
                                                 n++;                                                  n++;
                                         } else {                                          } else {
                                                 ret = 0;                                                  ret = 0;
Line 772  php_mb_parse_encoding_list(const char *value, int valu Line 775  php_mb_parse_encoding_list(const char *value, int valu
 }  }
 /* }}} */  /* }}} */
   
 /* {{{ MBSTRING_API php_mb_check_encoding_list */  
 MBSTRING_API int php_mb_check_encoding_list(const char *encoding_list TSRMLS_DC) {  
         return php_mb_parse_encoding_list(encoding_list, strlen(encoding_list), NULL, NULL, 0 TSRMLS_CC);         
 }  
 /* }}} */  
   
 /* {{{ static int php_mb_parse_encoding_array()  /* {{{ static int php_mb_parse_encoding_array()
  *  Return 0 if input contains any illegal encoding, otherwise 1.   *  Return 0 if input contains any illegal encoding, otherwise 1.
  *  Even if any illegal encoding is detected the result may contain a list    *  Even if any illegal encoding is detected the result may contain a list 
  *  of parsed encodings.   *  of parsed encodings.
  */   */
 static int  static int
php_mb_parse_encoding_array(zval *array, enum mbfl_no_encoding **return_list, int *return_size, int persistent TSRMLS_DC)php_mb_parse_encoding_array(zval *array, const mbfl_encoding ***return_list, size_t *return_size, int persistent TSRMLS_DC)
 {  {
         zval **hash_entry;          zval **hash_entry;
         HashTable *target_hash;          HashTable *target_hash;
        int i, n, l, size, bauto,ret = 1;        int i, n, size, bauto, ret = SUCCESS;
        enum mbfl_no_encoding no_encoding;        const mbfl_encoding **list, **entry;
        enum mbfl_no_encoding *src, *list, *entry; 
   
         list = NULL;          list = NULL;
         if (Z_TYPE_P(array) == IS_ARRAY) {          if (Z_TYPE_P(array) == IS_ARRAY) {
                 enum mbfl_no_encoding *identify_list;  
                 int identify_list_size;  
   
                 identify_list = MBSTRG(default_detect_order_list);  
                 identify_list_size = MBSTRG(default_detect_order_list_size);  
   
                 target_hash = Z_ARRVAL_P(array);                  target_hash = Z_ARRVAL_P(array);
                 zend_hash_internal_pointer_reset(target_hash);                  zend_hash_internal_pointer_reset(target_hash);
                 i = zend_hash_num_elements(target_hash);                  i = zend_hash_num_elements(target_hash);
                size = i + identify_list_size;                size = i + MBSTRG(default_detect_order_list_size);
                list = (enum mbfl_no_encoding *)pecalloc(size, sizeof(int), persistent);                list = (const mbfl_encoding **)pecalloc(size, sizeof(mbfl_encoding*), persistent);
                 if (list != NULL) {                  if (list != NULL) {
                         entry = list;                          entry = list;
                         bauto = 0;                          bauto = 0;
Line 816  php_mb_parse_encoding_array(zval *array, enum mbfl_no_ Line 806  php_mb_parse_encoding_array(zval *array, enum mbfl_no_
                                 convert_to_string_ex(hash_entry);                                  convert_to_string_ex(hash_entry);
                                 if (strcasecmp(Z_STRVAL_PP(hash_entry), "auto") == 0) {                                  if (strcasecmp(Z_STRVAL_PP(hash_entry), "auto") == 0) {
                                         if (!bauto) {                                          if (!bauto) {
                                                   const enum mbfl_no_encoding *src = MBSTRG(default_detect_order_list);
                                                   const size_t identify_list_size = MBSTRG(default_detect_order_list_size);
                                                   size_t j;
   
                                                 bauto = 1;                                                  bauto = 1;
                                                l = identify_list_size;                                                 for (j = 0; j < identify_list_size; j++) {
                                                src = identify_list;                                                        *entry++ = mbfl_no2encoding(*src++);
                                                while (l > 0) { 
                                                        *entry++ = *src++; 
                                                        l--; 
                                                         n++;                                                          n++;
                                                 }                                                  }
                                         }                                          }
                                 } else {                                  } else {
                                        no_encoding = mbfl_name2no_encoding(Z_STRVAL_PP(hash_entry));                                        const mbfl_encoding *encoding = mbfl_name2encoding(Z_STRVAL_PP(hash_entry));
                                        if (no_encoding != mbfl_no_encoding_invalid) {                                        if (encoding) {
                                                *entry++ = no_encoding;                                                *entry++ = encoding;
                                                 n++;                                                  n++;
                                         } else {                                          } else {
                                                ret = 0;                                                ret = FAILURE;
                                         }                                          }
                                 }                                  }
                                 zend_hash_move_forward(target_hash);                                  zend_hash_move_forward(target_hash);
Line 848  php_mb_parse_encoding_array(zval *array, enum mbfl_no_ Line 839  php_mb_parse_encoding_array(zval *array, enum mbfl_no_
                                 if (return_list) {                                  if (return_list) {
                                         *return_list = NULL;                                          *return_list = NULL;
                                 }                                  }
                                ret = 0;                                ret = FAILURE;
                         }                          }
                         if (return_size) {                          if (return_size) {
                                 *return_size = n;                                  *return_size = n;
Line 860  php_mb_parse_encoding_array(zval *array, enum mbfl_no_ Line 851  php_mb_parse_encoding_array(zval *array, enum mbfl_no_
                         if (return_size) {                          if (return_size) {
                                 *return_size = 0;                                  *return_size = 0;
                         }                          }
                        ret = 0;                        ret = FAILURE;
                 }                  }
         }          }
   
Line 868  php_mb_parse_encoding_array(zval *array, enum mbfl_no_ Line 859  php_mb_parse_encoding_array(zval *array, enum mbfl_no_
 }  }
 /* }}} */  /* }}} */
   
   /* {{{ zend_multibyte interface */
   static const zend_encoding* php_mb_zend_encoding_fetcher(const char *encoding_name TSRMLS_DC)
   {
           return (const zend_encoding*)mbfl_name2encoding(encoding_name);
   }
   
   static const char *php_mb_zend_encoding_name_getter(const zend_encoding *encoding)
   {
           return ((const mbfl_encoding *)encoding)->name;
   }
   
   static int php_mb_zend_encoding_lexer_compatibility_checker(const zend_encoding *_encoding)
   {
           const mbfl_encoding *encoding = (const mbfl_encoding*)_encoding;
           if (encoding->flag & MBFL_ENCTYPE_SBCS) {
                   return 1;
           }
           if ((encoding->flag & (MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE)) == MBFL_ENCTYPE_MBCS) {
                   return 1;
           }
           return 0;
   }
   
   static const zend_encoding *php_mb_zend_encoding_detector(const unsigned char *arg_string, size_t arg_length, const zend_encoding **list, size_t list_size TSRMLS_DC)
   {
           mbfl_string string;
   
           if (!list) {
                   list = (const zend_encoding **)MBSTRG(current_detect_order_list);
                   list_size = MBSTRG(current_detect_order_list_size);
           }
   
           mbfl_string_init(&string);
           string.no_language = MBSTRG(language);
           string.val = (unsigned char *)arg_string;
           string.len = arg_length;
           return (const zend_encoding *) mbfl_identify_encoding2(&string, (const mbfl_encoding **)list, list_size, 0);
   }
   
   static size_t php_mb_zend_encoding_converter(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length, const zend_encoding *encoding_to, const zend_encoding *encoding_from TSRMLS_DC)
   {
           mbfl_string string, result;
           mbfl_buffer_converter *convd;
           int status, loc;
   
           /* new encoding */
           /* initialize string */
           mbfl_string_init(&string);
           mbfl_string_init(&result);
           string.no_encoding = ((const mbfl_encoding*)encoding_from)->no_encoding;
           string.no_language = MBSTRG(language);
           string.val = (unsigned char*)from;
           string.len = from_length;
   
           /* initialize converter */
           convd = mbfl_buffer_converter_new2((const mbfl_encoding *)encoding_from, (const mbfl_encoding *)encoding_to, string.len);
           if (convd == NULL) {
                   return -1;
           }
           mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode));
           mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));
   
           /* do it */
           status = mbfl_buffer_converter_feed2(convd, &string, &loc);
           if (status) {
                   mbfl_buffer_converter_delete(convd);
                   return (size_t)-1;
           }
   
           mbfl_buffer_converter_flush(convd);
           if (!mbfl_buffer_converter_result(convd, &result)) {
                   mbfl_buffer_converter_delete(convd);
                   return (size_t)-1;
           }       
   
           *to = result.val;
           *to_length = result.len;
   
           mbfl_buffer_converter_delete(convd);
   
           return loc;
   }
   
   static int php_mb_zend_encoding_list_parser(const char *encoding_list, size_t encoding_list_len, const zend_encoding ***return_list, size_t *return_size, int persistent TSRMLS_DC)
   {
           return php_mb_parse_encoding_list(encoding_list, encoding_list_len, (const mbfl_encoding ***)return_list, return_size, persistent TSRMLS_CC);
   }
   
   static const zend_encoding *php_mb_zend_internal_encoding_getter(TSRMLS_D)
   {
           return (const zend_encoding *)MBSTRG(internal_encoding);
   }
   
   static int php_mb_zend_internal_encoding_setter(const zend_encoding *encoding TSRMLS_DC)
   {
           MBSTRG(internal_encoding) = (const mbfl_encoding *)encoding;
           return SUCCESS;
   }
   
   static zend_multibyte_functions php_mb_zend_multibyte_functions = {
           "mbstring",
           php_mb_zend_encoding_fetcher,
           php_mb_zend_encoding_name_getter,
           php_mb_zend_encoding_lexer_compatibility_checker,
           php_mb_zend_encoding_detector,
           php_mb_zend_encoding_converter,
           php_mb_zend_encoding_list_parser,
           php_mb_zend_internal_encoding_getter,
           php_mb_zend_internal_encoding_setter
   };
   /* }}} */
   
 static void *_php_mb_compile_regex(const char *pattern TSRMLS_DC);  static void *_php_mb_compile_regex(const char *pattern TSRMLS_DC);
 static int _php_mb_match_regex(void *opaque, const char *str, size_t str_len);  static int _php_mb_match_regex(void *opaque, const char *str, size_t str_len);
 static void _php_mb_free_regex(void *opaque);  static void _php_mb_free_regex(void *opaque);
Line 942  static void _php_mb_free_regex(void *opaque) Line 1045  static void _php_mb_free_regex(void *opaque)
 #endif  #endif
   
 /* {{{ php_mb_nls_get_default_detect_order_list */  /* {{{ php_mb_nls_get_default_detect_order_list */
static int php_mb_nls_get_default_detect_order_list(enum mbfl_no_language lang, enum mbfl_no_encoding **plist, int* plist_size)static int php_mb_nls_get_default_detect_order_list(enum mbfl_no_language lang, enum mbfl_no_encoding **plist, size_t *plist_size)
 {  {
         size_t i;          size_t i;
   
Line 960  static int php_mb_nls_get_default_detect_order_list(en Line 1063  static int php_mb_nls_get_default_detect_order_list(en
 }  }
 /* }}} */  /* }}} */
   
   static char *php_mb_rfc1867_substring_conf(const zend_encoding *encoding, char *start, int len, char quote TSRMLS_DC)
   {
           char *result = emalloc(len + 2);
           char *resp = result;
           int i;
   
           for (i = 0; i < len && start[i] != quote; ++i) {
                   if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) {
                           *resp++ = start[++i];
                   } else {
                           size_t j = php_mb_mbchar_bytes_ex(start+i, (const mbfl_encoding *)encoding);
   
                           while (j-- > 0 && i < len) {
                                   *resp++ = start[i++];
                           }
                           --i;
                   }
           }
   
           *resp = '\0';
           return result;
   }
   
   static char *php_mb_rfc1867_getword(const zend_encoding *encoding, char **line, char stop TSRMLS_DC) /* {{{ */
   {
           char *pos = *line, quote;
           char *res;
   
           while (*pos && *pos != stop) {
                   if ((quote = *pos) == '"' || quote == '\'') {
                           ++pos;
                           while (*pos && *pos != quote) {
                                   if (*pos == '\\' && pos[1] && pos[1] == quote) {
                                           pos += 2;
                                   } else {
                                           ++pos;
                                   }
                           }
                           if (*pos) {
                                   ++pos;
                           }
                   } else {
                           pos += php_mb_mbchar_bytes_ex(pos, (const mbfl_encoding *)encoding);
   
                   }
           }
           if (*pos == '\0') {
                   res = estrdup(*line);
                   *line += strlen(*line);
                   return res;
           }
   
           res = estrndup(*line, pos - *line);
   
           while (*pos == stop) {
                   pos += php_mb_mbchar_bytes_ex(pos, (const mbfl_encoding *)encoding);
           }
   
           *line = pos;
           return res;
   }
   /* }}} */
   
   static char *php_mb_rfc1867_getword_conf(const zend_encoding *encoding, char *str TSRMLS_DC) /* {{{ */
   {
           while (*str && isspace(*(unsigned char *)str)) {
                   ++str;
           }
   
           if (!*str) {
                   return estrdup("");
           }
   
           if (*str == '"' || *str == '\'') {
                   char quote = *str;
   
                   str++;
                   return php_mb_rfc1867_substring_conf(encoding, str, strlen(str), quote TSRMLS_CC);
           } else {
                   char *strend = str;
   
                   while (*strend && !isspace(*(unsigned char *)strend)) {
                           ++strend;
                   }
                   return php_mb_rfc1867_substring_conf(encoding, str, strend - str, 0 TSRMLS_CC);
           }
   }
   /* }}} */
   
   static char *php_mb_rfc1867_basename(const zend_encoding *encoding, char *filename TSRMLS_DC) /* {{{ */
   {
           char *s, *s2;
           const size_t filename_len = strlen(filename);
   
           /* The \ check should technically be needed for win32 systems only where
            * it is a valid path separator. However, IE in all it's wisdom always sends
            * the full path of the file on the user's filesystem, which means that unless
            * the user does basename() they get a bogus file name. Until IE's user base drops
            * to nill or problem is fixed this code must remain enabled for all systems. */
           s = php_mb_safe_strrchr_ex(filename, '\\', filename_len, (const mbfl_encoding *)encoding);
           s2 = php_mb_safe_strrchr_ex(filename, '/', filename_len, (const mbfl_encoding *)encoding);
           
           if (s && s2) {
                   if (s > s2) {
                           return ++s;
                   } else {
                           return ++s2;
                   }
           } else if (s) {
                   return ++s;
           } else if (s2) {
                   return ++s2;
           } else {
                   return filename;
           }
   }
   /* }}} */
   
 /* {{{ php.ini directive handler */  /* {{{ php.ini directive handler */
 /* {{{ static PHP_INI_MH(OnUpdate_mbstring_language) */  /* {{{ static PHP_INI_MH(OnUpdate_mbstring_language) */
 static PHP_INI_MH(OnUpdate_mbstring_language)  static PHP_INI_MH(OnUpdate_mbstring_language)
Line 980  static PHP_INI_MH(OnUpdate_mbstring_language) Line 1201  static PHP_INI_MH(OnUpdate_mbstring_language)
 /* {{{ static PHP_INI_MH(OnUpdate_mbstring_detect_order) */  /* {{{ static PHP_INI_MH(OnUpdate_mbstring_detect_order) */
 static PHP_INI_MH(OnUpdate_mbstring_detect_order)  static PHP_INI_MH(OnUpdate_mbstring_detect_order)
 {  {
        enum mbfl_no_encoding *list;        const mbfl_encoding **list;
        int size;        size_t size;
   
        if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {        if (!new_value) {
                 if (MBSTRG(detect_order_list)) {                  if (MBSTRG(detect_order_list)) {
                        free(MBSTRG(detect_order_list));                        pefree(MBSTRG(detect_order_list), 1);
                 }                  }
                MBSTRG(detect_order_list) = list;                MBSTRG(detect_order_list) = NULL;
                MBSTRG(detect_order_list_size) = size;                MBSTRG(detect_order_list_size) = 0;
        } else {                return SUCCESS;
                if (MBSTRG(detect_order_list)) {        }
                        free(MBSTRG(detect_order_list));
                        MBSTRG(detect_order_list) = NULL;        if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {
                } 
                 return FAILURE;                  return FAILURE;
         }          }
   
           if (MBSTRG(detect_order_list)) {
                   pefree(MBSTRG(detect_order_list), 1);
           }
           MBSTRG(detect_order_list) = list;
           MBSTRG(detect_order_list_size) = size;
         return SUCCESS;          return SUCCESS;
 }  }
 /* }}} */  /* }}} */
Line 1004  static PHP_INI_MH(OnUpdate_mbstring_detect_order) Line 1229  static PHP_INI_MH(OnUpdate_mbstring_detect_order)
 /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_input) */  /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_input) */
 static PHP_INI_MH(OnUpdate_mbstring_http_input)  static PHP_INI_MH(OnUpdate_mbstring_http_input)
 {  {
        enum mbfl_no_encoding *list;        const mbfl_encoding **list;
        int size;        size_t size;
   
        if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {        if (!new_value) {
                 if (MBSTRG(http_input_list)) {                  if (MBSTRG(http_input_list)) {
                        free(MBSTRG(http_input_list));                        pefree(MBSTRG(http_input_list), 1);
                 }                  }
                MBSTRG(http_input_list) = list;                MBSTRG(http_input_list) = NULL;
                MBSTRG(http_input_list_size) = size; 
        } else { 
                if (MBSTRG(http_input_list)) { 
                        free(MBSTRG(http_input_list)); 
                        MBSTRG(http_input_list) = NULL; 
                } 
                 MBSTRG(http_input_list_size) = 0;                  MBSTRG(http_input_list_size) = 0;
                   return SUCCESS;
           }
   
           if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {
                 return FAILURE;                  return FAILURE;
         }          }
   
           if (MBSTRG(http_input_list)) {
                   pefree(MBSTRG(http_input_list), 1);
           }
           MBSTRG(http_input_list) = list;
           MBSTRG(http_input_list_size) = size;
   
         return SUCCESS;          return SUCCESS;
 }  }
 /* }}} */  /* }}} */
Line 1029  static PHP_INI_MH(OnUpdate_mbstring_http_input) Line 1258  static PHP_INI_MH(OnUpdate_mbstring_http_input)
 /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_output) */  /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_output) */
 static PHP_INI_MH(OnUpdate_mbstring_http_output)  static PHP_INI_MH(OnUpdate_mbstring_http_output)
 {  {
        enum mbfl_no_encoding no_encoding;        const mbfl_encoding *encoding;
   
        no_encoding = mbfl_name2no_encoding(new_value);        if (new_value == NULL || new_value_length == 0) {
        if (no_encoding != mbfl_no_encoding_invalid) {                MBSTRG(http_output_encoding) = &mbfl_encoding_pass;
                MBSTRG(http_output_encoding) = no_encoding;                MBSTRG(current_http_output_encoding) = &mbfl_encoding_pass;
                MBSTRG(current_http_output_encoding) = no_encoding;                return SUCCESS;
        } else { 
                MBSTRG(http_output_encoding) = mbfl_no_encoding_pass; 
                MBSTRG(current_http_output_encoding) = mbfl_no_encoding_pass; 
                if (new_value != NULL && new_value_length > 0) { 
                        return FAILURE; 
                } 
         }          }
   
           encoding = mbfl_name2encoding(new_value);
           if (!encoding) {
                   MBSTRG(http_output_encoding) = &mbfl_encoding_pass;
                   MBSTRG(current_http_output_encoding) = &mbfl_encoding_pass;
                   return FAILURE;
           }
   
           MBSTRG(http_output_encoding) = encoding;
           MBSTRG(current_http_output_encoding) = encoding;
         return SUCCESS;          return SUCCESS;
 }  }
 /* }}} */  /* }}} */
Line 1050  static PHP_INI_MH(OnUpdate_mbstring_http_output) Line 1282  static PHP_INI_MH(OnUpdate_mbstring_http_output)
 /* {{{ static _php_mb_ini_mbstring_internal_encoding_set */  /* {{{ static _php_mb_ini_mbstring_internal_encoding_set */
 int _php_mb_ini_mbstring_internal_encoding_set(const char *new_value, uint new_value_length TSRMLS_DC)  int _php_mb_ini_mbstring_internal_encoding_set(const char *new_value, uint new_value_length TSRMLS_DC)
 {  {
        enum mbfl_no_encoding no_encoding;        const mbfl_encoding *encoding;
        const char *enc_name = NULL;
        uint enc_name_len = 0;        if (!new_value || new_value_length == 0 || !(encoding = mbfl_name2encoding(new_value))) {
    
        no_encoding = new_value ? mbfl_name2no_encoding(new_value): 
                                mbfl_no_encoding_invalid; 
        if (no_encoding != mbfl_no_encoding_invalid) { 
                enc_name = new_value; 
                enc_name_len = new_value_length; 
        } else { 
                 switch (MBSTRG(language)) {                  switch (MBSTRG(language)) {
                         case mbfl_no_language_uni:                          case mbfl_no_language_uni:
                                enc_name = "UTF-8";                                encoding = mbfl_no2encoding(mbfl_no_encoding_utf8);
                                enc_name_len = sizeof("UTF-8") - 1; 
                                 break;                                  break;
                         case mbfl_no_language_japanese:                          case mbfl_no_language_japanese:
                                enc_name = "EUC-JP";                                encoding = mbfl_no2encoding(mbfl_no_encoding_euc_jp);
                                enc_name_len = sizeof("EUC-JP") - 1; 
                                 break;                                  break;
                         case mbfl_no_language_korean:                          case mbfl_no_language_korean:
                                enc_name = "EUC-KR";                                encoding = mbfl_no2encoding(mbfl_no_encoding_euc_kr);
                                enc_name_len = sizeof("EUC-KR") - 1; 
                                 break;                                  break;
                         case mbfl_no_language_simplified_chinese:                          case mbfl_no_language_simplified_chinese:
                                enc_name = "EUC-CN";                                encoding = mbfl_no2encoding(mbfl_no_encoding_euc_cn);
                                enc_name_len = sizeof("EUC-CN") - 1; 
                                 break;                                  break;
                         case mbfl_no_language_traditional_chinese:                          case mbfl_no_language_traditional_chinese:
                                enc_name = "EUC-TW";                                encoding = mbfl_no2encoding(mbfl_no_encoding_euc_tw);
                                enc_name_len = sizeof("EUC-TW") - 1; 
                                 break;                                  break;
                         case mbfl_no_language_russian:                          case mbfl_no_language_russian:
                                enc_name = "KOI8-R";                                encoding = mbfl_no2encoding(mbfl_no_encoding_koi8r);
                                enc_name_len = sizeof("KOI8-R") - 1; 
                                 break;                                  break;
                         case mbfl_no_language_german:                          case mbfl_no_language_german:
                                enc_name = "ISO-8859-15";                                encoding = mbfl_no2encoding(mbfl_no_encoding_8859_15);
                                enc_name_len = sizeof("ISO-8859-15") - 1; 
                                 break;                                  break;
                         case mbfl_no_language_armenian:                          case mbfl_no_language_armenian:
                                enc_name = "ArmSCII-8";                                encoding = mbfl_no2encoding(mbfl_no_encoding_armscii8);
                                enc_name_len = sizeof("ArmSCII-8") - 1; 
                                 break;                                  break;
                         case mbfl_no_language_turkish:                          case mbfl_no_language_turkish:
                                enc_name = "ISO-8859-9";                                encoding = mbfl_no2encoding(mbfl_no_encoding_8859_9);
                                enc_name_len = sizeof("ISO-8859-9") - 1; 
                                 break;                                  break;
                         default:                          default:
                                enc_name = "ISO-8859-1";                                encoding = mbfl_no2encoding(mbfl_no_encoding_8859_1);
                                enc_name_len = sizeof("ISO-8859-1") - 1; 
                                 break;                                  break;
                 }                  }
                 no_encoding = mbfl_name2no_encoding(enc_name);  
         }          }
        MBSTRG(internal_encoding) = no_encoding;        MBSTRG(internal_encoding) = encoding;
        MBSTRG(current_internal_encoding) = no_encoding;        MBSTRG(current_internal_encoding) = encoding;
 #if HAVE_MBREGEX  #if HAVE_MBREGEX
         {          {
                 const char *enc_name = new_value;                  const char *enc_name = new_value;
Line 1124  int _php_mb_ini_mbstring_internal_encoding_set(const c Line 1338  int _php_mb_ini_mbstring_internal_encoding_set(const c
 /* {{{ static PHP_INI_MH(OnUpdate_mbstring_internal_encoding) */  /* {{{ static PHP_INI_MH(OnUpdate_mbstring_internal_encoding) */
 static PHP_INI_MH(OnUpdate_mbstring_internal_encoding)  static PHP_INI_MH(OnUpdate_mbstring_internal_encoding)
 {  {
           if (OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC) == FAILURE) {
                   return FAILURE;
           }
         if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN          if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN
                         || stage == PHP_INI_STAGE_RUNTIME) {                          || stage == PHP_INI_STAGE_RUNTIME) {
                 return _php_mb_ini_mbstring_internal_encoding_set(new_value, new_value_length TSRMLS_CC);                  return _php_mb_ini_mbstring_internal_encoding_set(new_value, new_value_length TSRMLS_CC);
Line 1139  static PHP_INI_MH(OnUpdate_mbstring_internal_encoding) Line 1356  static PHP_INI_MH(OnUpdate_mbstring_internal_encoding)
 }  }
 /* }}} */  /* }}} */
   
 #ifdef ZEND_MULTIBYTE  
 /* {{{ static PHP_INI_MH(OnUpdate_mbstring_script_encoding) */  
 static PHP_INI_MH(OnUpdate_mbstring_script_encoding)  
 {  
         int *list, size;  
   
         if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {  
                 if (MBSTRG(script_encoding_list) != NULL) {  
                         free(MBSTRG(script_encoding_list));  
                 }  
                 MBSTRG(script_encoding_list) = list;  
                 MBSTRG(script_encoding_list_size) = size;  
         } else {  
                 if (MBSTRG(script_encoding_list) != NULL) {  
                         free(MBSTRG(script_encoding_list));  
                 }  
                 MBSTRG(script_encoding_list) = NULL;  
                 MBSTRG(script_encoding_list_size) = 0;  
                 return FAILURE;  
         }  
   
         return SUCCESS;  
 }  
 /* }}} */  
 #endif /* ZEND_MULTIBYTE */  
   
 /* {{{ static PHP_INI_MH(OnUpdate_mbstring_substitute_character) */  /* {{{ static PHP_INI_MH(OnUpdate_mbstring_substitute_character) */
 static PHP_INI_MH(OnUpdate_mbstring_substitute_character)  static PHP_INI_MH(OnUpdate_mbstring_substitute_character)
 {  {
Line 1207  static PHP_INI_MH(OnUpdate_mbstring_substitute_charact Line 1398  static PHP_INI_MH(OnUpdate_mbstring_substitute_charact
 static PHP_INI_MH(OnUpdate_mbstring_encoding_translation)  static PHP_INI_MH(OnUpdate_mbstring_encoding_translation)
 {  {
         if (new_value == NULL) {          if (new_value == NULL) {
           return FAILURE;                return FAILURE;
         }          }
   
         OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);          OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
Line 1261  PHP_INI_BEGIN() Line 1452  PHP_INI_BEGIN()
         PHP_INI_ENTRY("mbstring.detect_order", NULL, PHP_INI_ALL, OnUpdate_mbstring_detect_order)          PHP_INI_ENTRY("mbstring.detect_order", NULL, PHP_INI_ALL, OnUpdate_mbstring_detect_order)
         PHP_INI_ENTRY("mbstring.http_input", "pass", PHP_INI_ALL, OnUpdate_mbstring_http_input)          PHP_INI_ENTRY("mbstring.http_input", "pass", PHP_INI_ALL, OnUpdate_mbstring_http_input)
         PHP_INI_ENTRY("mbstring.http_output", "pass", PHP_INI_ALL, OnUpdate_mbstring_http_output)          PHP_INI_ENTRY("mbstring.http_output", "pass", PHP_INI_ALL, OnUpdate_mbstring_http_output)
        PHP_INI_ENTRY("mbstring.internal_encoding", NULL, PHP_INI_ALL, OnUpdate_mbstring_internal_encoding)        STD_PHP_INI_ENTRY("mbstring.internal_encoding", NULL, PHP_INI_ALL, OnUpdate_mbstring_internal_encoding, internal_encoding_name, zend_mbstring_globals, mbstring_globals)
#ifdef ZEND_MULTIBYTE 
        PHP_INI_ENTRY("mbstring.script_encoding", NULL, PHP_INI_ALL, OnUpdate_mbstring_script_encoding) 
#endif /* ZEND_MULTIBYTE */ 
         PHP_INI_ENTRY("mbstring.substitute_character", NULL, PHP_INI_ALL, OnUpdate_mbstring_substitute_character)          PHP_INI_ENTRY("mbstring.substitute_character", NULL, PHP_INI_ALL, OnUpdate_mbstring_substitute_character)
         STD_PHP_INI_ENTRY("mbstring.func_overload", "0",           STD_PHP_INI_ENTRY("mbstring.func_overload", "0", 
         PHP_INI_SYSTEM, OnUpdateLong, func_overload, zend_mbstring_globals, mbstring_globals)          PHP_INI_SYSTEM, OnUpdateLong, func_overload, zend_mbstring_globals, mbstring_globals)
Line 1289  PHP_INI_END() Line 1477  PHP_INI_END()
 static PHP_GINIT_FUNCTION(mbstring)  static PHP_GINIT_FUNCTION(mbstring)
 {  {
         mbstring_globals->language = mbfl_no_language_uni;          mbstring_globals->language = mbfl_no_language_uni;
        mbstring_globals->internal_encoding = mbfl_no_encoding_invalid;        mbstring_globals->internal_encoding = NULL;
         mbstring_globals->current_internal_encoding = mbstring_globals->internal_encoding;          mbstring_globals->current_internal_encoding = mbstring_globals->internal_encoding;
#ifdef ZEND_MULTIBYTE        mbstring_globals->http_output_encoding = &mbfl_encoding_pass;
        mbstring_globals->script_encoding_list = NULL;        mbstring_globals->current_http_output_encoding = &mbfl_encoding_pass;
        mbstring_globals->script_encoding_list_size = 0;        mbstring_globals->http_input_identify = NULL;
#endif /* ZEND_MULTIBYTE */        mbstring_globals->http_input_identify_get = NULL;
        mbstring_globals->http_output_encoding = mbfl_no_encoding_pass;        mbstring_globals->http_input_identify_post = NULL;
        mbstring_globals->current_http_output_encoding = mbfl_no_encoding_pass;        mbstring_globals->http_input_identify_cookie = NULL;
        mbstring_globals->http_input_identify = mbfl_no_encoding_invalid;        mbstring_globals->http_input_identify_string = NULL;
        mbstring_globals->http_input_identify_get = mbfl_no_encoding_invalid; 
        mbstring_globals->http_input_identify_post = mbfl_no_encoding_invalid; 
        mbstring_globals->http_input_identify_cookie = mbfl_no_encoding_invalid; 
        mbstring_globals->http_input_identify_string = mbfl_no_encoding_invalid; 
         mbstring_globals->http_input_list = NULL;          mbstring_globals->http_input_list = NULL;
         mbstring_globals->http_input_list_size = 0;          mbstring_globals->http_input_list_size = 0;
         mbstring_globals->detect_order_list = NULL;          mbstring_globals->detect_order_list = NULL;
Line 1332  static PHP_GSHUTDOWN_FUNCTION(mbstring) Line 1516  static PHP_GSHUTDOWN_FUNCTION(mbstring)
         if (mbstring_globals->http_input_list) {          if (mbstring_globals->http_input_list) {
                 free(mbstring_globals->http_input_list);                  free(mbstring_globals->http_input_list);
         }          }
 #ifdef ZEND_MULTIBYTE  
         if (mbstring_globals->script_encoding_list) {  
                 free(mbstring_globals->script_encoding_list);  
         }  
 #endif /* ZEND_MULTIBYTE */  
         if (mbstring_globals->detect_order_list) {          if (mbstring_globals->detect_order_list) {
                 free(mbstring_globals->detect_order_list);                  free(mbstring_globals->detect_order_list);
         }          }
Line 1357  PHP_MINIT_FUNCTION(mbstring) Line 1536  PHP_MINIT_FUNCTION(mbstring)
         REGISTER_INI_ENTRIES();          REGISTER_INI_ENTRIES();
   
         /* This is a global handler. Should not be set in a per-request handler. */          /* This is a global handler. Should not be set in a per-request handler. */
        sapi_register_treat_data(mbstr_treat_data);        sapi_register_treat_data(mbstr_treat_data TSRMLS_CC);
   
         /* Post handlers are stored in the thread-local context. */          /* Post handlers are stored in the thread-local context. */
         if (MBSTRG(encoding_translation)) {          if (MBSTRG(encoding_translation)) {
Line 1375  PHP_MINIT_FUNCTION(mbstring) Line 1554  PHP_MINIT_FUNCTION(mbstring)
 #if HAVE_MBREGEX  #if HAVE_MBREGEX
         PHP_MINIT(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);          PHP_MINIT(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
 #endif  #endif
   
           if (FAILURE == zend_multibyte_set_functions(&php_mb_zend_multibyte_functions TSRMLS_CC)) {
                   return FAILURE;
           }
   
           php_rfc1867_set_multibyte_callbacks(
                   php_mb_encoding_translation,
                   php_mb_gpc_get_detect_order,
                   php_mb_gpc_set_input_encoding,
                   php_mb_rfc1867_getword,
                   php_mb_rfc1867_getword_conf,
                   php_mb_rfc1867_basename);
   
         return SUCCESS;          return SUCCESS;
 }  }
 /* }}} */  /* }}} */
Line 1383  PHP_MINIT_FUNCTION(mbstring) Line 1575  PHP_MINIT_FUNCTION(mbstring)
 PHP_MSHUTDOWN_FUNCTION(mbstring)  PHP_MSHUTDOWN_FUNCTION(mbstring)
 {  {
         UNREGISTER_INI_ENTRIES();          UNREGISTER_INI_ENTRIES();
        
 #if HAVE_MBREGEX  #if HAVE_MBREGEX
         PHP_MSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);          PHP_MSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
 #endif  #endif
Line 1395  PHP_MSHUTDOWN_FUNCTION(mbstring) Line 1587  PHP_MSHUTDOWN_FUNCTION(mbstring)
 /* {{{ PHP_RINIT_FUNCTION(mbstring) */  /* {{{ PHP_RINIT_FUNCTION(mbstring) */
 PHP_RINIT_FUNCTION(mbstring)  PHP_RINIT_FUNCTION(mbstring)
 {  {
         int n;  
         enum mbfl_no_encoding *list=NULL, *entry;  
         zend_function *func, *orig;          zend_function *func, *orig;
         const struct mb_overload_def *p;          const struct mb_overload_def *p;
   
Line 1407  PHP_RINIT_FUNCTION(mbstring) Line 1597  PHP_RINIT_FUNCTION(mbstring)
   
         MBSTRG(illegalchars) = 0;          MBSTRG(illegalchars) = 0;
   
        n = 0;        php_mb_populate_current_detect_order_list(TSRMLS_C);
        if (MBSTRG(detect_order_list)) { 
                list = MBSTRG(detect_order_list); 
                n = MBSTRG(detect_order_list_size); 
        } 
        if (n <= 0) { 
                list = MBSTRG(default_detect_order_list); 
                n = MBSTRG(default_detect_order_list_size); 
        } 
        entry = (enum mbfl_no_encoding *)safe_emalloc(n, sizeof(int), 0); 
        MBSTRG(current_detect_order_list) = entry; 
        MBSTRG(current_detect_order_list_size) = n; 
        while (n > 0) { 
                *entry++ = *list++; 
                n--; 
        } 
   
         /* override original function. */          /* override original function. */
         if (MBSTRG(func_overload)){          if (MBSTRG(func_overload)){
Line 1454  PHP_RINIT_FUNCTION(mbstring) Line 1629  PHP_RINIT_FUNCTION(mbstring)
 #if HAVE_MBREGEX  #if HAVE_MBREGEX
         PHP_RINIT(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);          PHP_RINIT(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
 #endif  #endif
#ifdef ZEND_MULTIBYTE        zend_multibyte_set_internal_encoding((const zend_encoding *)MBSTRG(internal_encoding) TSRMLS_CC);
        zend_multibyte_set_internal_encoding(mbfl_no_encoding2name(MBSTRG(internal_encoding)) TSRMLS_CC); 
        php_mb_set_zend_encoding(TSRMLS_C); 
#endif /* ZEND_MULTIBYTE */ 
   
         return SUCCESS;          return SUCCESS;
 }  }
Line 1481  PHP_RSHUTDOWN_FUNCTION(mbstring) Line 1653  PHP_RSHUTDOWN_FUNCTION(mbstring)
         }          }
   
         /* clear http input identification. */          /* clear http input identification. */
        MBSTRG(http_input_identify) = mbfl_no_encoding_invalid;        MBSTRG(http_input_identify) = NULL;
        MBSTRG(http_input_identify_post) = mbfl_no_encoding_invalid;        MBSTRG(http_input_identify_post) = NULL;
        MBSTRG(http_input_identify_get) = mbfl_no_encoding_invalid;        MBSTRG(http_input_identify_get) = NULL;
        MBSTRG(http_input_identify_cookie) = mbfl_no_encoding_invalid;        MBSTRG(http_input_identify_cookie) = NULL;
        MBSTRG(http_input_identify_string) = mbfl_no_encoding_invalid;        MBSTRG(http_input_identify_string) = NULL;
   
         /*  clear overloaded function. */          /*  clear overloaded function. */
         if (MBSTRG(func_overload)){          if (MBSTRG(func_overload)){
Line 1516  PHP_MINFO_FUNCTION(mbstring) Line 1688  PHP_MINFO_FUNCTION(mbstring)
         php_info_print_table_start();          php_info_print_table_start();
         php_info_print_table_row(2, "Multibyte Support", "enabled");          php_info_print_table_row(2, "Multibyte Support", "enabled");
         php_info_print_table_row(2, "Multibyte string engine", "libmbfl");          php_info_print_table_row(2, "Multibyte string engine", "libmbfl");
        php_info_print_table_row(2, "HTTP input encoding translation", MBSTRG(encoding_translation) ? "enabled": "disabled");           php_info_print_table_row(2, "HTTP input encoding translation", MBSTRG(encoding_translation) ? "enabled": "disabled");
         {
                 char tmp[256];
                 snprintf(tmp, sizeof(tmp), "%d.%d.%d", MBFL_VERSION_MAJOR, MBFL_VERSION_MINOR, MBFL_VERSION_TEENY);
                 php_info_print_table_row(2, "libmbfl version", tmp);
         }       
         php_info_print_table_end();          php_info_print_table_end();
   
         php_info_print_table_start();          php_info_print_table_start();
Line 1560  PHP_FUNCTION(mb_language) Line 1737  PHP_FUNCTION(mb_language)
    Sets the current internal encoding or Returns the current internal encoding as a string */     Sets the current internal encoding or Returns the current internal encoding as a string */
 PHP_FUNCTION(mb_internal_encoding)  PHP_FUNCTION(mb_internal_encoding)
 {  {
        char *name = NULL;        const char *name = NULL;
         int name_len;          int name_len;
        enum mbfl_no_encoding no_encoding;        const mbfl_encoding *encoding;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
         if (name == NULL) {          if (name == NULL) {
                name = (char *)mbfl_no_encoding2name(MBSTRG(current_internal_encoding));                name = MBSTRG(current_internal_encoding) ? MBSTRG(current_internal_encoding)->name: NULL;
                 if (name != NULL) {                  if (name != NULL) {
                         RETURN_STRING(name, 1);                          RETURN_STRING(name, 1);
                 } else {                  } else {
                         RETURN_FALSE;                          RETURN_FALSE;
                 }                  }
         } else {          } else {
                no_encoding = mbfl_name2no_encoding(name);                encoding = mbfl_name2encoding(name);
                if (no_encoding == mbfl_no_encoding_invalid) {                if (!encoding) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", name);                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", name);
                         RETURN_FALSE;                          RETURN_FALSE;
                 } else {                  } else {
                        MBSTRG(current_internal_encoding) = no_encoding;                        MBSTRG(current_internal_encoding) = encoding;
#ifdef ZEND_MULTIBYTE 
                        /* TODO: make independent from mbstring.encoding_translation? */ 
                        if (MBSTRG(encoding_translation)) { 
                                zend_multibyte_set_internal_encoding(name TSRMLS_CC); 
                        } 
#endif /* ZEND_MULTIBYTE */ 
                         RETURN_TRUE;                          RETURN_TRUE;
                 }                  }
         }          }
Line 1599  PHP_FUNCTION(mb_http_input) Line 1770  PHP_FUNCTION(mb_http_input)
 {  {
         char *typ = NULL;          char *typ = NULL;
         int typ_len;          int typ_len;
        int retname, n;        int retname;
        char *name, *list, *temp;        char *list, *temp;
        enum mbfl_no_encoding *entry;        const mbfl_encoding *result = NULL;
        enum mbfl_no_encoding result = mbfl_no_encoding_invalid; 
   
         retname = 1;          retname = 1;
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &typ, &typ_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &typ, &typ_len) == FAILURE) {
Line 1630  PHP_FUNCTION(mb_http_input) Line 1800  PHP_FUNCTION(mb_http_input)
                         break;                          break;
                 case 'I':                  case 'I':
                 case 'i':                  case 'i':
                        array_init(return_value);                        {
                        entry = MBSTRG(http_input_list);                                const mbfl_encoding **entry = MBSTRG(http_input_list);
                        n = MBSTRG(http_input_list_size);                                const size_t n = MBSTRG(http_input_list_size);
                        while (n > 0) {                                size_t i;
                                name = (char *)mbfl_no_encoding2name(*entry);                                array_init(return_value);
                                if (name) {                                for (i = 0; i < n; i++) {
                                        add_next_index_string(return_value, name, 1);                                        add_next_index_string(return_value, (*entry)->name, 1);
                                         entry++;
                                 }                                  }
                                entry++;                                retname = 0;
                                n--; 
                         }                          }
                         retname = 0;  
                         break;                          break;
                 case 'L':                  case 'L':
                 case 'l':                  case 'l':
                        entry = MBSTRG(http_input_list);                        {
                        n = MBSTRG(http_input_list_size);                                const mbfl_encoding **entry = MBSTRG(http_input_list);
                        list = NULL;                                const size_t n = MBSTRG(http_input_list_size);
                        while (n > 0) {                                size_t i;
                                name = (char *)mbfl_no_encoding2name(*entry);                                list = NULL;
                                if (name) {                                for (i = 0; i < n; i++) {
                                         if (list) {                                          if (list) {
                                                 temp = list;                                                  temp = list;
                                                spprintf(&list, 0, "%s,%s", temp, name);                                                spprintf(&list, 0, "%s,%s", temp, (*entry)->name);
                                                 efree(temp);                                                  efree(temp);
                                                 if (!list) {                                                   if (!list) { 
                                                         break;                                                          break;
                                                 }                                                  }
                                         } else {                                          } else {
                                                list = estrdup(name);                                                list = estrdup((*entry)->name);
                                         }                                          }
                                           entry++;
                                 }                                  }
                                 entry++;  
                                 n--;  
                         }                          }
                         if (!list) {                          if (!list) {
                                 RETURN_FALSE;                                  RETURN_FALSE;
Line 1678  PHP_FUNCTION(mb_http_input) Line 1846  PHP_FUNCTION(mb_http_input)
         }          }
   
         if (retname) {          if (retname) {
                if (result != mbfl_no_encoding_invalid &&                if (result) {
                        (name = (char *)mbfl_no_encoding2name(result)) != NULL) {                        RETVAL_STRING(result->name, 1);
                        RETVAL_STRING(name, 1); 
                 } else {                  } else {
                         RETVAL_FALSE;                          RETVAL_FALSE;
                 }                  }
Line 1692  PHP_FUNCTION(mb_http_input) Line 1859  PHP_FUNCTION(mb_http_input)
    Sets the current output_encoding or returns the current output_encoding as a string */     Sets the current output_encoding or returns the current output_encoding as a string */
 PHP_FUNCTION(mb_http_output)  PHP_FUNCTION(mb_http_output)
 {  {
        char *name = NULL;        const char *name = NULL;
         int name_len;          int name_len;
        enum mbfl_no_encoding no_encoding;        const mbfl_encoding *encoding;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", (char **)&name, &name_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", (char **)&name, &name_len) == FAILURE) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
   
         if (name == NULL) {          if (name == NULL) {
                name = (char *)mbfl_no_encoding2name(MBSTRG(current_http_output_encoding));                name = MBSTRG(current_http_output_encoding) ? MBSTRG(current_http_output_encoding)->name: NULL;
                 if (name != NULL) {                  if (name != NULL) {
                         RETURN_STRING(name, 1);                          RETURN_STRING(name, 1);
                 } else {                  } else {
                         RETURN_FALSE;                          RETURN_FALSE;
                 }                  }
         } else {          } else {
                no_encoding = mbfl_name2no_encoding(name);                encoding = mbfl_name2encoding(name);
                if (no_encoding == mbfl_no_encoding_invalid) {                if (!encoding) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", name);                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", name);
                         RETURN_FALSE;                          RETURN_FALSE;
                 } else {                  } else {
                        MBSTRG(current_http_output_encoding) = no_encoding;                        MBSTRG(current_http_output_encoding) = encoding;
                         RETURN_TRUE;                          RETURN_TRUE;
                 }                  }
         }          }
Line 1725  PHP_FUNCTION(mb_http_output) Line 1892  PHP_FUNCTION(mb_http_output)
 PHP_FUNCTION(mb_detect_order)  PHP_FUNCTION(mb_detect_order)
 {  {
         zval **arg1 = NULL;          zval **arg1 = NULL;
         int n, size;  
         enum mbfl_no_encoding *list, *entry;  
         char *name;  
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Z", &arg1) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Z", &arg1) == FAILURE) {
                 return;                  return;
         }          }
   
         if (!arg1) {          if (!arg1) {
                   size_t i;
                   size_t n = MBSTRG(current_detect_order_list_size);
                   const mbfl_encoding **entry = MBSTRG(current_detect_order_list);
                 array_init(return_value);                  array_init(return_value);
                entry = MBSTRG(current_detect_order_list);                for (i = 0; i < n; i++) {
                n = MBSTRG(current_detect_order_list_size);                        add_next_index_string(return_value, (*entry)->name, 1);
                while (n > 0) { 
                        name = (char *)mbfl_no_encoding2name(*entry); 
                        if (name) { 
                                add_next_index_string(return_value, name, 1); 
                        } 
                         entry++;                          entry++;
                         n--;  
                 }                  }
         } else {          } else {
                list = NULL;                const mbfl_encoding **list = NULL;
                size = 0;                size_t size = 0;
                 switch (Z_TYPE_PP(arg1)) {                  switch (Z_TYPE_PP(arg1)) {
                 case IS_ARRAY:                  case IS_ARRAY:
                        if (!php_mb_parse_encoding_array(*arg1, &list, &size, 0 TSRMLS_CC)) {                        if (FAILURE == php_mb_parse_encoding_array(*arg1, &list, &size, 0 TSRMLS_CC)) {
                                 if (list) {                                  if (list) {
                                         efree(list);                                          efree(list);
                                 }                                  }
Line 1759  PHP_FUNCTION(mb_detect_order) Line 1920  PHP_FUNCTION(mb_detect_order)
                         break;                          break;
                 default:                  default:
                         convert_to_string_ex(arg1);                          convert_to_string_ex(arg1);
                        if (!php_mb_parse_encoding_list(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1), &list, &size, 0 TSRMLS_CC)) {                        if (FAILURE == php_mb_parse_encoding_list(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1), &list, &size, 0 TSRMLS_CC)) {
                                 if (list) {                                  if (list) {
                                         efree(list);                                          efree(list);
                                 }                                  }
Line 1879  PHP_FUNCTION(mb_parse_str) Line 2040  PHP_FUNCTION(mb_parse_str)
         char *encstr = NULL;          char *encstr = NULL;
         int encstr_len;          int encstr_len;
         php_mb_encoding_handler_info_t info;          php_mb_encoding_handler_info_t info;
        enum mbfl_no_encoding detected;        const mbfl_encoding *detected;
   
         track_vars_array = NULL;          track_vars_array = NULL;
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &encstr, &encstr_len, &track_vars_array) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &encstr, &encstr_len, &track_vars_array) == FAILURE) {
                 return;                  return;
         }          }
   
         /* Clear out the array */  
         if (track_vars_array != NULL) {          if (track_vars_array != NULL) {
                   /* Clear out the array */
                 zval_dtor(track_vars_array);                  zval_dtor(track_vars_array);
                 array_init(track_vars_array);                  array_init(track_vars_array);
         }          }
Line 1896  PHP_FUNCTION(mb_parse_str) Line 2057  PHP_FUNCTION(mb_parse_str)
   
         info.data_type              = PARSE_STRING;          info.data_type              = PARSE_STRING;
         info.separator              = PG(arg_separator).input;           info.separator              = PG(arg_separator).input; 
         info.force_register_globals = (track_vars_array == NULL);  
         info.report_errors          = 1;          info.report_errors          = 1;
         info.to_encoding            = MBSTRG(current_internal_encoding);          info.to_encoding            = MBSTRG(current_internal_encoding);
         info.to_language            = MBSTRG(language);          info.to_language            = MBSTRG(language);
Line 1904  PHP_FUNCTION(mb_parse_str) Line 2064  PHP_FUNCTION(mb_parse_str)
         info.num_from_encodings     = MBSTRG(http_input_list_size);           info.num_from_encodings     = MBSTRG(http_input_list_size); 
         info.from_language          = MBSTRG(language);          info.from_language          = MBSTRG(language);
   
        detected = _php_mb_encoding_handler_ex(&info, track_vars_array, encstr TSRMLS_CC);        if (track_vars_array != NULL) {
                 detected = _php_mb_encoding_handler_ex(&info, track_vars_array, encstr TSRMLS_CC);
         } else {
                 zval tmp;
                 if (!EG(active_symbol_table)) {
                         zend_rebuild_symbol_table(TSRMLS_C);
                 }
                 Z_ARRVAL(tmp) = EG(active_symbol_table);                
                 detected = _php_mb_encoding_handler_ex(&info, &tmp, encstr TSRMLS_CC);          
         }
   
         MBSTRG(http_input_identify) = detected;          MBSTRG(http_input_identify) = detected;
   
        RETVAL_BOOL(detected != mbfl_no_encoding_invalid);        RETVAL_BOOL(detected);
   
         if (encstr != NULL) efree(encstr);          if (encstr != NULL) efree(encstr);
 }  }
Line 1924  PHP_FUNCTION(mb_output_handler) Line 2093  PHP_FUNCTION(mb_output_handler)
         mbfl_string string, result;          mbfl_string string, result;
         const char *charset;          const char *charset;
         char *p;          char *p;
        enum mbfl_no_encoding encoding;        const mbfl_encoding *encoding;
         int last_feed, len;          int last_feed, len;
         unsigned char send_text_mimetype = 0;          unsigned char send_text_mimetype = 0;
         char *s, *mimetype = NULL;          char *s, *mimetype = NULL;
Line 1943  PHP_FUNCTION(mb_output_handler) Line 2112  PHP_FUNCTION(mb_output_handler)
                         mbfl_buffer_converter_delete(MBSTRG(outconv));                          mbfl_buffer_converter_delete(MBSTRG(outconv));
                         MBSTRG(outconv) = NULL;                          MBSTRG(outconv) = NULL;
                 }                  }
                if (encoding == mbfl_no_encoding_pass) {                if (encoding == &mbfl_encoding_pass) {
                         RETURN_STRINGL(arg_string, arg_string_len, 1);                          RETURN_STRINGL(arg_string, arg_string_len, 1);
                 }                  }
   
Line 1965  PHP_FUNCTION(mb_output_handler) Line 2134  PHP_FUNCTION(mb_output_handler)
   
                 /* if content-type is not yet set, set it and activate the converter */                  /* if content-type is not yet set, set it and activate the converter */
                 if (SG(sapi_headers).send_default_content_type || send_text_mimetype) {                  if (SG(sapi_headers).send_default_content_type || send_text_mimetype) {
                        charset = mbfl_no2preferred_mime_name(encoding);                        charset = encoding->mime_name;
                         if (charset) {                          if (charset) {
                                 len = spprintf( &p, 0, "Content-Type: %s; charset=%s",  mimetype, charset );                                   len = spprintf( &p, 0, "Content-Type: %s; charset=%s",  mimetype, charset ); 
                                 if (sapi_add_header(p, len, 0) != FAILURE) {                                  if (sapi_add_header(p, len, 0) != FAILURE) {
Line 1973  PHP_FUNCTION(mb_output_handler) Line 2142  PHP_FUNCTION(mb_output_handler)
                                 }                                  }
                         }                          }
                         /* activate the converter */                          /* activate the converter */
                        MBSTRG(outconv) = mbfl_buffer_converter_new(MBSTRG(current_internal_encoding), encoding, 0);                        MBSTRG(outconv) = mbfl_buffer_converter_new2(MBSTRG(current_internal_encoding), encoding, 0);
                         if (send_text_mimetype){                          if (send_text_mimetype){
                                 efree(mimetype);                                  efree(mimetype);
                         }                          }
Line 1994  PHP_FUNCTION(mb_output_handler) Line 2163  PHP_FUNCTION(mb_output_handler)
         /* feed the string */          /* feed the string */
         mbfl_string_init(&string);          mbfl_string_init(&string);
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
        string.no_encoding = MBSTRG(current_internal_encoding);        string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         string.val = (unsigned char *)arg_string;          string.val = (unsigned char *)arg_string;
         string.len = arg_string_len;          string.len = arg_string_len;
         mbfl_buffer_converter_feed(MBSTRG(outconv), &string);          mbfl_buffer_converter_feed(MBSTRG(outconv), &string);
Line 2031  PHP_FUNCTION(mb_strlen) Line 2200  PHP_FUNCTION(mb_strlen)
   
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
         if (enc_name == NULL) {          if (enc_name == NULL) {
                string.no_encoding = MBSTRG(current_internal_encoding);                string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         } else {          } else {
                 string.no_encoding = mbfl_name2no_encoding(enc_name);                  string.no_encoding = mbfl_name2no_encoding(enc_name);
                 if (string.no_encoding == mbfl_no_encoding_invalid) {                  if (string.no_encoding == mbfl_no_encoding_invalid) {
Line 2058  PHP_FUNCTION(mb_strpos) Line 2227  PHP_FUNCTION(mb_strpos)
         mbfl_string haystack, needle;          mbfl_string haystack, needle;
         char *enc_name = NULL;          char *enc_name = NULL;
         int enc_name_len;          int enc_name_len;
        
         mbfl_string_init(&haystack);          mbfl_string_init(&haystack);
         mbfl_string_init(&needle);          mbfl_string_init(&needle);
         haystack.no_language = MBSTRG(language);          haystack.no_language = MBSTRG(language);
        haystack.no_encoding = MBSTRG(current_internal_encoding);        haystack.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         needle.no_language = MBSTRG(language);          needle.no_language = MBSTRG(language);
        needle.no_encoding = MBSTRG(current_internal_encoding);        needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         offset = 0;          offset = 0;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ls", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &offset, &enc_name, &enc_name_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ls", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &offset, &enc_name, &enc_name_len) == FAILURE) {
Line 2129  PHP_FUNCTION(mb_strrpos) Line 2298  PHP_FUNCTION(mb_strrpos)
         mbfl_string_init(&haystack);          mbfl_string_init(&haystack);
         mbfl_string_init(&needle);          mbfl_string_init(&needle);
         haystack.no_language = MBSTRG(language);          haystack.no_language = MBSTRG(language);
        haystack.no_encoding = MBSTRG(current_internal_encoding);        haystack.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         needle.no_language = MBSTRG(language);          needle.no_language = MBSTRG(language);
        needle.no_encoding = MBSTRG(current_internal_encoding);        needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|Zs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &zoffset, &enc_name, &enc_name_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|Zs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &zoffset, &enc_name, &enc_name_len) == FAILURE) {
                 RETURN_FALSE;                  RETURN_FALSE;
Line 2218  PHP_FUNCTION(mb_stripos) Line 2387  PHP_FUNCTION(mb_stripos)
         int n;          int n;
         long offset;          long offset;
         mbfl_string haystack, needle;          mbfl_string haystack, needle;
        char *from_encoding = (char*)mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));        const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name;
         int from_encoding_len;          int from_encoding_len;
         n = -1;          n = -1;
         offset = 0;          offset = 0;
Line 2247  PHP_FUNCTION(mb_strripos) Line 2416  PHP_FUNCTION(mb_strripos)
         int n;          int n;
         long offset;          long offset;
         mbfl_string haystack, needle;          mbfl_string haystack, needle;
        const char *from_encoding = mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));        const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name;
         int from_encoding_len;          int from_encoding_len;
         n = -1;          n = -1;
         offset = 0;          offset = 0;
Line 2279  PHP_FUNCTION(mb_strstr) Line 2448  PHP_FUNCTION(mb_strstr)
         mbfl_string_init(&haystack);          mbfl_string_init(&haystack);
         mbfl_string_init(&needle);          mbfl_string_init(&needle);
         haystack.no_language = MBSTRG(language);          haystack.no_language = MBSTRG(language);
        haystack.no_encoding = MBSTRG(current_internal_encoding);        haystack.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         needle.no_language = MBSTRG(language);          needle.no_language = MBSTRG(language);
        needle.no_encoding = MBSTRG(current_internal_encoding);        needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, (int *)&haystack.len, (char **)&needle.val, (int *)&needle.len, &part, &enc_name, &enc_name_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, (int *)&haystack.len, (char **)&needle.val, (int *)&needle.len, &part, &enc_name, &enc_name_len) == FAILURE) {
                 RETURN_FALSE;                  RETURN_FALSE;
Line 2337  PHP_FUNCTION(mb_strrchr) Line 2506  PHP_FUNCTION(mb_strrchr)
         mbfl_string_init(&haystack);          mbfl_string_init(&haystack);
         mbfl_string_init(&needle);          mbfl_string_init(&needle);
         haystack.no_language = MBSTRG(language);          haystack.no_language = MBSTRG(language);
        haystack.no_encoding = MBSTRG(current_internal_encoding);        haystack.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         needle.no_language = MBSTRG(language);          needle.no_language = MBSTRG(language);
        needle.no_encoding = MBSTRG(current_internal_encoding);        needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &enc_name, &enc_name_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &enc_name, &enc_name_len) == FAILURE) {
                 RETURN_FALSE;                  RETURN_FALSE;
Line 2392  PHP_FUNCTION(mb_stristr) Line 2561  PHP_FUNCTION(mb_stristr)
         unsigned int from_encoding_len, len, mblen;          unsigned int from_encoding_len, len, mblen;
         int n;          int n;
         mbfl_string haystack, needle, result, *ret = NULL;          mbfl_string haystack, needle, result, *ret = NULL;
        const char *from_encoding = mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));        const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name;
         mbfl_string_init(&haystack);          mbfl_string_init(&haystack);
         mbfl_string_init(&needle);          mbfl_string_init(&needle);
         haystack.no_language = MBSTRG(language);          haystack.no_language = MBSTRG(language);
        haystack.no_encoding = MBSTRG(current_internal_encoding);        haystack.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         needle.no_language = MBSTRG(language);          needle.no_language = MBSTRG(language);
        needle.no_encoding = MBSTRG(current_internal_encoding);        needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &from_encoding, &from_encoding_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &from_encoding, &from_encoding_len) == FAILURE) {
Line 2450  PHP_FUNCTION(mb_strrichr) Line 2619  PHP_FUNCTION(mb_strrichr)
         zend_bool part = 0;          zend_bool part = 0;
         int n, from_encoding_len, len, mblen;          int n, from_encoding_len, len, mblen;
         mbfl_string haystack, needle, result, *ret = NULL;          mbfl_string haystack, needle, result, *ret = NULL;
        char *from_encoding = (char*)mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));        const char *from_encoding = MBSTRG(current_internal_encoding)->name;
         mbfl_string_init(&haystack);          mbfl_string_init(&haystack);
         mbfl_string_init(&needle);          mbfl_string_init(&needle);
         haystack.no_language = MBSTRG(language);          haystack.no_language = MBSTRG(language);
        haystack.no_encoding = MBSTRG(current_internal_encoding);        haystack.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         needle.no_language = MBSTRG(language);          needle.no_language = MBSTRG(language);
        needle.no_encoding = MBSTRG(current_internal_encoding);        needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &from_encoding, &from_encoding_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &from_encoding, &from_encoding_len) == FAILURE) {
Line 2508  PHP_FUNCTION(mb_substr_count) Line 2677  PHP_FUNCTION(mb_substr_count)
         mbfl_string_init(&haystack);          mbfl_string_init(&haystack);
         mbfl_string_init(&needle);          mbfl_string_init(&needle);
         haystack.no_language = MBSTRG(language);          haystack.no_language = MBSTRG(language);
        haystack.no_encoding = MBSTRG(current_internal_encoding);        haystack.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         needle.no_language = MBSTRG(language);          needle.no_language = MBSTRG(language);
        needle.no_encoding = MBSTRG(current_internal_encoding);        needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &enc_name, &enc_name_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &enc_name, &enc_name_len) == FAILURE) {
                 return;                  return;
Line 2546  PHP_FUNCTION(mb_substr) Line 2715  PHP_FUNCTION(mb_substr)
         char *str, *encoding;          char *str, *encoding;
         long from, len;          long from, len;
         int mblen, str_len, encoding_len;          int mblen, str_len, encoding_len;
           zval **z_len = NULL;
         mbfl_string string, result, *ret;          mbfl_string string, result, *ret;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ls", &str, &str_len, &from, &len, &encoding, &encoding_len) == FAILURE) {        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|Zs", &str, &str_len, &from, &z_len, &encoding, &encoding_len) == FAILURE) {
                 return;                  return;
         }          }
   
         mbfl_string_init(&string);          mbfl_string_init(&string);
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
        string.no_encoding = MBSTRG(current_internal_encoding);        string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
         if (argc == 4) {          if (argc == 4) {
                 string.no_encoding = mbfl_name2no_encoding(encoding);                  string.no_encoding = mbfl_name2no_encoding(encoding);
Line 2567  PHP_FUNCTION(mb_substr) Line 2737  PHP_FUNCTION(mb_substr)
         string.val = (unsigned char *)str;          string.val = (unsigned char *)str;
         string.len = str_len;          string.len = str_len;
   
        if (argc < 3) {        if (argc < 3 || Z_TYPE_PP(z_len) == IS_NULL) {
                 len = str_len;                  len = str_len;
           } else {
                   convert_to_long_ex(z_len);
                   len = Z_LVAL_PP(z_len);
         }          }
   
         /* measures length */          /* measures length */
Line 2619  PHP_FUNCTION(mb_strcut) Line 2792  PHP_FUNCTION(mb_strcut)
         char *encoding;          char *encoding;
         long from, len;          long from, len;
         int encoding_len;          int encoding_len;
           zval **z_len = NULL;
         mbfl_string string, result, *ret;          mbfl_string string, result, *ret;
   
         mbfl_string_init(&string);          mbfl_string_init(&string);
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
        string.no_encoding = MBSTRG(current_internal_encoding);        string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ls", (char **)&string.val, (int **)&string.len, &from, &len, &encoding, &encoding_len) == FAILURE) {        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|Zs", (char **)&string.val, (int **)&string.len, &from, &z_len, &encoding, &encoding_len) == FAILURE) {
                 return;                  return;
         }          }
   
Line 2637  PHP_FUNCTION(mb_strcut) Line 2811  PHP_FUNCTION(mb_strcut)
                 }                  }
         }          }
   
        if (argc < 3) {        if (argc < 3 || Z_TYPE_PP(z_len) == IS_NULL) {
                 len = string.len;                  len = string.len;
           } else {
                   convert_to_long_ex(z_len);
                   len = Z_LVAL_PP(z_len);
         }          }
   
         /* if "from" position is negative, count start position from the end          /* if "from" position is negative, count start position from the end
Line 2686  PHP_FUNCTION(mb_strwidth) Line 2863  PHP_FUNCTION(mb_strwidth)
         mbfl_string_init(&string);          mbfl_string_init(&string);
   
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
        string.no_encoding = MBSTRG(current_internal_encoding);        string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", (char **)&string.val, &string.len, &enc_name, &enc_name_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", (char **)&string.val, &string.len, &enc_name, &enc_name_len) == FAILURE) {
                 return;                  return;
Line 2725  PHP_FUNCTION(mb_strimwidth) Line 2902  PHP_FUNCTION(mb_strimwidth)
         mbfl_string_init(&string);          mbfl_string_init(&string);
         mbfl_string_init(&marker);          mbfl_string_init(&marker);
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
        string.no_encoding = MBSTRG(current_internal_encoding);        string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         marker.no_language = MBSTRG(language);          marker.no_language = MBSTRG(language);
        marker.no_encoding = MBSTRG(current_internal_encoding);        marker.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         marker.val = NULL;          marker.val = NULL;
         marker.len = 0;          marker.len = 0;
   
Line 2771  PHP_FUNCTION(mb_strimwidth) Line 2948  PHP_FUNCTION(mb_strimwidth)
 MBSTRING_API char * php_mb_convert_encoding(const char *input, size_t length, const char *_to_encoding, const char *_from_encodings, size_t *output_len TSRMLS_DC)  MBSTRING_API char * php_mb_convert_encoding(const char *input, size_t length, const char *_to_encoding, const char *_from_encodings, size_t *output_len TSRMLS_DC)
 {  {
         mbfl_string string, result, *ret;          mbfl_string string, result, *ret;
        enum mbfl_no_encoding from_encoding, to_encoding;        const mbfl_encoding *from_encoding, *to_encoding;
         mbfl_buffer_converter *convd;          mbfl_buffer_converter *convd;
        int size, *list;        size_t size;
         const mbfl_encoding **list;
         char *output=NULL;          char *output=NULL;
   
         if (output_len) {          if (output_len) {
Line 2784  MBSTRING_API char * php_mb_convert_encoding(const char Line 2962  MBSTRING_API char * php_mb_convert_encoding(const char
         }          }
         /* new encoding */          /* new encoding */
         if (_to_encoding && strlen(_to_encoding)) {          if (_to_encoding && strlen(_to_encoding)) {
                to_encoding = mbfl_name2no_encoding(_to_encoding);                to_encoding = mbfl_name2encoding(_to_encoding);
                if (to_encoding == mbfl_no_encoding_invalid) {                if (!to_encoding) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", _to_encoding);                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", _to_encoding);
                         return NULL;                          return NULL;
                 }                  }
Line 2797  MBSTRING_API char * php_mb_convert_encoding(const char Line 2975  MBSTRING_API char * php_mb_convert_encoding(const char
         mbfl_string_init(&string);          mbfl_string_init(&string);
         mbfl_string_init(&result);          mbfl_string_init(&result);
         from_encoding = MBSTRG(current_internal_encoding);          from_encoding = MBSTRG(current_internal_encoding);
        string.no_encoding = from_encoding;        string.no_encoding = from_encoding->no_encoding;
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
         string.val = (unsigned char *)input;          string.val = (unsigned char *)input;
         string.len = length;          string.len = length;
Line 2806  MBSTRING_API char * php_mb_convert_encoding(const char Line 2984  MBSTRING_API char * php_mb_convert_encoding(const char
         if (_from_encodings) {          if (_from_encodings) {
                 list = NULL;                  list = NULL;
                 size = 0;                  size = 0;
            php_mb_parse_encoding_list(_from_encodings, strlen(_from_encodings), &list, &size, 0 TSRMLS_CC);                php_mb_parse_encoding_list(_from_encodings, strlen(_from_encodings), &list, &size, 0 TSRMLS_CC);
                 if (size == 1) {                  if (size == 1) {
                         from_encoding = *list;                          from_encoding = *list;
                        string.no_encoding = from_encoding;                        string.no_encoding = from_encoding->no_encoding;
                 } else if (size > 1) {                  } else if (size > 1) {
                         /* auto detect */                          /* auto detect */
                        from_encoding = mbfl_identify_encoding_no(&string, list, size, MBSTRG(strict_detection));                        from_encoding = mbfl_identify_encoding2(&string, list, size, MBSTRG(strict_detection));
                        if (from_encoding != mbfl_no_encoding_invalid) {                        if (from_encoding) {
                                string.no_encoding = from_encoding;                                string.no_encoding = from_encoding->no_encoding;
                         } else {                          } else {
                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to detect character encoding");                                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to detect character encoding");
                                from_encoding = mbfl_no_encoding_pass;                                from_encoding = &mbfl_encoding_pass;
                                 to_encoding = from_encoding;                                  to_encoding = from_encoding;
                                string.no_encoding = from_encoding;                                string.no_encoding = from_encoding->no_encoding;
                         }                          }
                 } else {                  } else {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal character encoding specified");                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal character encoding specified");
Line 2830  MBSTRING_API char * php_mb_convert_encoding(const char Line 3008  MBSTRING_API char * php_mb_convert_encoding(const char
         }          }
   
         /* initialize converter */          /* initialize converter */
        convd = mbfl_buffer_converter_new(from_encoding, to_encoding, string.len);        convd = mbfl_buffer_converter_new2(from_encoding, to_encoding, string.len);
         if (convd == NULL) {          if (convd == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create character encoding converter");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create character encoding converter");
                 return NULL;                  return NULL;
Line 2931  PHP_FUNCTION(mb_convert_encoding) Line 3109  PHP_FUNCTION(mb_convert_encoding)
    Returns a case-folded version of sourcestring */     Returns a case-folded version of sourcestring */
 PHP_FUNCTION(mb_convert_case)  PHP_FUNCTION(mb_convert_case)
 {  {
        char *str, *from_encoding = (char*)mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));        const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name;
         char *str;
         int str_len, from_encoding_len;          int str_len, from_encoding_len;
         long case_mode = 0;          long case_mode = 0;
         char *newstr;          char *newstr;
Line 2955  PHP_FUNCTION(mb_convert_case) Line 3134  PHP_FUNCTION(mb_convert_case)
  */   */
 PHP_FUNCTION(mb_strtoupper)  PHP_FUNCTION(mb_strtoupper)
 {  {
        char *str, *from_encoding = (char*)mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));        const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name;
         char *str;
         int str_len, from_encoding_len;          int str_len, from_encoding_len;
         char *newstr;          char *newstr;
         size_t ret_len;          size_t ret_len;
Line 2978  PHP_FUNCTION(mb_strtoupper) Line 3158  PHP_FUNCTION(mb_strtoupper)
  */   */
 PHP_FUNCTION(mb_strtolower)  PHP_FUNCTION(mb_strtolower)
 {  {
        char *str, *from_encoding = (char*)mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));        const char *from_encoding = MBSTRG(current_internal_encoding)->mime_name;
         char *str;
         int str_len, from_encoding_len;          int str_len, from_encoding_len;
         char *newstr;          char *newstr;
         size_t ret_len;          size_t ret_len;
Line 3006  PHP_FUNCTION(mb_detect_encoding) Line 3187  PHP_FUNCTION(mb_detect_encoding)
         zval *encoding_list;          zval *encoding_list;
   
         mbfl_string string;          mbfl_string string;
        const char *ret;        const mbfl_encoding *ret;
        enum mbfl_no_encoding *elist;        const mbfl_encoding **elist, **list;
        int size, *list;        size_t size;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zb", &str, &str_len, &encoding_list, &strict) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zb", &str, &str_len, &encoding_list, &strict) == FAILURE) {
                 return;                  return;
Line 3020  PHP_FUNCTION(mb_detect_encoding) Line 3201  PHP_FUNCTION(mb_detect_encoding)
         if (ZEND_NUM_ARGS() >= 2 && !ZVAL_IS_NULL(encoding_list)) {          if (ZEND_NUM_ARGS() >= 2 && !ZVAL_IS_NULL(encoding_list)) {
                 switch (Z_TYPE_P(encoding_list)) {                  switch (Z_TYPE_P(encoding_list)) {
                 case IS_ARRAY:                  case IS_ARRAY:
                        if (!php_mb_parse_encoding_array(encoding_list, &list, &size, 0 TSRMLS_CC)) {                        if (FAILURE == php_mb_parse_encoding_array(encoding_list, &list, &size, 0 TSRMLS_CC)) {
                                 if (list) {                                  if (list) {
                                         efree(list);                                          efree(list);
                                         list = NULL;                                          list = NULL;
Line 3030  PHP_FUNCTION(mb_detect_encoding) Line 3211  PHP_FUNCTION(mb_detect_encoding)
                         break;                          break;
                 default:                  default:
                         convert_to_string(encoding_list);                          convert_to_string(encoding_list);
                        if (!php_mb_parse_encoding_list(Z_STRVAL_P(encoding_list), Z_STRLEN_P(encoding_list), &list, &size, 0 TSRMLS_CC)) {                        if (FAILURE == php_mb_parse_encoding_list(Z_STRVAL_P(encoding_list), Z_STRLEN_P(encoding_list), &list, &size, 0 TSRMLS_CC)) {
                                 if (list) {                                  if (list) {
                                         efree(list);                                          efree(list);
                                         list = NULL;                                          list = NULL;
Line 3059  PHP_FUNCTION(mb_detect_encoding) Line 3240  PHP_FUNCTION(mb_detect_encoding)
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
         string.val = (unsigned char *)str;          string.val = (unsigned char *)str;
         string.len = str_len;          string.len = str_len;
        ret = mbfl_identify_encoding_name(&string, elist, size, strict);        ret = mbfl_identify_encoding2(&string, elist, size, strict);
   
         if (list != NULL) {          if (list != NULL) {
                 efree((void *)list);                  efree((void *)list);
Line 3069  PHP_FUNCTION(mb_detect_encoding) Line 3250  PHP_FUNCTION(mb_detect_encoding)
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
   
        RETVAL_STRING((char *)ret, 1);        RETVAL_STRING((char *)ret->name, 1);
 }  }
 /* }}} */  /* }}} */
   
Line 3134  PHP_FUNCTION(mb_encode_mimeheader) Line 3315  PHP_FUNCTION(mb_encode_mimeheader)
   
         mbfl_string_init(&string);          mbfl_string_init(&string);
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
        string.no_encoding = MBSTRG(current_internal_encoding);        string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sssl", (char **)&string.val, &string.len, &charset_name, &charset_name_len, &trans_enc_name, &trans_enc_name_len, &linefeed, &linefeed_len, &indent) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sssl", (char **)&string.val, &string.len, &charset_name, &charset_name_len, &trans_enc_name, &trans_enc_name_len, &linefeed, &linefeed_len, &indent) == FAILURE) {
                 return;                  return;
Line 3168  PHP_FUNCTION(mb_encode_mimeheader) Line 3349  PHP_FUNCTION(mb_encode_mimeheader)
         mbfl_string_init(&result);          mbfl_string_init(&result);
         ret = mbfl_mime_header_encode(&string, &result, charset, transenc, linefeed, indent);          ret = mbfl_mime_header_encode(&string, &result, charset, transenc, linefeed, indent);
         if (ret != NULL) {          if (ret != NULL) {
                RETVAL_STRINGL((char *)ret->val, ret->len, 0)   /* the string is already strdup()'ed */                RETVAL_STRINGL((char *)ret->val, ret->len, 0);        /* the string is already strdup()'ed */
         } else {          } else {
                 RETVAL_FALSE;                  RETVAL_FALSE;
         }          }
Line 3183  PHP_FUNCTION(mb_decode_mimeheader) Line 3364  PHP_FUNCTION(mb_decode_mimeheader)
   
         mbfl_string_init(&string);          mbfl_string_init(&string);
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
        string.no_encoding = MBSTRG(current_internal_encoding);        string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", (char **)&string.val, &string.len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", (char **)&string.val, &string.len) == FAILURE) {
                 return;                  return;
         }          }
   
         mbfl_string_init(&result);          mbfl_string_init(&result);
        ret = mbfl_mime_header_decode(&string, &result, MBSTRG(current_internal_encoding));        ret = mbfl_mime_header_decode(&string, &result, MBSTRG(current_internal_encoding)->no_encoding);
         if (ret != NULL) {          if (ret != NULL) {
                RETVAL_STRINGL((char *)ret->val, ret->len, 0)   /* the string is already strdup()'ed */                RETVAL_STRINGL((char *)ret->val, ret->len, 0);        /* the string is already strdup()'ed */
         } else {          } else {
                 RETVAL_FALSE;                  RETVAL_FALSE;
         }          }
Line 3212  PHP_FUNCTION(mb_convert_kana) Line 3393  PHP_FUNCTION(mb_convert_kana)
   
         mbfl_string_init(&string);          mbfl_string_init(&string);
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
        string.no_encoding = MBSTRG(current_internal_encoding);        string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ss", (char **)&string.val, &string.len, &optstr, &optstr_len, &encname, &encname_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ss", (char **)&string.val, &string.len, &optstr, &optstr_len, &encname, &encname_len) == FAILURE) {
                 return;                  return;
Line 3311  PHP_FUNCTION(mb_convert_variables) Line 3492  PHP_FUNCTION(mb_convert_variables)
         zval ***args, ***stack, **var, **hash_entry, **zfrom_enc;          zval ***args, ***stack, **var, **hash_entry, **zfrom_enc;
         HashTable *target_hash;          HashTable *target_hash;
         mbfl_string string, result, *ret;          mbfl_string string, result, *ret;
        enum mbfl_no_encoding from_encoding, to_encoding;        const mbfl_encoding *from_encoding, *to_encoding;
         mbfl_encoding_detector *identd;          mbfl_encoding_detector *identd;
         mbfl_buffer_converter *convd;          mbfl_buffer_converter *convd;
        int n, to_enc_len, argc, stack_level, stack_max, elistsz;        int n, to_enc_len, argc, stack_level, stack_max;
        enum mbfl_no_encoding *elist;        size_t elistsz;
        char *name, *to_enc;        const mbfl_encoding **elist;
         char *to_enc;
         void *ptmp;               void *ptmp;     
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ+", &to_enc, &to_enc_len, &zfrom_enc, &args, &argc) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ+", &to_enc, &to_enc_len, &zfrom_enc, &args, &argc) == FAILURE) {
                 return;                  return;
         }          }
   
         /* new encoding */          /* new encoding */
        to_encoding = mbfl_name2no_encoding(to_enc);        to_encoding = mbfl_name2encoding(to_enc);
        if (to_encoding == mbfl_no_encoding_invalid) {        if (!to_encoding) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", to_enc);                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", to_enc);
                 efree(args);                  efree(args);
                 RETURN_FALSE;                  RETURN_FALSE;
Line 3335  PHP_FUNCTION(mb_convert_variables) Line 3517  PHP_FUNCTION(mb_convert_variables)
         mbfl_string_init(&string);          mbfl_string_init(&string);
         mbfl_string_init(&result);          mbfl_string_init(&result);
         from_encoding = MBSTRG(current_internal_encoding);          from_encoding = MBSTRG(current_internal_encoding);
        string.no_encoding = from_encoding;        string.no_encoding = from_encoding->no_encoding;
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
   
         /* pre-conversion encoding */          /* pre-conversion encoding */
Line 3351  PHP_FUNCTION(mb_convert_variables) Line 3533  PHP_FUNCTION(mb_convert_variables)
                 break;                  break;
         }          }
         if (elistsz <= 0) {          if (elistsz <= 0) {
                from_encoding = mbfl_no_encoding_pass;                from_encoding = &mbfl_encoding_pass;
         } else if (elistsz == 1) {          } else if (elistsz == 1) {
                 from_encoding = *elist;                  from_encoding = *elist;
         } else {          } else {
                 /* auto detect */                  /* auto detect */
                from_encoding = mbfl_no_encoding_invalid;                from_encoding = NULL;
                 stack_max = PHP_MBSTR_STACK_BLOCK_SIZE;                  stack_max = PHP_MBSTR_STACK_BLOCK_SIZE;
                 stack = (zval ***)safe_emalloc(stack_max, sizeof(zval **), 0);                  stack = (zval ***)safe_emalloc(stack_max, sizeof(zval **), 0);
                 stack_level = 0;                  stack_level = 0;
                identd = mbfl_encoding_detector_new(elist, elistsz, MBSTRG(strict_detection));                identd = mbfl_encoding_detector_new2(elist, elistsz, MBSTRG(strict_detection));
                 if (identd != NULL) {                  if (identd != NULL) {
                         n = 0;                          n = 0;
                         while (n < argc || stack_level > 0) {                          while (n < argc || stack_level > 0) {
Line 3413  PHP_FUNCTION(mb_convert_variables) Line 3595  PHP_FUNCTION(mb_convert_variables)
                                 }                                  }
                         }                          }
 detect_end:  detect_end:
                        from_encoding = mbfl_encoding_detector_judge(identd);                        from_encoding = mbfl_encoding_detector_judge2(identd);
                         mbfl_encoding_detector_delete(identd);                          mbfl_encoding_detector_delete(identd);
                 }                  }
                 efree(stack);                  efree(stack);
   
                if (from_encoding == mbfl_no_encoding_invalid) {                if (!from_encoding) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to detect encoding");                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to detect encoding");
                        from_encoding = mbfl_no_encoding_pass;                        from_encoding = &mbfl_encoding_pass;
                 }                  }
         }          }
         if (elist != NULL) {          if (elist != NULL) {
Line 3428  detect_end: Line 3610  detect_end:
         }          }
         /* create converter */          /* create converter */
         convd = NULL;          convd = NULL;
        if (from_encoding != mbfl_no_encoding_pass) {        if (from_encoding != &mbfl_encoding_pass) {
                convd = mbfl_buffer_converter_new(from_encoding, to_encoding, 0);                convd = mbfl_buffer_converter_new2(from_encoding, to_encoding, 0);
                 if (convd == NULL) {                  if (convd == NULL) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create converter");                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create converter");
                         RETURN_FALSE;                          RETURN_FALSE;
Line 3511  detect_end: Line 3693  detect_end:
   
         efree(args);          efree(args);
   
        name = (char *)mbfl_no_encoding2name(from_encoding);        if (from_encoding) {
        if (name != NULL) {                RETURN_STRING(from_encoding->name, 1);
                RETURN_STRING(name, 1); 
         } else {          } else {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
Line 3531  php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS Line 3712  php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS
         HashTable *target_hash;          HashTable *target_hash;
         size_t argc = ZEND_NUM_ARGS();          size_t argc = ZEND_NUM_ARGS();
         int i, *convmap, *mapelm, mapsize=0;          int i, *convmap, *mapelm, mapsize=0;
           zend_bool is_hex = 0;
         mbfl_string string, result, *ret;          mbfl_string string, result, *ret;
         enum mbfl_no_encoding no_encoding;          enum mbfl_no_encoding no_encoding;
   
        if (zend_parse_parameters(argc TSRMLS_CC, "szs", &str, &str_len, &zconvmap, &encoding, &encoding_len) == FAILURE) {        if (zend_parse_parameters(argc TSRMLS_CC, "sz|sb", &str, &str_len, &zconvmap, &encoding, &encoding_len, &is_hex) == FAILURE) {
                 return;                  return;
         }          }
   
         mbfl_string_init(&string);          mbfl_string_init(&string);
         string.no_language = MBSTRG(language);          string.no_language = MBSTRG(language);
        string.no_encoding = MBSTRG(current_internal_encoding);        string.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         string.val = (unsigned char *)str;          string.val = (unsigned char *)str;
         string.len = str_len;          string.len = str_len;
   
         /* encoding */          /* encoding */
        if (argc == 3) {        if ((argc == 3 || argc == 4) && encoding_len > 0) {
                 no_encoding = mbfl_name2no_encoding(encoding);                  no_encoding = mbfl_name2no_encoding(encoding);
                 if (no_encoding == mbfl_no_encoding_invalid) {                  if (no_encoding == mbfl_no_encoding_invalid) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encoding);                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encoding);
Line 3555  php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS Line 3737  php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS
                 }                  }
         }          }
   
           if (argc == 4) {
                   if (type == 0 && is_hex) {
                           type = 2; /* output in hex format */
                   }
           }
   
         /* conversion map */          /* conversion map */
         convmap = NULL;          convmap = NULL;
         if (Z_TYPE_P(zconvmap) == IS_ARRAY) {          if (Z_TYPE_P(zconvmap) == IS_ARRAY) {
Line 3592  php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS Line 3780  php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS
 }  }
 /* }}} */  /* }}} */
   
/* {{{ proto string mb_encode_numericentity(string string, array convmap [, string encoding])/* {{{ proto string mb_encode_numericentity(string string, array convmap [, string encoding [, bool is_hex]])
    Converts specified characters to HTML numeric entities */     Converts specified characters to HTML numeric entities */
 PHP_FUNCTION(mb_encode_numericentity)  PHP_FUNCTION(mb_encode_numericentity)
 {  {
Line 3852  PHP_FUNCTION(mb_send_mail) Line 4040  PHP_FUNCTION(mb_send_mail)
         mbfl_string orig_str, conv_str;          mbfl_string orig_str, conv_str;
         mbfl_string *pstr;      /* pointer to mbfl string for return value */          mbfl_string *pstr;      /* pointer to mbfl string for return value */
         enum mbfl_no_encoding          enum mbfl_no_encoding
            tran_cs,    /* transfar text charset */                tran_cs,        /* transfar text charset */
            head_enc,   /* header transfar encoding */                head_enc,       /* header transfar encoding */
            body_enc;   /* body transfar encoding */                body_enc;       /* body transfar encoding */
         mbfl_memory_device device;      /* automatic allocateable buffer for additional header */          mbfl_memory_device device;      /* automatic allocateable buffer for additional header */
         const mbfl_language *lang;          const mbfl_language *lang;
         int err = 0;          int err = 0;
Line 3862  PHP_FUNCTION(mb_send_mail) Line 4050  PHP_FUNCTION(mb_send_mail)
         smart_str *s;          smart_str *s;
         extern void mbfl_memory_device_unput(mbfl_memory_device *device);          extern void mbfl_memory_device_unput(mbfl_memory_device *device);
         char *pp, *ee;          char *pp, *ee;
    
        if (PG(safe_mode) && (ZEND_NUM_ARGS() == 5)) { 
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect.  The fifth parameter is disabled in SAFE MODE."); 
                RETURN_FALSE; 
        } 
     
         /* initialize */          /* initialize */
         mbfl_memory_device_init(&device, 0, 0);          mbfl_memory_device_init(&device, 0, 0);
         mbfl_string_init(&orig_str);          mbfl_string_init(&orig_str);
Line 3966  PHP_FUNCTION(mb_send_mail) Line 4149  PHP_FUNCTION(mb_send_mail)
   
         /* To: */          /* To: */
         if (to != NULL) {          if (to != NULL) {
        if (to_len > 0) {                if (to_len > 0) {
            to_r = estrndup(to, to_len);                        to_r = estrndup(to, to_len);
            for (; to_len; to_len--) {                        for (; to_len; to_len--) {
                if (!isspace((unsigned char) to_r[to_len - 1])) {                                if (!isspace((unsigned char) to_r[to_len - 1])) {
                    break;                                        break;
                }                                }
                to_r[to_len - 1] = '\0';                                to_r[to_len - 1] = '\0';
            }                        }
            for (i = 0; to_r[i]; i++) {                        for (i = 0; to_r[i]; i++) {
                         if (iscntrl((unsigned char) to_r[i])) {                          if (iscntrl((unsigned char) to_r[i])) {
                                 /* According to RFC 822, section 3.1.1 long headers may be separated into                                  /* According to RFC 822, section 3.1.1 long headers may be separated into
                                  * parts using CRLF followed at least one linear-white-space character ('\t' or ' ').                                   * parts using CRLF followed at least one linear-white-space character ('\t' or ' ').
Line 3984  PHP_FUNCTION(mb_send_mail) Line 4167  PHP_FUNCTION(mb_send_mail)
                                 SKIP_LONG_HEADER_SEP_MBSTRING(to_r, i);                                  SKIP_LONG_HEADER_SEP_MBSTRING(to_r, i);
                                 to_r[i] = ' ';                                  to_r[i] = ' ';
                         }                          }
            }                        }
        } else {                } else {
            to_r = to;                        to_r = to;
        }                }
    } else {        } else {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing To: field");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing To: field");
                 err = 1;                  err = 1;
         }          }
Line 3998  PHP_FUNCTION(mb_send_mail) Line 4181  PHP_FUNCTION(mb_send_mail)
                 orig_str.no_language = MBSTRG(language);                  orig_str.no_language = MBSTRG(language);
                 orig_str.val = (unsigned char *)subject;                  orig_str.val = (unsigned char *)subject;
                 orig_str.len = subject_len;                  orig_str.len = subject_len;
                orig_str.no_encoding = MBSTRG(current_internal_encoding);                orig_str.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
                if (orig_str.no_encoding == mbfl_no_encoding_invalid                if (orig_str.no_encoding == mbfl_no_encoding_invalid || orig_str.no_encoding == mbfl_no_encoding_pass) {
                    || orig_str.no_encoding == mbfl_no_encoding_pass) {                        const mbfl_encoding *encoding = mbfl_identify_encoding2(&orig_str, MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size), MBSTRG(strict_detection));
                        orig_str.no_encoding = mbfl_identify_encoding_no(&orig_str, MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size), MBSTRG(strict_detection));                        orig_str.no_encoding = encoding ? encoding->no_encoding: mbfl_no_encoding_invalid;
                 }                  }
                 pstr = mbfl_mime_header_encode(&orig_str, &conv_str, tran_cs, head_enc, "\n", sizeof("Subject: [PHP-jp nnnnnnnn]"));                  pstr = mbfl_mime_header_encode(&orig_str, &conv_str, tran_cs, head_enc, "\n", sizeof("Subject: [PHP-jp nnnnnnnn]"));
                 if (pstr != NULL) {                  if (pstr != NULL) {
Line 4017  PHP_FUNCTION(mb_send_mail) Line 4200  PHP_FUNCTION(mb_send_mail)
                 orig_str.no_language = MBSTRG(language);                  orig_str.no_language = MBSTRG(language);
                 orig_str.val = (unsigned char *)message;                  orig_str.val = (unsigned char *)message;
                 orig_str.len = (unsigned int)message_len;                  orig_str.len = (unsigned int)message_len;
                orig_str.no_encoding = MBSTRG(current_internal_encoding);                orig_str.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
                if (orig_str.no_encoding == mbfl_no_encoding_invalid                if (orig_str.no_encoding == mbfl_no_encoding_invalid || orig_str.no_encoding == mbfl_no_encoding_pass) {
                    || orig_str.no_encoding == mbfl_no_encoding_pass) {                        const mbfl_encoding *encoding = mbfl_identify_encoding2(&orig_str, MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size), MBSTRG(strict_detection));
                        orig_str.no_encoding = mbfl_identify_encoding_no(&orig_str, MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size), MBSTRG(strict_detection));                        orig_str.no_encoding = encoding ? encoding->no_encoding: mbfl_no_encoding_invalid;
                 }                  }
   
                 pstr = NULL;                  pstr = NULL;
Line 4129  PHP_FUNCTION(mb_send_mail) Line 4312  PHP_FUNCTION(mb_send_mail)
 PHP_FUNCTION(mb_get_info)  PHP_FUNCTION(mb_get_info)
 {  {
         char *typ = NULL;          char *typ = NULL;
        int typ_len, n;        int typ_len;
         size_t n;
         char *name;          char *name;
         const struct mb_overload_def *over_func;          const struct mb_overload_def *over_func;
         zval *row1, *row2;          zval *row1, *row2;
         const mbfl_language *lang = mbfl_no2language(MBSTRG(language));          const mbfl_language *lang = mbfl_no2language(MBSTRG(language));
        enum mbfl_no_encoding *entry;        const mbfl_encoding **entry;
#ifdef ZEND_MULTIBYTE 
        zval *row3; 
#endif /* ZEND_MULTIBYTE */ 
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &typ, &typ_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &typ, &typ_len) == FAILURE) {
                 RETURN_FALSE;                  RETURN_FALSE;
Line 4145  PHP_FUNCTION(mb_get_info) Line 4326  PHP_FUNCTION(mb_get_info)
   
         if (!typ || !strcasecmp("all", typ)) {          if (!typ || !strcasecmp("all", typ)) {
                 array_init(return_value);                  array_init(return_value);
                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(current_internal_encoding))) != NULL) {                if (MBSTRG(current_internal_encoding)) {
                        add_assoc_string(return_value, "internal_encoding", name, 1);                        add_assoc_string(return_value, "internal_encoding", (char *)MBSTRG(current_internal_encoding)->name, 1);
                 }                  }
                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(http_input_identify))) != NULL) {                if (MBSTRG(http_input_identify)) {
                        add_assoc_string(return_value, "http_input", name, 1);                        add_assoc_string(return_value, "http_input", (char *)MBSTRG(http_input_identify)->name, 1);
                 }                  }
                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(current_http_output_encoding))) != NULL) {                if (MBSTRG(current_http_output_encoding)) {
                        add_assoc_string(return_value, "http_output", name, 1);                        add_assoc_string(return_value, "http_output", (char *)MBSTRG(current_http_output_encoding)->name, 1);
                 }                  }
                 if ((name = (char *)zend_ini_string("mbstring.http_output_conv_mimetypes", sizeof("mbstring.http_output_conv_mimetypes"), 0)) != NULL) {                  if ((name = (char *)zend_ini_string("mbstring.http_output_conv_mimetypes", sizeof("mbstring.http_output_conv_mimetypes"), 0)) != NULL) {
                         add_assoc_string(return_value, "http_output_conv_mimetypes", name, 1);                          add_assoc_string(return_value, "http_output_conv_mimetypes", name, 1);
Line 4194  PHP_FUNCTION(mb_get_info) Line 4375  PHP_FUNCTION(mb_get_info)
                 }                                 }               
                 n = MBSTRG(current_detect_order_list_size);                  n = MBSTRG(current_detect_order_list_size);
                 entry = MBSTRG(current_detect_order_list);                  entry = MBSTRG(current_detect_order_list);
                if(n > 0) {                if (n > 0) {
                         size_t i;
                         MAKE_STD_ZVAL(row2);                          MAKE_STD_ZVAL(row2);
                         array_init(row2);                          array_init(row2);
                        while (n > 0) {                        for (i = 0; i < n; i++) {
                                if ((name = (char *)mbfl_no_encoding2name(*entry)) != NULL) {                                add_next_index_string(row2, (*entry)->name, 1);
                                        add_next_index_string(row2, name, 1); 
                                } 
                                 entry++;                                  entry++;
                                 n--;  
                         }                          }
                         add_assoc_zval(return_value, "detect_order", row2);                          add_assoc_zval(return_value, "detect_order", row2);
                 }                  }
Line 4220  PHP_FUNCTION(mb_get_info) Line 4399  PHP_FUNCTION(mb_get_info)
                 } else {                  } else {
                         add_assoc_string(return_value, "strict_detection", "Off", 1);                          add_assoc_string(return_value, "strict_detection", "Off", 1);
                 }                  }
 #ifdef ZEND_MULTIBYTE  
                 entry = MBSTRG(script_encoding_list);  
                 n = MBSTRG(script_encoding_list_size);  
                 if(n > 0) {  
                         MAKE_STD_ZVAL(row3);  
                         array_init(row3);  
                         while (n > 0) {  
                                 if ((name = (char *)mbfl_no_encoding2name(*entry)) != NULL) {  
                                         add_next_index_string(row3, name, 1);  
                                 }  
                                 entry++;  
                                 n--;  
                         }  
                         add_assoc_zval(return_value, "script_encoding", row3);  
                 }  
 #endif /* ZEND_MULTIBYTE */  
         } else if (!strcasecmp("internal_encoding", typ)) {          } else if (!strcasecmp("internal_encoding", typ)) {
                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(current_internal_encoding))) != NULL) {                if (MBSTRG(current_internal_encoding)) {
                        RETVAL_STRING(name, 1);                        RETVAL_STRING((char *)MBSTRG(current_internal_encoding)->name, 1);
                 }                                 }               
         } else if (!strcasecmp("http_input", typ)) {          } else if (!strcasecmp("http_input", typ)) {
                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(http_input_identify))) != NULL) {                if (MBSTRG(http_input_identify)) {
                        RETVAL_STRING(name, 1);                        RETVAL_STRING((char *)MBSTRG(http_input_identify)->name, 1);
                 }                                 }               
         } else if (!strcasecmp("http_output", typ)) {          } else if (!strcasecmp("http_output", typ)) {
                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(current_http_output_encoding))) != NULL) {                if (MBSTRG(current_http_output_encoding)) {
                        RETVAL_STRING(name, 1);                        RETVAL_STRING((char *)MBSTRG(current_http_output_encoding)->name, 1);
                 }                                 }               
         } else if (!strcasecmp("http_output_conv_mimetypes", typ)) {          } else if (!strcasecmp("http_output_conv_mimetypes", typ)) {
                 if ((name = (char *)zend_ini_string("mbstring.http_output_conv_mimetypes", sizeof("mbstring.http_output_conv_mimetypes"), 0)) != NULL) {                  if ((name = (char *)zend_ini_string("mbstring.http_output_conv_mimetypes", sizeof("mbstring.http_output_conv_mimetypes"), 0)) != NULL) {
Line 4294  PHP_FUNCTION(mb_get_info) Line 4457  PHP_FUNCTION(mb_get_info)
         } else if (!strcasecmp("detect_order", typ)) {          } else if (!strcasecmp("detect_order", typ)) {
                 n = MBSTRG(current_detect_order_list_size);                  n = MBSTRG(current_detect_order_list_size);
                 entry = MBSTRG(current_detect_order_list);                  entry = MBSTRG(current_detect_order_list);
                if(n > 0) {                if (n > 0) {
                         size_t i;
                         array_init(return_value);                          array_init(return_value);
                        while (n > 0) {                        for (i = 0; i < n; i++) {
                                name = (char *)mbfl_no_encoding2name(*entry);                                add_next_index_string(return_value, (*entry)->name, 1);
                                if (name) { 
                                        add_next_index_string(return_value, name, 1); 
                                } 
                                 entry++;                                  entry++;
                                 n--;  
                         }                          }
                 }                  }
         } else if (!strcasecmp("substitute_character", typ)) {          } else if (!strcasecmp("substitute_character", typ)) {
Line 4322  PHP_FUNCTION(mb_get_info) Line 4482  PHP_FUNCTION(mb_get_info)
                         RETVAL_STRING("Off", 1);                          RETVAL_STRING("Off", 1);
                 }                  }
         } else {          } else {
 #ifdef ZEND_MULTIBYTE  
         if (!strcasecmp("script_encoding", typ)) {  
                 entry = MBSTRG(script_encoding_list);  
                 n = MBSTRG(script_encoding_list_size);  
                 if(n > 0) {  
                         array_init(return_value);  
                         while (n > 0) {  
                                 name = (char *)mbfl_no_encoding2name(*entry);  
                                 if (name) {  
                                         add_next_index_string(return_value, name, 1);  
                                 }  
                                 entry++;  
                                 n--;  
                         }  
                 }  
                 return;  
         }  
 #endif /* ZEND_MULTIBYTE */  
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
 }  }
Line 4354  PHP_FUNCTION(mb_check_encoding) Line 4496  PHP_FUNCTION(mb_check_encoding)
         char *enc = NULL;          char *enc = NULL;
         int enc_len;          int enc_len;
         mbfl_buffer_converter *convd;          mbfl_buffer_converter *convd;
        enum mbfl_no_encoding no_encoding = MBSTRG(current_internal_encoding);        const mbfl_encoding *encoding = MBSTRG(current_internal_encoding);
         mbfl_string string, result, *ret = NULL;          mbfl_string string, result, *ret = NULL;
         long illegalchars = 0;          long illegalchars = 0;
   
Line 4367  PHP_FUNCTION(mb_check_encoding) Line 4509  PHP_FUNCTION(mb_check_encoding)
         }          }
   
         if (enc != NULL) {          if (enc != NULL) {
                no_encoding = mbfl_name2no_encoding(enc);                encoding = mbfl_name2encoding(enc);
                if (no_encoding == mbfl_no_encoding_invalid || no_encoding == mbfl_no_encoding_pass) {                if (!encoding || encoding == &mbfl_encoding_pass) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid encoding \"%s\"", enc);                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid encoding \"%s\"", enc);
                         RETURN_FALSE;                          RETURN_FALSE;
                 }                  }
         }          }
        
        convd = mbfl_buffer_converter_new(no_encoding, no_encoding, 0);        convd = mbfl_buffer_converter_new2(encoding, encoding, 0);
         if (convd == NULL) {          if (convd == NULL) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create converter");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create converter");
                 RETURN_FALSE;                  RETURN_FALSE;
         }                 }       
         mbfl_buffer_converter_illegal_mode(convd, MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE);          mbfl_buffer_converter_illegal_mode(convd, MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE);
         mbfl_buffer_converter_illegal_substchar(convd, 0);                mbfl_buffer_converter_illegal_substchar(convd, 0);      
        
         /* initialize string */          /* initialize string */
        mbfl_string_init_set(&string, mbfl_no_language_neutral, no_encoding);        mbfl_string_init_set(&string, mbfl_no_language_neutral, encoding->no_encoding);
         mbfl_string_init(&result);          mbfl_string_init(&result);
   
         string.val = (unsigned char *)var;          string.val = (unsigned char *)var;
Line 4402  PHP_FUNCTION(mb_check_encoding) Line 4544  PHP_FUNCTION(mb_check_encoding)
 }  }
 /* }}} */  /* }}} */
   
/* {{{ MBSTRING_API int php_mb_encoding_translation() */
MBSTRING_API int php_mb_encoding_translation(TSRMLS_D) /* {{{ php_mb_populate_current_detect_order_list */
 static void php_mb_populate_current_detect_order_list(TSRMLS_D)
 {  {
           const mbfl_encoding **entry = 0;
           size_t nentries;
   
           if (MBSTRG(current_detect_order_list)) {
                   return;
           }
   
           if (MBSTRG(detect_order_list) && MBSTRG(detect_order_list_size)) {
                   nentries = MBSTRG(detect_order_list_size);
                   entry = (const mbfl_encoding **)safe_emalloc(nentries, sizeof(mbfl_encoding*), 0);
                   memcpy(entry, MBSTRG(detect_order_list), sizeof(mbfl_encoding*) * nentries);
           } else {
                   const enum mbfl_no_encoding *src = MBSTRG(default_detect_order_list);
                   size_t i;
                   nentries = MBSTRG(default_detect_order_list_size);
                   entry = (const mbfl_encoding **)safe_emalloc(nentries, sizeof(mbfl_encoding*), 0);
                   for (i = 0; i < nentries; i++) {
                           entry[i] = mbfl_no2encoding(src[i]);
                   }
           }
           MBSTRG(current_detect_order_list) = entry;
           MBSTRG(current_detect_order_list_size) = nentries;
   }
   
   /* {{{ static int php_mb_encoding_translation() */
   static int php_mb_encoding_translation(TSRMLS_D) 
   {
         return MBSTRG(encoding_translation);          return MBSTRG(encoding_translation);
 }  }
 /* }}} */  /* }}} */
Line 4430  MBSTRING_API size_t php_mb_mbchar_bytes_ex(const char  Line 4600  MBSTRING_API size_t php_mb_mbchar_bytes_ex(const char 
 /* {{{ MBSTRING_API size_t php_mb_mbchar_bytes() */  /* {{{ MBSTRING_API size_t php_mb_mbchar_bytes() */
 MBSTRING_API size_t php_mb_mbchar_bytes(const char *s TSRMLS_DC)  MBSTRING_API size_t php_mb_mbchar_bytes(const char *s TSRMLS_DC)
 {  {
        return php_mb_mbchar_bytes_ex(s,        return php_mb_mbchar_bytes_ex(s, MBSTRG(internal_encoding));
                mbfl_no2encoding(MBSTRG(internal_encoding))); 
 }  }
 /* }}} */  /* }}} */
   
Line 4479  MBSTRING_API char *php_mb_safe_strrchr_ex(const char * Line 4648  MBSTRING_API char *php_mb_safe_strrchr_ex(const char *
 /* {{{ MBSTRING_API char *php_mb_safe_strrchr() */  /* {{{ MBSTRING_API char *php_mb_safe_strrchr() */
 MBSTRING_API char *php_mb_safe_strrchr(const char *s, unsigned int c, size_t nbytes TSRMLS_DC)  MBSTRING_API char *php_mb_safe_strrchr(const char *s, unsigned int c, size_t nbytes TSRMLS_DC)
 {  {
        return php_mb_safe_strrchr_ex(s, c, nbytes,        return php_mb_safe_strrchr_ex(s, c, nbytes, MBSTRG(internal_encoding));
                mbfl_no2encoding(MBSTRG(internal_encoding))); 
 }  }
 /* }}} */  /* }}} */
   
 /* {{{ MBSTRING_API char *php_mb_strrchr() */  
 MBSTRING_API char *php_mb_strrchr(const char *s, char c TSRMLS_DC)  
 {  
         return php_mb_safe_strrchr(s, c, -1 TSRMLS_CC);  
 }  
 /* }}} */  
   
 /* {{{ MBSTRING_API size_t php_mb_gpc_mbchar_bytes() */  
 MBSTRING_API size_t php_mb_gpc_mbchar_bytes(const char *s TSRMLS_DC)  
 {  
   
         if (MBSTRG(http_input_identify) != mbfl_no_encoding_invalid){  
                 return php_mb_mbchar_bytes_ex(s,  
                 mbfl_no2encoding(MBSTRG(http_input_identify)));  
         } else {  
                 return php_mb_mbchar_bytes_ex(s,  
                 mbfl_no2encoding(MBSTRG(internal_encoding)));  
         }  
 }  
 /* }}} */  
   
 /*      {{{ MBSTRING_API int php_mb_gpc_encoding_converter() */  
 MBSTRING_API int php_mb_gpc_encoding_converter(char **str, int *len, int num, const char *encoding_to, const char *encoding_from TSRMLS_DC)  
 {  
         int i;  
         mbfl_string string, result, *ret = NULL;  
         enum mbfl_no_encoding from_encoding, to_encoding;  
         mbfl_buffer_converter *convd;  
   
         if (encoding_to) {  
                 /* new encoding */  
                 to_encoding = mbfl_name2no_encoding(encoding_to);  
                 if (to_encoding == mbfl_no_encoding_invalid) {  
                         return -1;  
                 }  
         } else {  
                 to_encoding = MBSTRG(current_internal_encoding);  
         }         
         if (encoding_from) {  
                 /* old encoding */  
                 from_encoding = mbfl_name2no_encoding(encoding_from);  
                 if (from_encoding == mbfl_no_encoding_invalid) {  
                         return -1;  
                 }  
         } else {  
                 from_encoding = MBSTRG(http_input_identify);  
         }  
   
         if (from_encoding == mbfl_no_encoding_pass) {  
                 return 0;  
         }  
   
         /* initialize string */  
         mbfl_string_init(&string);  
         mbfl_string_init(&result);  
         string.no_encoding = from_encoding;  
         string.no_language = MBSTRG(language);  
   
         for (i=0; i<num; i++){  
                 string.val = (unsigned char *)str[i];  
                 string.len = len[i];  
   
                 /* initialize converter */  
                 convd = mbfl_buffer_converter_new(from_encoding, to_encoding, string.len);  
                 if (convd == NULL) {  
                         return -1;  
                 }  
                 mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode));  
                 mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));  
                   
                 /* do it */  
                 ret = mbfl_buffer_converter_feed_result(convd, &string, &result);  
                 if (ret != NULL) {  
                         efree(str[i]);  
                         str[i] = (char *)ret->val;  
                         len[i] = (int)ret->len;  
                 }  
                   
                 MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd);  
                 mbfl_buffer_converter_delete(convd);  
         }  
   
         return ret ? 0 : -1;  
 }  
 /* }}} */  
   
 /* {{{ MBSTRING_API int php_mb_gpc_encoding_detector()  
  */  
 MBSTRING_API int php_mb_gpc_encoding_detector(char **arg_string, int *arg_length, int num, char *arg_list TSRMLS_DC)  
 {  
         mbfl_string string;  
         enum mbfl_no_encoding *elist;  
         enum mbfl_no_encoding encoding = mbfl_no_encoding_invalid;  
         mbfl_encoding_detector *identd = NULL;   
   
         int size;  
         enum mbfl_no_encoding *list;  
   
         if (MBSTRG(http_input_list_size) == 1 &&   
                 MBSTRG(http_input_list)[0] == mbfl_no_encoding_pass) {  
                 MBSTRG(http_input_identify) = mbfl_no_encoding_pass;  
                 return SUCCESS;  
         }  
   
         if (MBSTRG(http_input_list_size) == 1 &&   
                 MBSTRG(http_input_list)[0] != mbfl_no_encoding_auto &&  
                 mbfl_no_encoding2name(MBSTRG(http_input_list)[0]) != NULL) {  
                 MBSTRG(http_input_identify) = MBSTRG(http_input_list)[0];  
                 return SUCCESS;  
         }  
   
         if (arg_list && strlen(arg_list)>0) {  
                 /* make encoding list */  
                 list = NULL;  
                 size = 0;  
                 php_mb_parse_encoding_list(arg_list, strlen(arg_list), &list, &size, 0 TSRMLS_CC);  
                   
                 if (size > 0 && list != NULL) {  
                         elist = list;  
                 } else {  
                         elist = MBSTRG(current_detect_order_list);  
                         size = MBSTRG(current_detect_order_list_size);  
                         if (size <= 0){  
                                 elist = MBSTRG(default_detect_order_list);  
                                 size = MBSTRG(default_detect_order_list_size);  
                         }  
                 }  
         } else {  
                 elist = MBSTRG(current_detect_order_list);  
                 size = MBSTRG(current_detect_order_list_size);  
                 if (size <= 0){  
                         elist = MBSTRG(default_detect_order_list);  
                         size = MBSTRG(default_detect_order_list_size);  
                 }  
         }  
   
         mbfl_string_init(&string);  
         string.no_language = MBSTRG(language);  
   
         identd = mbfl_encoding_detector_new(elist, size, MBSTRG(strict_detection));  
   
         if (identd) {  
                 int n = 0;  
                 while(n < num){  
                         string.val = (unsigned char *)arg_string[n];  
                         string.len = arg_length[n];  
                         if (mbfl_encoding_detector_feed(identd, &string)) {  
                                 break;  
                         }  
                         n++;  
                 }  
                 encoding = mbfl_encoding_detector_judge(identd);  
                 mbfl_encoding_detector_delete(identd);  
         }  
   
         if (encoding != mbfl_no_encoding_invalid) {  
                 MBSTRG(http_input_identify) = encoding;  
                 return SUCCESS;  
         } else {  
                 return FAILURE;  
         }  
 }  
 /* }}} */  
   
 /* {{{ MBSTRING_API int php_mb_stripos()  /* {{{ MBSTRING_API int php_mb_stripos()
  */   */
 MBSTRING_API int php_mb_stripos(int mode, const char *old_haystack, unsigned int old_haystack_len, const char *old_needle, unsigned int old_needle_len, long offset, const char *from_encoding TSRMLS_DC)  MBSTRING_API int php_mb_stripos(int mode, const char *old_haystack, unsigned int old_haystack_len, const char *old_needle, unsigned int old_needle_len, long offset, const char *from_encoding TSRMLS_DC)
Line 4659  MBSTRING_API int php_mb_stripos(int mode, const char * Line 4663  MBSTRING_API int php_mb_stripos(int mode, const char *
         mbfl_string_init(&haystack);          mbfl_string_init(&haystack);
         mbfl_string_init(&needle);          mbfl_string_init(&needle);
         haystack.no_language = MBSTRG(language);          haystack.no_language = MBSTRG(language);
        haystack.no_encoding = MBSTRG(current_internal_encoding);        haystack.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
         needle.no_language = MBSTRG(language);          needle.no_language = MBSTRG(language);
        needle.no_encoding = MBSTRG(current_internal_encoding);        needle.no_encoding = MBSTRG(current_internal_encoding)->no_encoding;
   
         do {          do {
                 size_t len = 0;                  size_t len = 0;
Line 4725  MBSTRING_API int php_mb_stripos(int mode, const char * Line 4729  MBSTRING_API int php_mb_stripos(int mode, const char *
 }  }
 /* }}} */  /* }}} */
   
#ifdef ZEND_MULTIBYTEstatic void php_mb_gpc_get_detect_order(const zend_encoding ***list, size_t *list_size TSRMLS_DC) /* {{{ */
/* {{{ php_mb_set_zend_encoding() */ 
static int php_mb_set_zend_encoding(TSRMLS_D) 
 {  {
        /* 'd better use mbfl_memory_device? */        *list = (const zend_encoding **)MBSTRG(http_input_list);
        char *name, *list = NULL;        *list_size = MBSTRG(http_input_list_size);
        int n, *entry, list_size = 0; 
        zend_encoding_detector encoding_detector; 
        zend_encoding_converter encoding_converter; 
        zend_encoding_oddlen encoding_oddlen; 
 
        /* notify script encoding to Zend Engine */ 
        entry = MBSTRG(script_encoding_list); 
        n = MBSTRG(script_encoding_list_size); 
        while (n > 0) { 
                name = (char *)mbfl_no_encoding2name(*entry); 
                if (name) { 
                        list_size += strlen(name) + 1; 
                        if (!list) { 
                                list = (char*)emalloc(list_size); 
                                *list = '\0'; 
                        } else { 
                                list = (char*)erealloc(list, list_size); 
                                strcat(list, ","); 
                        } 
                        strcat(list, name); 
                } 
                entry++; 
                n--; 
        } 
        zend_multibyte_set_script_encoding(list, (list ? strlen(list) : 0) TSRMLS_CC); 
        if (list) { 
                efree(list); 
        } 
        encoding_detector = php_mb_encoding_detector; 
        encoding_converter = php_mb_encoding_converter; 
        encoding_oddlen = php_mb_oddlen; 
 
        /* TODO: make independent from mbstring.encoding_translation? */ 
        if (MBSTRG(encoding_translation)) { 
                /* notify internal encoding to Zend Engine */ 
                name = (char*)mbfl_no_encoding2name(MBSTRG(current_internal_encoding)); 
                zend_multibyte_set_internal_encoding(name TSRMLS_CC); 
        } 
 
        zend_multibyte_set_functions(encoding_detector, encoding_converter, encoding_oddlen TSRMLS_CC); 
 
        return 0; 
 }  }
 /* }}} */  /* }}} */
   
/* {{{ char *php_mb_encoding_detector()static void php_mb_gpc_set_input_encoding(const zend_encoding *encoding TSRMLS_DC) /* {{{ */
 * Interface for Zend Engine 
 */ 
static char* php_mb_encoding_detector(const unsigned char *arg_string, size_t arg_length, char *arg_list TSRMLS_DC) 
 {  {
        mbfl_string string;        MBSTRG(http_input_identify) = (const mbfl_encoding*)encoding;
        const char *ret; 
        enum mbfl_no_encoding *elist; 
        int size, *list; 
 
        /* make encoding list */ 
        list = NULL; 
        size = 0; 
        php_mb_parse_encoding_list(arg_list, strlen(arg_list), &list, &size, 0 TSRMLS_CC); 
        if (size <= 0) { 
                return NULL; 
        } 
        if (size > 0 && list != NULL) { 
                elist = list; 
        } else { 
                elist = MBSTRG(current_detect_order_list); 
                size = MBSTRG(current_detect_order_list_size); 
        } 
 
        mbfl_string_init(&string); 
        string.no_language = MBSTRG(language); 
        string.val = (unsigned char *)arg_string; 
        string.len = arg_length; 
        ret = mbfl_identify_encoding_name(&string, elist, size, 0); 
        if (list != NULL) { 
                efree((void *)list); 
        } 
        if (ret != NULL) { 
                return estrdup(ret); 
        } else { 
                return NULL; 
        } 
 }  }
 /* }}} */  /* }}} */
   
 /*      {{{ int php_mb_encoding_converter() */  
 static int php_mb_encoding_converter(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length, const char *encoding_to, const char *encoding_from TSRMLS_DC)  
 {  
         mbfl_string string, result, *ret;  
         enum mbfl_no_encoding from_encoding, to_encoding;  
         mbfl_buffer_converter *convd;  
   
         /* new encoding */  
         to_encoding = mbfl_name2no_encoding(encoding_to);  
         if (to_encoding == mbfl_no_encoding_invalid) {  
                 return -1;  
         }         
         /* old encoding */  
         from_encoding = mbfl_name2no_encoding(encoding_from);  
         if (from_encoding == mbfl_no_encoding_invalid) {  
                 return -1;  
         }  
         /* initialize string */  
         mbfl_string_init(&string);  
         mbfl_string_init(&result);  
         string.no_encoding = from_encoding;  
         string.no_language = MBSTRG(language);  
         string.val = (unsigned char*)from;  
         string.len = from_length;  
   
         /* initialize converter */  
         convd = mbfl_buffer_converter_new(from_encoding, to_encoding, string.len);  
         if (convd == NULL) {  
                 return -1;  
         }  
         mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode));  
         mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));  
   
         /* do it */  
         ret = mbfl_buffer_converter_feed_result(convd, &string, &result);  
         if (ret != NULL) {  
                 *to = ret->val;  
                 *to_length = ret->len;  
         }  
   
         MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd);  
         mbfl_buffer_converter_delete(convd);  
   
         return ret ? 0 : -1;  
 }  
 /* }}} */  
   
 /* {{{ int php_mb_oddlen()  
  *      returns number of odd (e.g. appears only first byte of multibyte  
  *      character) chars  
  */  
 static size_t php_mb_oddlen(const unsigned char *string, size_t length, const char *encoding TSRMLS_DC)  
 {  
         mbfl_string mb_string;  
   
         mbfl_string_init(&mb_string);  
         mb_string.no_language = MBSTRG(language);  
         mb_string.no_encoding = mbfl_name2no_encoding(encoding);  
         mb_string.val = (unsigned char *)string;  
         mb_string.len = length;  
   
         if (mb_string.no_encoding == mbfl_no_encoding_invalid) {  
                 return 0;  
         }  
         return mbfl_oddlen(&mb_string);  
 }  
 /* }}} */  
 #endif /* ZEND_MULTIBYTE */  
   
 #endif  /* HAVE_MBSTRING */  #endif  /* HAVE_MBSTRING */
   

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>