Skip to content

Commit 26e4244

Browse files
committed
Fix bug #81598: Use C.UTF-8 as LC_CTYPE locale by default
Unfortunately, libedit is locale based and does not accept UTF-8 input when the C locale is used. This patch switches the default locale to C.UTF-8 instead (if it is available). This makes libedit work and I believe it shouldn't affect behavior of single-byte locale-dependent functions that PHP otherwise uses. Closes phpGH-7635.
1 parent 15e7e57 commit 26e4244

File tree

7 files changed

+20
-3
lines changed

7 files changed

+20
-3
lines changed

NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ PHP NEWS
1515
(devnexen)
1616
. Introduced MYSQLI_IS_MARIADB. (devnexen)
1717

18+
- Readline:
19+
. Fixed bug #81598 (Cannot input unicode characters in PHP 8 interactive
20+
shell). (Nikita)
21+
1822
- Reflection:
1923
. Fixed bug #81681 (ReflectionEnum throwing exceptions). (cmb)
2024

Zend/tests/lc_ctype_inheritance.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ var_dump(setlocale(LC_CTYPE, "de_DE", "de-DE") !== false);
1616
var_dump(bin2hex(strtoupper("\xe4")));
1717
var_dump(preg_match('/\w/', "\xe4"));
1818
?>
19-
--EXPECT--
20-
string(1) "C"
19+
--EXPECTF--
20+
string(%d) "C%r(\.UTF-8)?%r"
2121
string(2) "e4"
2222
int(0)
2323
bool(true)

Zend/zend_operators.c

+9
Original file line numberDiff line numberDiff line change
@@ -2662,6 +2662,15 @@ ZEND_API void zend_update_current_locale(void) /* {{{ */
26622662
}
26632663
/* }}} */
26642664

2665+
ZEND_API void zend_reset_lc_ctype_locale(void)
2666+
{
2667+
/* Use the C.UTF-8 locale so that readline can process UTF-8 input, while not interfering
2668+
* with single-byte locale-dependent functions used by PHP. */
2669+
if (!setlocale(LC_CTYPE, "C.UTF-8")) {
2670+
setlocale(LC_CTYPE, "C");
2671+
}
2672+
}
2673+
26652674
static zend_always_inline void zend_str_tolower_impl(char *dest, const char *str, size_t length) /* {{{ */ {
26662675
unsigned char *p = (unsigned char*)str;
26672676
unsigned char *q = (unsigned char*)dest;

Zend/zend_operators.h

+2
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,8 @@ ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len);
472472

473473
ZEND_API void zend_update_current_locale(void);
474474

475+
ZEND_API void zend_reset_lc_ctype_locale(void);
476+
475477
/* The offset in bytes between the value and type fields of a zval */
476478
#define ZVAL_OFFSETOF_TYPE \
477479
(offsetof(zval, u1.type_info) - offsetof(zval, value))

ext/snmp/snmp.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1999,7 +1999,7 @@ PHP_MINIT_FUNCTION(snmp)
19991999

20002000
init_snmp("snmpapp");
20012001
/* net-snmp corrupts the CTYPE locale during initialization. */
2002-
setlocale(LC_CTYPE, "C");
2002+
zend_reset_lc_ctype_locale();
20032003

20042004
#ifdef NETSNMP_DS_LIB_DONT_PERSIST_STATE
20052005
/* Prevent update of the snmpapp.conf file */

ext/standard/basic_functions.c

+1
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ PHP_RSHUTDOWN_FUNCTION(basic) /* {{{ */
528528
* to the value in startup environment */
529529
if (BG(locale_changed)) {
530530
setlocale(LC_ALL, "C");
531+
zend_reset_lc_ctype_locale();
531532
zend_update_current_locale();
532533
if (BG(ctype_string)) {
533534
zend_string_release_ex(BG(ctype_string), 0);

main/main.c

+1
Original file line numberDiff line numberDiff line change
@@ -2087,6 +2087,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
20872087
zuf.getenv_function = sapi_getenv;
20882088
zuf.resolve_path_function = php_resolve_path_for_zend;
20892089
zend_startup(&zuf);
2090+
zend_reset_lc_ctype_locale();
20902091
zend_update_current_locale();
20912092

20922093
zend_observer_startup();

0 commit comments

Comments
 (0)