Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions ext/standard/basic_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,16 @@ PHP_RINIT_FUNCTION(basic) /* {{{ */
BG(strtok_last) = NULL;
BG(ctype_string) = NULL;
BG(locale_changed) = 0;
#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE) && !defined(PHP_WIN32)
BG(thread_locale) = (locale_t)0;
BG(locale_cat_collate) = NULL;
BG(locale_cat_monetary) = NULL;
BG(locale_cat_numeric) = NULL;
BG(locale_cat_time) = NULL;
# ifdef LC_MESSAGES
BG(locale_cat_messages) = NULL;
# endif
#endif
BG(user_compare_fci) = empty_fcall_info;
BG(user_compare_fci_cache) = empty_fcall_info_cache;
BG(page_uid) = -1;
Expand Down Expand Up @@ -446,13 +456,36 @@ PHP_RSHUTDOWN_FUNCTION(basic) /* {{{ */
/* Check if locale was changed and change it back
* to the value in startup environment */
if (BG(locale_changed)) {
#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE) && !defined(PHP_WIN32)
/* Restore to use the global locale for this thread and free the per-thread locale */
#ifdef LC_GLOBAL_LOCALE
uselocale(LC_GLOBAL_LOCALE);
#endif
if (BG(thread_locale)) {
freelocale(BG(thread_locale));
BG(thread_locale) = (locale_t)0;
}
#else
setlocale(LC_ALL, "C");
#endif
#if !(defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE) && !defined(PHP_WIN32))
/* Only reset process-wide LC_CTYPE when per-thread locales are not used */
zend_reset_lc_ctype_locale();
#endif
zend_update_current_locale();
if (BG(ctype_string)) {
zend_string_release_ex(BG(ctype_string), 0);
BG(ctype_string) = NULL;
}
#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE) && !defined(PHP_WIN32)
if (BG(locale_cat_collate)) { zend_string_release_ex(BG(locale_cat_collate), 0); BG(locale_cat_collate) = NULL; }
if (BG(locale_cat_monetary)) { zend_string_release_ex(BG(locale_cat_monetary), 0); BG(locale_cat_monetary) = NULL; }
if (BG(locale_cat_numeric)) { zend_string_release_ex(BG(locale_cat_numeric), 0); BG(locale_cat_numeric) = NULL; }
if (BG(locale_cat_time)) { zend_string_release_ex(BG(locale_cat_time), 0); BG(locale_cat_time) = NULL; }
# ifdef LC_MESSAGES
if (BG(locale_cat_messages)) { zend_string_release_ex(BG(locale_cat_messages), 0); BG(locale_cat_messages) = NULL; }
# endif
#endif
}

/* FG(stream_wrappers) and FG(stream_filters) are destroyed
Expand Down
16 changes: 16 additions & 0 deletions ext/standard/basic_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@

#include "url_scanner_ex.h"

/* Locale headers for per-thread locale support */
#include <locale.h>
#ifdef HAVE_XLOCALE_H
# include <xlocale.h>
#endif

#if defined(_WIN32) && !defined(__clang__)
#include <intrin.h>
#endif
Expand Down Expand Up @@ -57,6 +63,16 @@ typedef struct _php_basic_globals {
zend_string *strtok_string;
zend_string *ctype_string; /* current LC_CTYPE locale (or NULL for 'C') */
bool locale_changed; /* locale was changed and has to be restored */
#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE) && !defined(PHP_WIN32)
locale_t thread_locale;
zend_string *locale_cat_collate;
zend_string *locale_cat_monetary;
zend_string *locale_cat_numeric;
zend_string *locale_cat_time;
#ifdef LC_MESSAGES
zend_string *locale_cat_messages;
#endif
#endif
char *strtok_last;
char strtok_table[256];
size_t strtok_len;
Expand Down
Loading