mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fix internal_encoding fallback in mbstring
By introducing a hook that is called whenever one of internal_encoding / input_encoding / output_encoding changes, so that mbstring can adjust it's internal state. This also makes internal_encoding work with zend multibyte.
This commit is contained in:
parent
3ccd3aba90
commit
f73f190c3f
16 changed files with 212 additions and 123 deletions
3
NEWS
3
NEWS
|
@ -60,6 +60,9 @@ PHP NEWS
|
||||||
- LDAP:
|
- LDAP:
|
||||||
. Deprecated ldap_control_paged_result_response and ldap_control_paged_result
|
. Deprecated ldap_control_paged_result_response and ldap_control_paged_result
|
||||||
|
|
||||||
|
- Mbstring:
|
||||||
|
. Fixed bug #77907 (mb-functions do not respect default_encoding). (Nikita)
|
||||||
|
|
||||||
- Opcache:
|
- Opcache:
|
||||||
. Implemented preloading RFC: https://wiki.php.net/rfc/preload. (Dmitry)
|
. Implemented preloading RFC: https://wiki.php.net/rfc/preload. (Dmitry)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ if (!extension_loaded("mbstring")) {
|
||||||
?>
|
?>
|
||||||
--INI--
|
--INI--
|
||||||
zend.multibyte=1
|
zend.multibyte=1
|
||||||
mbstring.internal_encoding=big5
|
internal_encoding=big5
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
echo '\'hello';
|
echo '\'hello';
|
||||||
|
|
|
@ -11,7 +11,7 @@ if (!extension_loaded("mbstring")) {
|
||||||
?>
|
?>
|
||||||
--INI--
|
--INI--
|
||||||
zend.multibyte=1
|
zend.multibyte=1
|
||||||
mbstring.internal_encoding=SJIS
|
internal_encoding=SJIS
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
declare(encoding='Shift_JIS');
|
declare(encoding='Shift_JIS');
|
||||||
|
|
|
@ -11,7 +11,7 @@ if (!extension_loaded("mbstring")) {
|
||||||
?>
|
?>
|
||||||
--INI--
|
--INI--
|
||||||
zend.multibyte=1
|
zend.multibyte=1
|
||||||
mbstring.internal_encoding=iso-8859-1
|
internal_encoding=iso-8859-1
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
print "Hello World\n";
|
print "Hello World\n";
|
||||||
|
|
Binary file not shown.
|
@ -12,7 +12,7 @@ if (!extension_loaded("mbstring")) {
|
||||||
--INI--
|
--INI--
|
||||||
zend.multibyte=1
|
zend.multibyte=1
|
||||||
zend.script_encoding=Shift_JIS
|
zend.script_encoding=Shift_JIS
|
||||||
mbstring.internal_encoding=Shift_JIS
|
internal_encoding=Shift_JIS
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
function —\Ž\”\($ˆø<CB86>”)
|
function —\Ž\”\($ˆø<CB86>”)
|
||||||
|
|
|
@ -13,7 +13,7 @@ if (!extension_loaded("mbstring")) {
|
||||||
zend.multibyte=1
|
zend.multibyte=1
|
||||||
mbstring.encoding_translation = On
|
mbstring.encoding_translation = On
|
||||||
zend.script_encoding=Shift_JIS
|
zend.script_encoding=Shift_JIS
|
||||||
mbstring.internal_encoding=UTF-8
|
internal_encoding=UTF-8
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
function —\Ž\”\($ˆø<CB86>”)
|
function —\Ž\”\($ˆø<CB86>”)
|
||||||
|
|
|
@ -338,37 +338,25 @@ PHP_MINFO_FUNCTION(miconv)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static char *get_internal_encoding(void) {
|
static const char *get_internal_encoding(void) {
|
||||||
if (ICONVG(internal_encoding) && ICONVG(internal_encoding)[0]) {
|
if (ICONVG(internal_encoding) && ICONVG(internal_encoding)[0]) {
|
||||||
return ICONVG(internal_encoding);
|
return ICONVG(internal_encoding);
|
||||||
} else if (PG(internal_encoding) && PG(internal_encoding)[0]) {
|
|
||||||
return PG(internal_encoding);
|
|
||||||
} else if (SG(default_charset)) {
|
|
||||||
return SG(default_charset);
|
|
||||||
}
|
}
|
||||||
return "";
|
return php_get_internal_encoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_input_encoding(void) {
|
static const char *get_input_encoding(void) {
|
||||||
if (ICONVG(input_encoding) && ICONVG(input_encoding)[0]) {
|
if (ICONVG(input_encoding) && ICONVG(input_encoding)[0]) {
|
||||||
return ICONVG(input_encoding);
|
return ICONVG(input_encoding);
|
||||||
} else if (PG(input_encoding) && PG(input_encoding)[0]) {
|
|
||||||
return PG(input_encoding);
|
|
||||||
} else if (SG(default_charset)) {
|
|
||||||
return SG(default_charset);
|
|
||||||
}
|
}
|
||||||
return "";
|
return php_get_input_encoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_output_encoding(void) {
|
static const char *get_output_encoding(void) {
|
||||||
if (ICONVG(output_encoding) && ICONVG(output_encoding)[0]) {
|
if (ICONVG(output_encoding) && ICONVG(output_encoding)[0]) {
|
||||||
return ICONVG(output_encoding);
|
return ICONVG(output_encoding);
|
||||||
} else if (PG(output_encoding) && PG(output_encoding)[0]) {
|
|
||||||
return PG(output_encoding);
|
|
||||||
} else if (SG(default_charset)) {
|
|
||||||
return SG(default_charset);
|
|
||||||
}
|
}
|
||||||
return "";
|
return php_get_output_encoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2064,7 +2052,7 @@ static void _php_iconv_show_error(php_iconv_err_t err, const char *out_charset,
|
||||||
Returns the character count of str */
|
Returns the character count of str */
|
||||||
PHP_FUNCTION(iconv_strlen)
|
PHP_FUNCTION(iconv_strlen)
|
||||||
{
|
{
|
||||||
char *charset = get_internal_encoding();
|
const char *charset = get_internal_encoding();
|
||||||
size_t charset_len = 0;
|
size_t charset_len = 0;
|
||||||
zend_string *str;
|
zend_string *str;
|
||||||
|
|
||||||
|
@ -2096,7 +2084,7 @@ PHP_FUNCTION(iconv_strlen)
|
||||||
Returns specified part of a string */
|
Returns specified part of a string */
|
||||||
PHP_FUNCTION(iconv_substr)
|
PHP_FUNCTION(iconv_substr)
|
||||||
{
|
{
|
||||||
char *charset = get_internal_encoding();
|
const char *charset = get_internal_encoding();
|
||||||
size_t charset_len = 0;
|
size_t charset_len = 0;
|
||||||
zend_string *str;
|
zend_string *str;
|
||||||
zend_long offset, length = 0;
|
zend_long offset, length = 0;
|
||||||
|
@ -2135,7 +2123,7 @@ PHP_FUNCTION(iconv_substr)
|
||||||
Finds position of first occurrence of needle within part of haystack beginning with offset */
|
Finds position of first occurrence of needle within part of haystack beginning with offset */
|
||||||
PHP_FUNCTION(iconv_strpos)
|
PHP_FUNCTION(iconv_strpos)
|
||||||
{
|
{
|
||||||
char *charset = get_internal_encoding();
|
const char *charset = get_internal_encoding();
|
||||||
size_t charset_len = 0, haystk_len;
|
size_t charset_len = 0, haystk_len;
|
||||||
zend_string *haystk;
|
zend_string *haystk;
|
||||||
zend_string *ndl;
|
zend_string *ndl;
|
||||||
|
@ -2190,7 +2178,7 @@ PHP_FUNCTION(iconv_strpos)
|
||||||
Finds position of last occurrence of needle within part of haystack beginning with offset */
|
Finds position of last occurrence of needle within part of haystack beginning with offset */
|
||||||
PHP_FUNCTION(iconv_strrpos)
|
PHP_FUNCTION(iconv_strrpos)
|
||||||
{
|
{
|
||||||
char *charset = get_internal_encoding();
|
const char *charset = get_internal_encoding();
|
||||||
size_t charset_len = 0;
|
size_t charset_len = 0;
|
||||||
zend_string *haystk;
|
zend_string *haystk;
|
||||||
zend_string *ndl;
|
zend_string *ndl;
|
||||||
|
@ -2331,7 +2319,7 @@ PHP_FUNCTION(iconv_mime_encode)
|
||||||
PHP_FUNCTION(iconv_mime_decode)
|
PHP_FUNCTION(iconv_mime_decode)
|
||||||
{
|
{
|
||||||
zend_string *encoded_str;
|
zend_string *encoded_str;
|
||||||
char *charset = get_internal_encoding();
|
const char *charset = get_internal_encoding();
|
||||||
size_t charset_len = 0;
|
size_t charset_len = 0;
|
||||||
zend_long mode = 0;
|
zend_long mode = 0;
|
||||||
|
|
||||||
|
@ -2371,7 +2359,7 @@ PHP_FUNCTION(iconv_mime_decode)
|
||||||
PHP_FUNCTION(iconv_mime_decode_headers)
|
PHP_FUNCTION(iconv_mime_decode_headers)
|
||||||
{
|
{
|
||||||
zend_string *encoded_str;
|
zend_string *encoded_str;
|
||||||
char *charset = get_internal_encoding();
|
const char *charset = get_internal_encoding();
|
||||||
size_t charset_len = 0;
|
size_t charset_len = 0;
|
||||||
zend_long mode = 0;
|
zend_long mode = 0;
|
||||||
char *enc_str_tmp;
|
char *enc_str_tmp;
|
||||||
|
|
|
@ -58,11 +58,6 @@ MBSTRING_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data)
|
||||||
const mbfl_encoding *detected;
|
const mbfl_encoding *detected;
|
||||||
php_mb_encoding_handler_info_t info;
|
php_mb_encoding_handler_info_t info;
|
||||||
|
|
||||||
if (arg != PARSE_STRING) {
|
|
||||||
char *value = MBSTRG(internal_encoding_name);
|
|
||||||
_php_mb_ini_mbstring_internal_encoding_set(value, value ? strlen(value): 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!MBSTRG(encoding_translation)) {
|
if (!MBSTRG(encoding_translation)) {
|
||||||
php_default_treat_data(arg, str, destArray);
|
php_default_treat_data(arg, str, destArray);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -615,34 +615,6 @@ ZEND_TSRMLS_CACHE_DEFINE()
|
||||||
ZEND_GET_MODULE(mbstring)
|
ZEND_GET_MODULE(mbstring)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char *get_internal_encoding(void) {
|
|
||||||
if (PG(internal_encoding) && PG(internal_encoding)[0]) {
|
|
||||||
return PG(internal_encoding);
|
|
||||||
} else if (SG(default_charset)) {
|
|
||||||
return SG(default_charset);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *get_input_encoding(void) {
|
|
||||||
if (PG(input_encoding) && PG(input_encoding)[0]) {
|
|
||||||
return PG(input_encoding);
|
|
||||||
} else if (SG(default_charset)) {
|
|
||||||
return SG(default_charset);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *get_output_encoding(void) {
|
|
||||||
if (PG(output_encoding) && PG(output_encoding)[0]) {
|
|
||||||
return PG(output_encoding);
|
|
||||||
} else if (SG(default_charset)) {
|
|
||||||
return SG(default_charset);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* {{{ allocators */
|
/* {{{ allocators */
|
||||||
static void *_php_mb_allocators_malloc(size_t sz)
|
static void *_php_mb_allocators_malloc(size_t sz)
|
||||||
{
|
{
|
||||||
|
@ -1289,77 +1261,70 @@ static PHP_INI_MH(OnUpdate_mbstring_detect_order)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_input) */
|
static int _php_mb_ini_mbstring_http_input_set(const char *new_value, size_t new_value_length) {
|
||||||
static PHP_INI_MH(OnUpdate_mbstring_http_input)
|
|
||||||
{
|
|
||||||
const mbfl_encoding **list;
|
const mbfl_encoding **list;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1)) {
|
||||||
if (!new_value || !ZSTR_VAL(new_value)) {
|
|
||||||
if (MBSTRG(http_input_list)) {
|
|
||||||
pefree(MBSTRG(http_input_list), 1);
|
|
||||||
}
|
|
||||||
if (SUCCESS == php_mb_parse_encoding_list(get_input_encoding(), strlen(get_input_encoding())+1, &list, &size, 1)) {
|
|
||||||
MBSTRG(http_input_list) = list;
|
|
||||||
MBSTRG(http_input_list_size) = size;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
MBSTRG(http_input_list) = NULL;
|
|
||||||
MBSTRG(http_input_list_size) = 0;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(new_value), ZSTR_LEN(new_value), &list, &size, 1)) {
|
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MBSTRG(http_input_list)) {
|
if (MBSTRG(http_input_list)) {
|
||||||
pefree(MBSTRG(http_input_list), 1);
|
pefree(MBSTRG(http_input_list), 1);
|
||||||
}
|
}
|
||||||
MBSTRG(http_input_list) = list;
|
MBSTRG(http_input_list) = list;
|
||||||
MBSTRG(http_input_list_size) = size;
|
MBSTRG(http_input_list_size) = size;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_input) */
|
||||||
|
static PHP_INI_MH(OnUpdate_mbstring_http_input)
|
||||||
|
{
|
||||||
if (stage & (PHP_INI_STAGE_ACTIVATE | PHP_INI_STAGE_RUNTIME)) {
|
if (stage & (PHP_INI_STAGE_ACTIVATE | PHP_INI_STAGE_RUNTIME)) {
|
||||||
php_error_docref("ref.mbstring", E_DEPRECATED, "Use of mbstring.http_input is deprecated");
|
php_error_docref("ref.mbstring", E_DEPRECATED, "Use of mbstring.http_input is deprecated");
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
if (!new_value || !ZSTR_VAL(new_value)) {
|
||||||
|
const char *encoding = php_get_input_encoding();
|
||||||
|
MBSTRG(http_input_set) = 0;
|
||||||
|
_php_mb_ini_mbstring_http_input_set(encoding, strlen(encoding));
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
MBSTRG(http_input_set) = 1;
|
||||||
|
return _php_mb_ini_mbstring_http_input_set(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static int _php_mb_ini_mbstring_http_output_set(const char *new_value) {
|
||||||
|
const mbfl_encoding *encoding = mbfl_name2encoding(new_value);
|
||||||
|
if (!encoding) {
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MBSTRG(http_output_encoding) = encoding;
|
||||||
|
MBSTRG(current_http_output_encoding) = encoding;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* {{{ 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)
|
||||||
{
|
{
|
||||||
const mbfl_encoding *encoding;
|
|
||||||
|
|
||||||
if (new_value == NULL || ZSTR_LEN(new_value) == 0) {
|
|
||||||
encoding = mbfl_name2encoding(get_output_encoding());
|
|
||||||
if (!encoding) {
|
|
||||||
MBSTRG(http_output_encoding) = &mbfl_encoding_pass;
|
|
||||||
MBSTRG(current_http_output_encoding) = &mbfl_encoding_pass;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
encoding = mbfl_name2encoding(ZSTR_VAL(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;
|
|
||||||
|
|
||||||
if (stage & (PHP_INI_STAGE_ACTIVATE | PHP_INI_STAGE_RUNTIME)) {
|
if (stage & (PHP_INI_STAGE_ACTIVATE | PHP_INI_STAGE_RUNTIME)) {
|
||||||
php_error_docref("ref.mbstring", E_DEPRECATED, "Use of mbstring.http_output is deprecated");
|
php_error_docref("ref.mbstring", E_DEPRECATED, "Use of mbstring.http_output is deprecated");
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
if (new_value == NULL || ZSTR_LEN(new_value) == 0) {
|
||||||
|
MBSTRG(http_output_set) = 0;
|
||||||
|
_php_mb_ini_mbstring_http_output_set(php_get_output_encoding());
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
MBSTRG(http_output_set) = 1;
|
||||||
|
return _php_mb_ini_mbstring_http_output_set(ZSTR_VAL(new_value));
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ 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, size_t new_value_length)
|
static int _php_mb_ini_mbstring_internal_encoding_set(const char *new_value, size_t new_value_length)
|
||||||
{
|
{
|
||||||
const mbfl_encoding *encoding;
|
const mbfl_encoding *encoding;
|
||||||
|
|
||||||
|
@ -1395,20 +1360,13 @@ static PHP_INI_MH(OnUpdate_mbstring_internal_encoding)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stage & (PHP_INI_STAGE_STARTUP | PHP_INI_STAGE_SHUTDOWN | PHP_INI_STAGE_RUNTIME)) {
|
if (new_value && ZSTR_LEN(new_value)) {
|
||||||
if (new_value && ZSTR_LEN(new_value)) {
|
MBSTRG(internal_encoding_set) = 1;
|
||||||
return _php_mb_ini_mbstring_internal_encoding_set(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
|
return _php_mb_ini_mbstring_internal_encoding_set(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
|
||||||
} else {
|
|
||||||
return _php_mb_ini_mbstring_internal_encoding_set(get_internal_encoding(), strlen(get_internal_encoding())+1);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* the corresponding mbstring globals needs to be set according to the
|
const char *encoding = php_get_internal_encoding();
|
||||||
* ini value in the later stage because it never falls back to the
|
MBSTRG(internal_encoding_set) = 0;
|
||||||
* default value if 1. no value for mbstring.internal_encoding is given,
|
return _php_mb_ini_mbstring_internal_encoding_set(encoding, strlen(encoding));
|
||||||
* 2. mbstring.language directive is processed in per-dir or runtime
|
|
||||||
* context and 3. call to the handler for mbstring.language is done
|
|
||||||
* after mbstring.internal_encoding is handled. */
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
@ -1532,6 +1490,24 @@ PHP_INI_BEGIN()
|
||||||
PHP_INI_END()
|
PHP_INI_END()
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static void mbstring_internal_encoding_changed_hook() {
|
||||||
|
/* One of the internal_encoding / input_encoding / output_encoding ini settings changed. */
|
||||||
|
if (!MBSTRG(internal_encoding_set)) {
|
||||||
|
const char *encoding = php_get_internal_encoding();
|
||||||
|
_php_mb_ini_mbstring_internal_encoding_set(encoding, strlen(encoding));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MBSTRG(http_output_set)) {
|
||||||
|
const char *encoding = php_get_output_encoding();
|
||||||
|
_php_mb_ini_mbstring_http_output_set(encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MBSTRG(http_input_set)) {
|
||||||
|
const char *encoding = php_get_input_encoding();
|
||||||
|
_php_mb_ini_mbstring_http_input_set(encoding, strlen(encoding));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* {{{ module global initialize handler */
|
/* {{{ module global initialize handler */
|
||||||
static PHP_GINIT_FUNCTION(mbstring)
|
static PHP_GINIT_FUNCTION(mbstring)
|
||||||
{
|
{
|
||||||
|
@ -1572,6 +1548,9 @@ ZEND_TSRMLS_CACHE_UPDATE();
|
||||||
#endif
|
#endif
|
||||||
mbstring_globals->last_used_encoding_name = NULL;
|
mbstring_globals->last_used_encoding_name = NULL;
|
||||||
mbstring_globals->last_used_encoding = NULL;
|
mbstring_globals->last_used_encoding = NULL;
|
||||||
|
mbstring_globals->internal_encoding_set = 0;
|
||||||
|
mbstring_globals->http_output_set = 0;
|
||||||
|
mbstring_globals->http_input_set = 0;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -1603,6 +1582,11 @@ ZEND_TSRMLS_CACHE_UPDATE();
|
||||||
|
|
||||||
REGISTER_INI_ENTRIES();
|
REGISTER_INI_ENTRIES();
|
||||||
|
|
||||||
|
/* We assume that we're the only user of the hook. */
|
||||||
|
ZEND_ASSERT(php_internal_encoding_changed == NULL);
|
||||||
|
php_internal_encoding_changed = mbstring_internal_encoding_changed_hook;
|
||||||
|
mbstring_internal_encoding_changed_hook();
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
||||||
|
@ -1763,6 +1747,10 @@ PHP_RSHUTDOWN_FUNCTION(mbstring)
|
||||||
MBSTRG(last_used_encoding_name) = NULL;
|
MBSTRG(last_used_encoding_name) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MBSTRG(internal_encoding_set) = 0;
|
||||||
|
MBSTRG(http_output_set) = 0;
|
||||||
|
MBSTRG(http_input_set) = 0;
|
||||||
|
|
||||||
#if HAVE_MBREGEX
|
#if HAVE_MBREGEX
|
||||||
PHP_RSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
|
PHP_RSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1846,6 +1834,7 @@ PHP_FUNCTION(mb_internal_encoding)
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
} else {
|
} else {
|
||||||
MBSTRG(current_internal_encoding) = encoding;
|
MBSTRG(current_internal_encoding) = encoding;
|
||||||
|
MBSTRG(internal_encoding_set) = 1;
|
||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1969,6 +1958,7 @@ PHP_FUNCTION(mb_http_output)
|
||||||
php_error_docref(NULL, E_WARNING, "Unknown encoding \"%s\"", name);
|
php_error_docref(NULL, E_WARNING, "Unknown encoding \"%s\"", name);
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
} else {
|
} else {
|
||||||
|
MBSTRG(http_output_set) = 1;
|
||||||
MBSTRG(current_http_output_encoding) = encoding;
|
MBSTRG(current_http_output_encoding) = encoding;
|
||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,9 +130,6 @@ MBSTRING_API size_t php_mb_mbchar_bytes(const char *s);
|
||||||
MBSTRING_API size_t php_mb_stripos(int mode, const char *old_haystack, size_t old_haystack_len, const char *old_needle, size_t old_needle_len, zend_long offset, zend_string *from_encoding);
|
MBSTRING_API size_t php_mb_stripos(int mode, const char *old_haystack, size_t old_haystack_len, const char *old_needle, size_t old_needle_len, zend_long offset, zend_string *from_encoding);
|
||||||
MBSTRING_API int php_mb_check_encoding(const char *input, size_t length, const char *enc);
|
MBSTRING_API int php_mb_check_encoding(const char *input, size_t length, const char *enc);
|
||||||
|
|
||||||
/* internal use only */
|
|
||||||
int _php_mb_ini_mbstring_internal_encoding_set(const char *new_value, size_t new_value_length);
|
|
||||||
|
|
||||||
ZEND_BEGIN_MODULE_GLOBALS(mbstring)
|
ZEND_BEGIN_MODULE_GLOBALS(mbstring)
|
||||||
char *internal_encoding_name;
|
char *internal_encoding_name;
|
||||||
const mbfl_encoding *internal_encoding;
|
const mbfl_encoding *internal_encoding;
|
||||||
|
@ -169,6 +166,10 @@ ZEND_BEGIN_MODULE_GLOBALS(mbstring)
|
||||||
#endif
|
#endif
|
||||||
zend_string *last_used_encoding_name;
|
zend_string *last_used_encoding_name;
|
||||||
const mbfl_encoding *last_used_encoding;
|
const mbfl_encoding *last_used_encoding;
|
||||||
|
/* Whether an explicit internal_encoding / http_output / http_input encoding was set. */
|
||||||
|
zend_bool internal_encoding_set;
|
||||||
|
zend_bool http_output_set;
|
||||||
|
zend_bool http_input_set;
|
||||||
ZEND_END_MODULE_GLOBALS(mbstring)
|
ZEND_END_MODULE_GLOBALS(mbstring)
|
||||||
|
|
||||||
#define MB_OVERLOAD_MAIL 1
|
#define MB_OVERLOAD_MAIL 1
|
||||||
|
|
|
@ -50,7 +50,7 @@ string(6) "EUC-JP"
|
||||||
string(0) ""
|
string(0) ""
|
||||||
string(0) ""
|
string(0) ""
|
||||||
string(0) ""
|
string(0) ""
|
||||||
string(5) "UTF-8"
|
string(6) "EUC-JP"
|
||||||
string(0) ""
|
string(0) ""
|
||||||
string(0) ""
|
string(0) ""
|
||||||
Setting INI
|
Setting INI
|
||||||
|
|
66
ext/mbstring/tests/internal_encoding.phpt
Normal file
66
ext/mbstring/tests/internal_encoding.phpt
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
--TEST--
|
||||||
|
Check that "internal_encoding" ini is picked up by mbstring
|
||||||
|
--INI--
|
||||||
|
internal_encoding=iso-8859-1
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
var_dump(mb_internal_encoding());
|
||||||
|
var_dump(mb_strlen("\xc3\xb6"));
|
||||||
|
|
||||||
|
ini_set('mbstring.internal_encoding', 'utf-8');
|
||||||
|
|
||||||
|
var_dump(mb_internal_encoding());
|
||||||
|
var_dump(mb_strlen("\xc3\xb6"));
|
||||||
|
|
||||||
|
// mbstring.internal_encoding is set, this has no effect
|
||||||
|
ini_set('internal_encoding', 'iso-8859-2');
|
||||||
|
|
||||||
|
var_dump(mb_internal_encoding());
|
||||||
|
var_dump(mb_strlen("\xc3\xb6"));
|
||||||
|
|
||||||
|
// mbstring.internal_encoding is unset, pick up internal_encoding again
|
||||||
|
ini_set('mbstring.internal_encoding', '');
|
||||||
|
|
||||||
|
var_dump(mb_internal_encoding());
|
||||||
|
var_dump(mb_strlen("\xc3\xb6"));
|
||||||
|
|
||||||
|
mb_internal_encoding('utf-8');
|
||||||
|
|
||||||
|
var_dump(mb_internal_encoding());
|
||||||
|
var_dump(mb_strlen("\xc3\xb6"));
|
||||||
|
|
||||||
|
// mb_internal_encoding() is set, this has no effect
|
||||||
|
ini_set('internal_encoding', 'iso-8859-3');
|
||||||
|
|
||||||
|
var_dump(mb_internal_encoding());
|
||||||
|
var_dump(mb_strlen("\xc3\xb6"));
|
||||||
|
|
||||||
|
// mbstring.internal_encoding is unset, pick up internal_encoding again
|
||||||
|
ini_set('mbstring.internal_encoding', '');
|
||||||
|
|
||||||
|
var_dump(mb_internal_encoding());
|
||||||
|
var_dump(mb_strlen("\xc3\xb6"));
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
string(10) "ISO-8859-1"
|
||||||
|
int(2)
|
||||||
|
|
||||||
|
Deprecated: ini_set(): Use of mbstring.internal_encoding is deprecated in %s on line %d
|
||||||
|
string(5) "UTF-8"
|
||||||
|
int(1)
|
||||||
|
string(5) "UTF-8"
|
||||||
|
int(1)
|
||||||
|
|
||||||
|
Deprecated: ini_set(): Use of mbstring.internal_encoding is deprecated in %s on line %d
|
||||||
|
string(10) "ISO-8859-2"
|
||||||
|
int(2)
|
||||||
|
string(5) "UTF-8"
|
||||||
|
int(1)
|
||||||
|
string(5) "UTF-8"
|
||||||
|
int(1)
|
||||||
|
|
||||||
|
Deprecated: ini_set(): Use of mbstring.internal_encoding is deprecated in %s on line %d
|
||||||
|
string(10) "ISO-8859-3"
|
||||||
|
int(2)
|
|
@ -47,7 +47,7 @@ string(10) "ISO-8859-1"
|
||||||
string(0) ""
|
string(0) ""
|
||||||
string(0) ""
|
string(0) ""
|
||||||
string(0) ""
|
string(0) ""
|
||||||
string(5) "UTF-8"
|
string(10) "ISO-8859-1"
|
||||||
bool(true)
|
bool(true)
|
||||||
string(5) "UTF-8"
|
string(5) "UTF-8"
|
||||||
Done
|
Done
|
||||||
|
|
41
main/main.c
41
main/main.c
|
@ -578,12 +578,44 @@ static PHP_INI_DISP(display_errors_mode)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
PHPAPI const char *php_get_internal_encoding() {
|
||||||
|
if (PG(internal_encoding) && PG(internal_encoding)[0]) {
|
||||||
|
return PG(internal_encoding);
|
||||||
|
} else if (SG(default_charset)) {
|
||||||
|
return SG(default_charset);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
PHPAPI const char *php_get_input_encoding() {
|
||||||
|
if (PG(input_encoding) && PG(input_encoding)[0]) {
|
||||||
|
return PG(input_encoding);
|
||||||
|
} else if (SG(default_charset)) {
|
||||||
|
return SG(default_charset);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
PHPAPI const char *php_get_output_encoding() {
|
||||||
|
if (PG(output_encoding) && PG(output_encoding)[0]) {
|
||||||
|
return PG(output_encoding);
|
||||||
|
} else if (SG(default_charset)) {
|
||||||
|
return SG(default_charset);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
PHPAPI void (*php_internal_encoding_changed)(void) = NULL;
|
||||||
|
|
||||||
/* {{{ PHP_INI_MH
|
/* {{{ PHP_INI_MH
|
||||||
*/
|
*/
|
||||||
static PHP_INI_MH(OnUpdateDefaultCharset)
|
static PHP_INI_MH(OnUpdateDefaultCharset)
|
||||||
{
|
{
|
||||||
if (new_value) {
|
if (new_value) {
|
||||||
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
||||||
|
if (php_internal_encoding_changed) {
|
||||||
|
php_internal_encoding_changed();
|
||||||
|
}
|
||||||
#ifdef PHP_WIN32
|
#ifdef PHP_WIN32
|
||||||
php_win32_cp_do_update(ZSTR_VAL(new_value));
|
php_win32_cp_do_update(ZSTR_VAL(new_value));
|
||||||
#endif
|
#endif
|
||||||
|
@ -598,6 +630,9 @@ static PHP_INI_MH(OnUpdateInternalEncoding)
|
||||||
{
|
{
|
||||||
if (new_value) {
|
if (new_value) {
|
||||||
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
||||||
|
if (php_internal_encoding_changed) {
|
||||||
|
php_internal_encoding_changed();
|
||||||
|
}
|
||||||
#ifdef PHP_WIN32
|
#ifdef PHP_WIN32
|
||||||
php_win32_cp_do_update(ZSTR_VAL(new_value));
|
php_win32_cp_do_update(ZSTR_VAL(new_value));
|
||||||
#endif
|
#endif
|
||||||
|
@ -612,6 +647,9 @@ static PHP_INI_MH(OnUpdateInputEncoding)
|
||||||
{
|
{
|
||||||
if (new_value) {
|
if (new_value) {
|
||||||
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
||||||
|
if (php_internal_encoding_changed) {
|
||||||
|
php_internal_encoding_changed();
|
||||||
|
}
|
||||||
#ifdef PHP_WIN32
|
#ifdef PHP_WIN32
|
||||||
php_win32_cp_do_update(NULL);
|
php_win32_cp_do_update(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
@ -626,6 +664,9 @@ static PHP_INI_MH(OnUpdateOutputEncoding)
|
||||||
{
|
{
|
||||||
if (new_value) {
|
if (new_value) {
|
||||||
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
||||||
|
if (php_internal_encoding_changed) {
|
||||||
|
php_internal_encoding_changed();
|
||||||
|
}
|
||||||
#ifdef PHP_WIN32
|
#ifdef PHP_WIN32
|
||||||
php_win32_cp_do_update(NULL);
|
php_win32_cp_do_update(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -371,6 +371,11 @@ PHPAPI int php_mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const
|
||||||
PHPAPI void php_register_pre_request_shutdown(void (*func)(void *), void *userdata);
|
PHPAPI void php_register_pre_request_shutdown(void (*func)(void *), void *userdata);
|
||||||
PHPAPI void php_com_initialize(void);
|
PHPAPI void php_com_initialize(void);
|
||||||
PHPAPI char *php_get_current_user(void);
|
PHPAPI char *php_get_current_user(void);
|
||||||
|
|
||||||
|
PHPAPI const char *php_get_internal_encoding(void);
|
||||||
|
PHPAPI const char *php_get_input_encoding(void);
|
||||||
|
PHPAPI const char *php_get_output_encoding(void);
|
||||||
|
PHPAPI extern void (*php_internal_encoding_changed)(void);
|
||||||
END_EXTERN_C()
|
END_EXTERN_C()
|
||||||
|
|
||||||
/* PHP-named Zend macro wrappers */
|
/* PHP-named Zend macro wrappers */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue