diff options
Diffstat (limited to 'ext/mbstring/mbstring.c')
| -rw-r--r-- | ext/mbstring/mbstring.c | 265 |
1 files changed, 255 insertions, 10 deletions
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 8adce024f..dbf2bf413 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mbstring.c,v 1.224.2.12 2006/01/01 12:50:08 sniper Exp $ */ +/* $Id: mbstring.c,v 1.224.2.23 2006/05/11 14:47:34 masugata Exp $ */ /* * PHP 4 Multibyte String module "mbstring" @@ -164,7 +164,7 @@ static ZEND_BEGIN_ARG_INFO(third_and_rest_force_ref, 1) ZEND_ARG_PASS_INFO(0) ZEND_ARG_PASS_INFO(0) - ZEND_END_ARG_INFO(); + ZEND_END_ARG_INFO() /* {{{ mb_overload_def mb_ovld[] */ static const struct mb_overload_def mb_ovld[] = { @@ -220,6 +220,7 @@ zend_function_entry mbstring_functions[] = { PHP_FE(mb_decode_numericentity, NULL) PHP_FE(mb_send_mail, NULL) PHP_FE(mb_get_info, NULL) + PHP_FE(mb_check_encoding, NULL) #if HAVE_MBREGEX PHP_MBREGEX_FUNCTION_ENTRIES #endif @@ -687,14 +688,26 @@ static PHP_INI_MH(OnUpdate_mbstring_script_encoding) /* {{{ static PHP_INI_MH(OnUpdate_mbstring_substitute_character) */ static PHP_INI_MH(OnUpdate_mbstring_substitute_character) { + int c; + char *endptr = NULL; + if (new_value != NULL) { if (strcasecmp("none", new_value) == 0) { MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE; + MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE; } else if (strcasecmp("long", new_value) == 0) { MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG; + MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG; } else { MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR; - MBSTRG(filter_illegal_substchar) = zend_atoi(new_value, new_value_length); + MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR; + if (new_value_length >0) { + c = strtol(new_value, &endptr, 0); + if (*endptr == '\0') { + MBSTRG(filter_illegal_substchar) = c; + MBSTRG(current_filter_illegal_substchar) = c; + } + } } } @@ -777,6 +790,7 @@ static void _php_mb_globals_ctor(zend_mbstring_globals *pglobals TSRMLS_DC) MBSTRG(filter_illegal_substchar) = 0x3f; /* '?' */ MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR; MBSTRG(current_filter_illegal_substchar) = 0x3f; /* '?' */ + MBSTRG(illegalchars) = 0; MBSTRG(func_overload) = 0; MBSTRG(encoding_translation) = 0; MBSTRG(strict_detection) = 0; @@ -919,6 +933,7 @@ PHP_RINIT_FUNCTION(mbstring) MBSTRG(current_http_output_encoding) = MBSTRG(http_output_encoding); MBSTRG(current_filter_illegal_mode) = MBSTRG(filter_illegal_mode); MBSTRG(current_filter_illegal_substchar) = MBSTRG(filter_illegal_substchar); + MBSTRG(illegalchars) = 0; n = 0; if (MBSTRG(detect_order_list)) { @@ -987,6 +1002,7 @@ PHP_RSHUTDOWN_FUNCTION(mbstring) MBSTRG(current_detect_order_list_size) = 0; } if (MBSTRG(outconv) != NULL) { + MBSTRG(illegalchars) += mbfl_buffer_illegalchars(MBSTRG(outconv)); mbfl_buffer_converter_delete(MBSTRG(outconv)); MBSTRG(outconv) = NULL; } @@ -1443,6 +1459,7 @@ PHP_FUNCTION(mb_output_handler) if ((arg_status & PHP_OUTPUT_HANDLER_START) != 0) { /* delete the converter just in case. */ if (MBSTRG(outconv)) { + MBSTRG(illegalchars) += mbfl_buffer_illegalchars(MBSTRG(outconv)); mbfl_buffer_converter_delete(MBSTRG(outconv)); MBSTRG(outconv) = NULL; } @@ -1507,6 +1524,7 @@ PHP_FUNCTION(mb_output_handler) /* delete the converter if it is the last feed. */ if (last_feed) { + MBSTRG(illegalchars) += mbfl_buffer_illegalchars(MBSTRG(outconv)); mbfl_buffer_converter_delete(MBSTRG(outconv)); MBSTRG(outconv) = NULL; } @@ -2071,6 +2089,7 @@ MBSTRING_API char * php_mb_convert_encoding(char *input, size_t length, char *_t output = (char *)ret->val; } + MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd); mbfl_buffer_converter_delete(convd); return output; } @@ -2717,6 +2736,7 @@ detect_end: } efree(stack); + MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd); mbfl_buffer_converter_delete(convd); } @@ -3048,7 +3068,7 @@ PHP_FUNCTION(mb_send_mail) char *extra_cmd=NULL; int extra_cmd_len; int i; - char *to_r; + char *to_r = NULL; char *force_extra_parameters = INI_STR("mail.force_extra_parameters"); struct { int cnt_type:1; @@ -3068,7 +3088,12 @@ PHP_FUNCTION(mb_send_mail) HashTable ht_headers; smart_str *s; extern void mbfl_memory_device_unput(mbfl_memory_device *device); - + + 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 */ mbfl_memory_device_init(&device, 0, 0); mbfl_string_init(&orig_str); @@ -3321,13 +3346,20 @@ PHP_FUNCTION(mb_send_mail) /* }}} */ -/* {{{ proto string mb_get_info([string type]) +/* {{{ proto mixed mb_get_info([string type]) Returns the current settings of mbstring */ PHP_FUNCTION(mb_get_info) { char *typ = NULL; - int typ_len; + int typ_len, n; char *name; + const struct mb_overload_def *over_func; + zval *row1, *row2; + const mbfl_language *lang = mbfl_no2language(MBSTRG(current_language)); + enum mbfl_no_encoding *entry; +#ifdef ZEND_MULTIBYTE + zval *row3; +#endif /* ZEND_MULTIBYTE */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &typ, &typ_len) == FAILURE) { RETURN_FALSE; @@ -3344,9 +3376,82 @@ PHP_FUNCTION(mb_get_info) if ((name = (char *)mbfl_no_encoding2name(MBSTRG(current_http_output_encoding))) != NULL) { add_assoc_string(return_value, "http_output", name, 1); } - if ((name = (char *)mbfl_no_encoding2name(MBSTRG(func_overload))) != NULL) { - add_assoc_string(return_value, "func_overload", name, 1); + if (MBSTRG(func_overload)){ + over_func = &(mb_ovld[0]); + MAKE_STD_ZVAL(row1); + array_init(row1); + while (over_func->type > 0) { + if ((MBSTRG(func_overload) & over_func->type) == over_func->type ) { + add_assoc_string(row1, over_func->orig_func, over_func->ovld_func, 1); + } + over_func++; + } + add_assoc_zval(return_value, "func_overload", row1); + } else { + add_assoc_string(return_value, "func_overload", "no overload", 1); + } + if (lang != NULL) { + if ((name = (char *)mbfl_no_encoding2name(lang->mail_charset)) != NULL) { + add_assoc_string(return_value, "mail_charset", name, 1); + } + if ((name = (char *)mbfl_no_encoding2name(lang->mail_header_encoding)) != NULL) { + add_assoc_string(return_value, "mail_header_encoding", name, 1); + } + if ((name = (char *)mbfl_no_encoding2name(lang->mail_body_encoding)) != NULL) { + add_assoc_string(return_value, "mail_body_encoding", name, 1); + } + } + add_assoc_long(return_value, "illegal_chars", MBSTRG(illegalchars)); + if (MBSTRG(encoding_translation)) { + add_assoc_string(return_value, "encoding_translation", "On", 1); + } else { + add_assoc_string(return_value, "encoding_translation", "Off", 1); + } + if ((name = (char *)mbfl_no_language2name(MBSTRG(current_language))) != NULL) { + add_assoc_string(return_value, "language", name, 1); + } + n = MBSTRG(current_detect_order_list_size); + entry = MBSTRG(current_detect_order_list); + if(n > 0) { + MAKE_STD_ZVAL(row2); + array_init(row2); + while (n > 0) { + if ((name = (char *)mbfl_no_encoding2name(*entry)) != NULL) { + add_next_index_string(row2, name, 1); + } + entry++; + n--; + } + add_assoc_zval(return_value, "detect_order", row2); + } + if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) { + add_assoc_string(return_value, "substitute_character", "none", 1); + } else if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG) { + add_assoc_string(return_value, "substitute_character", "long", 1); + } else { + add_assoc_long(return_value, "substitute_character", MBSTRG(current_filter_illegal_substchar)); + } + if (MBSTRG(strict_detection)) { + add_assoc_string(return_value, "strict_detection", "On", 1); + } else { + 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)) { if ((name = (char *)mbfl_no_encoding2name(MBSTRG(current_internal_encoding))) != NULL) { RETVAL_STRING(name, 1); @@ -3360,9 +3465,147 @@ PHP_FUNCTION(mb_get_info) RETVAL_STRING(name, 1); } } else if (!strcasecmp("func_overload", typ)) { - if ((name = (char *)mbfl_no_encoding2name(MBSTRG(func_overload))) != NULL) { + if (MBSTRG(func_overload)){ + over_func = &(mb_ovld[0]); + array_init(return_value); + while (over_func->type > 0) { + if ((MBSTRG(func_overload) & over_func->type) == over_func->type ) { + add_assoc_string(return_value, over_func->orig_func, over_func->ovld_func, 1); + } + over_func++; + } + } else { + RETVAL_STRING("no overload", 1); + } + } else if (!strcasecmp("mail_charset", typ)) { + if (lang != NULL && (name = (char *)mbfl_no_encoding2name(lang->mail_charset)) != NULL) { RETVAL_STRING(name, 1); } + } else if (!strcasecmp("mail_header_encoding", typ)) { + if (lang != NULL && (name = (char *)mbfl_no_encoding2name(lang->mail_header_encoding)) != NULL) { + RETVAL_STRING(name, 1); + } + } else if (!strcasecmp("mail_body_encoding", typ)) { + if (lang != NULL && (name = (char *)mbfl_no_encoding2name(lang->mail_body_encoding)) != NULL) { + RETVAL_STRING(name, 1); + } + } else if (!strcasecmp("illegal_chars", typ)) { + RETVAL_LONG(MBSTRG(illegalchars)); + } else if (!strcasecmp("encoding_translation", typ)) { + if (MBSTRG(encoding_translation)) { + RETVAL_STRING("On", 1); + } else { + RETVAL_STRING("Off", 1); + } + } else if (!strcasecmp("language", typ)) { + if ((name = (char *)mbfl_no_language2name(MBSTRG(current_language))) != NULL) { + RETVAL_STRING(name, 1); + } + } else if (!strcasecmp("detect_order", typ)) { + n = MBSTRG(current_detect_order_list_size); + entry = MBSTRG(current_detect_order_list); + 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--; + } + } + } else if (!strcasecmp("substitute_character", typ)) { + if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) { + RETVAL_STRING("none", 1); + } else if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG) { + RETVAL_STRING("long", 1); + } else { + RETVAL_LONG(MBSTRG(current_filter_illegal_substchar)); + } + } else if (!strcasecmp("strict_detection", typ)) { + if (MBSTRG(strict_detection)) { + RETVAL_STRING("On", 1); + } else { + RETVAL_STRING("Off", 1); + } + } 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; + } +} +/* }}} */ + +/* {{{ proto bool mb_check_encoding([string var[, string encoding]]) + Check if the string is valid for the specified encoding */ +PHP_FUNCTION(mb_check_encoding) +{ + char *var = NULL; + int var_len; + char *enc = NULL; + int enc_len; + mbfl_buffer_converter *convd; + enum mbfl_no_encoding no_encoding = MBSTRG(current_internal_encoding); + mbfl_string string, result, *ret = NULL; + long illegalchars = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &var, &var_len, &enc, &enc_len) == FAILURE) { + RETURN_FALSE; + } + + if (var == NULL) { + RETURN_BOOL(MBSTRG(illegalchars) == 0); + } + + if (enc != NULL) { + no_encoding = mbfl_name2no_encoding(enc); + if (no_encoding == mbfl_no_encoding_invalid || no_encoding == mbfl_no_encoding_pass) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid encoding \"%s\"", enc); + RETURN_FALSE; + } + } + + convd = mbfl_buffer_converter_new(no_encoding, no_encoding, 0); + if (convd == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create converter"); + RETURN_FALSE; + } + mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode)); + mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar)); + + /* initialize string */ + mbfl_string_init(&string); + mbfl_string_init(&result); + string.no_encoding = no_encoding; + string.no_language = MBSTRG(current_language); + + string.val = (unsigned char *)var; + string.len = var_len; + ret = mbfl_buffer_converter_feed_result(convd, &string, &result); + illegalchars = mbfl_buffer_illegalchars(convd); + mbfl_buffer_converter_delete(convd); + + if (ret != NULL) { + MBSTRG(illegalchars) += illegalchars; + efree(ret->val); + RETURN_BOOL(illegalchars == 0); } else { RETURN_FALSE; } @@ -3529,6 +3772,7 @@ MBSTRING_API int php_mb_gpc_encoding_converter(char **str, int *len, int num, co str[i] = ret->val; len[i] = ret->len; } + MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd); mbfl_buffer_converter_delete(convd); } @@ -3745,6 +3989,7 @@ int php_mb_encoding_converter(char **to, int *to_length, const char *from, *to = ret->val; *to_length = ret->len; } + MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd); mbfl_buffer_converter_delete(convd); return ret ? 0 : -1; |
