- LDAP:
. Deprecated ldap_control_paged_result_response and ldap_control_paged_result
+- Mbstring:
+ . Fixed bug #77907 (mb-functions do not respect default_encoding). (Nikita)
+
- Opcache:
. Implemented preloading RFC: https://wiki.php.net/rfc/preload. (Dmitry)
?>
--INI--
zend.multibyte=1
-mbstring.internal_encoding=big5
+internal_encoding=big5
--FILE--
<?php
echo '\'hello';
?>
--INI--
zend.multibyte=1
-mbstring.internal_encoding=SJIS
+internal_encoding=SJIS
--FILE--
<?php
declare(encoding='Shift_JIS');
?>
--INI--
zend.multibyte=1
-mbstring.internal_encoding=iso-8859-1
+internal_encoding=iso-8859-1
--FILE--
<?php
print "Hello World\n";
--INI--
zend.multibyte=1
zend.script_encoding=Shift_JIS
-mbstring.internal_encoding=Shift_JIS
+internal_encoding=Shift_JIS
--FILE--
<?php
function \97\\8e\\94\($\88ø\90\94)
zend.multibyte=1
mbstring.encoding_translation = On
zend.script_encoding=Shift_JIS
-mbstring.internal_encoding=UTF-8
+internal_encoding=UTF-8
--FILE--
<?php
function \97\\8e\\94\($\88ø\90\94)
}
/* }}} */
-static char *get_internal_encoding(void) {
+static const char *get_internal_encoding(void) {
if (ICONVG(internal_encoding) && ICONVG(internal_encoding)[0]) {
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]) {
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]) {
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();
}
Returns the character count of str */
PHP_FUNCTION(iconv_strlen)
{
- char *charset = get_internal_encoding();
+ const char *charset = get_internal_encoding();
size_t charset_len = 0;
zend_string *str;
Returns specified part of a string */
PHP_FUNCTION(iconv_substr)
{
- char *charset = get_internal_encoding();
+ const char *charset = get_internal_encoding();
size_t charset_len = 0;
zend_string *str;
zend_long offset, length = 0;
Finds position of first occurrence of needle within part of haystack beginning with offset */
PHP_FUNCTION(iconv_strpos)
{
- char *charset = get_internal_encoding();
+ const char *charset = get_internal_encoding();
size_t charset_len = 0, haystk_len;
zend_string *haystk;
zend_string *ndl;
Finds position of last occurrence of needle within part of haystack beginning with offset */
PHP_FUNCTION(iconv_strrpos)
{
- char *charset = get_internal_encoding();
+ const char *charset = get_internal_encoding();
size_t charset_len = 0;
zend_string *haystk;
zend_string *ndl;
PHP_FUNCTION(iconv_mime_decode)
{
zend_string *encoded_str;
- char *charset = get_internal_encoding();
+ const char *charset = get_internal_encoding();
size_t charset_len = 0;
zend_long mode = 0;
PHP_FUNCTION(iconv_mime_decode_headers)
{
zend_string *encoded_str;
- char *charset = get_internal_encoding();
+ const char *charset = get_internal_encoding();
size_t charset_len = 0;
zend_long mode = 0;
char *enc_str_tmp;
const mbfl_encoding *detected;
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)) {
php_default_treat_data(arg, str, destArray);
return;
ZEND_GET_MODULE(mbstring)
#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 */
static void *_php_mb_allocators_malloc(size_t sz)
{
}
/* }}} */
-/* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_input) */
-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) {
const mbfl_encoding **list;
size_t size;
-
- 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)) {
+ if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1)) {
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;
+}
+/* {{{ 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)) {
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 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;
- }
+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)
+{
if (stage & (PHP_INI_STAGE_ACTIVATE | PHP_INI_STAGE_RUNTIME)) {
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 */
-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;
return FAILURE;
}
- if (stage & (PHP_INI_STAGE_STARTUP | PHP_INI_STAGE_SHUTDOWN | PHP_INI_STAGE_RUNTIME)) {
- if (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);
- }
+ 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));
} else {
- /* the corresponding mbstring globals needs to be set according to the
- * ini value in the later stage because it never falls back to the
- * default value if 1. no value for mbstring.internal_encoding is given,
- * 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;
+ const char *encoding = php_get_internal_encoding();
+ MBSTRG(internal_encoding_set) = 0;
+ return _php_mb_ini_mbstring_internal_encoding_set(encoding, strlen(encoding));
}
}
/* }}} */
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 */
static PHP_GINIT_FUNCTION(mbstring)
{
#endif
mbstring_globals->last_used_encoding_name = 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;
}
/* }}} */
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. */
sapi_register_treat_data(mbstr_treat_data);
MBSTRG(last_used_encoding_name) = NULL;
}
+ MBSTRG(internal_encoding_set) = 0;
+ MBSTRG(http_output_set) = 0;
+ MBSTRG(http_input_set) = 0;
+
#if HAVE_MBREGEX
PHP_RSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
#endif
RETURN_FALSE;
} else {
MBSTRG(current_internal_encoding) = encoding;
+ MBSTRG(internal_encoding_set) = 1;
RETURN_TRUE;
}
}
php_error_docref(NULL, E_WARNING, "Unknown encoding \"%s\"", name);
RETURN_FALSE;
} else {
+ MBSTRG(http_output_set) = 1;
MBSTRG(current_http_output_encoding) = encoding;
RETURN_TRUE;
}
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);
-/* 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)
char *internal_encoding_name;
const mbfl_encoding *internal_encoding;
#endif
zend_string *last_used_encoding_name;
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)
#define MB_OVERLOAD_MAIL 1
string(0) ""
string(0) ""
string(0) ""
-string(5) "UTF-8"
+string(6) "EUC-JP"
string(0) ""
string(0) ""
Setting INI
--- /dev/null
+--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)
string(0) ""
string(0) ""
string(0) ""
-string(5) "UTF-8"
+string(10) "ISO-8859-1"
bool(true)
string(5) "UTF-8"
Done
}
/* }}} */
+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
*/
static PHP_INI_MH(OnUpdateDefaultCharset)
{
if (new_value) {
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
+ if (php_internal_encoding_changed) {
+ php_internal_encoding_changed();
+ }
#ifdef PHP_WIN32
php_win32_cp_do_update(ZSTR_VAL(new_value));
#endif
{
if (new_value) {
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
+ if (php_internal_encoding_changed) {
+ php_internal_encoding_changed();
+ }
#ifdef PHP_WIN32
php_win32_cp_do_update(ZSTR_VAL(new_value));
#endif
{
if (new_value) {
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
+ if (php_internal_encoding_changed) {
+ php_internal_encoding_changed();
+ }
#ifdef PHP_WIN32
php_win32_cp_do_update(NULL);
#endif
{
if (new_value) {
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
+ if (php_internal_encoding_changed) {
+ php_internal_encoding_changed();
+ }
#ifdef PHP_WIN32
php_win32_cp_do_update(NULL);
#endif
PHPAPI void php_register_pre_request_shutdown(void (*func)(void *), void *userdata);
PHPAPI void php_com_initialize(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()
/* PHP-named Zend macro wrappers */