Commit 778ed86b2d for wordpress.org
commit 778ed86b2d9928fa98ac72486b62293ce81f6ccc
Author: jonsurrell <jonsurrell@git.wordpress.org>
Date: Tue Oct 6 09:32:52 2026 +0000
I18N: Ignore non-string values in the locale getters.
`get_locale()`, `get_user_locale()` and `determine_locale()` read untyped values from options, user meta, globals, filters and request parameters. A non-string value can cause a `TypeError` during just-in-time translation. The getters now ignore non-string and empty values and use their existing fallbacks.
Developed in: https://github.com/WordPress/wordpress-develop/pull/13335
Props jonsurrell, westonruter, josephscott.
Fixes #66106.
Built from https://develop.svn.wordpress.org/trunk@64122
git-svn-id: http://core.svn.wordpress.org/trunk@63278 1a063a9b-81f0-0310-95a4-ce76da25c4cd
diff --git a/wp-includes/formatting.php b/wp-includes/formatting.php
index c39beaf7b1..480ca7fb5e 100644
--- a/wp-includes/formatting.php
+++ b/wp-includes/formatting.php
@@ -2498,6 +2498,11 @@ function sanitize_html_class( $classname, $fallback = '' ) {
* @return string The sanitized value.
*/
function sanitize_locale_name( $locale_name ) {
+ // Request values can arrive as arrays, and preg_replace() would map over them.
+ if ( ! is_string( $locale_name ) ) {
+ return '';
+ }
+
// Limit to A-Z, a-z, 0-9, '_', '-'.
$sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $locale_name );
diff --git a/wp-includes/l10n.php b/wp-includes/l10n.php
index 7b9d2652d4..f83d1ce61f 100644
--- a/wp-includes/l10n.php
+++ b/wp-includes/l10n.php
@@ -31,8 +31,18 @@ function get_locale() {
global $locale, $wp_local_package;
if ( isset( $locale ) ) {
+ if ( empty( $locale ) || ! is_string( $locale ) ) {
+ $locale = 'en_US';
+ }
+
/** This filter is documented in wp-includes/l10n.php */
- return apply_filters( 'locale', $locale );
+ $filtered_locale = apply_filters( 'locale', $locale );
+
+ if ( empty( $filtered_locale ) || ! is_string( $filtered_locale ) ) {
+ return $locale;
+ }
+
+ return $filtered_locale;
}
if ( isset( $wp_local_package ) ) {
@@ -66,18 +76,26 @@ function get_locale() {
}
}
- if ( empty( $locale ) ) {
+ if ( empty( $locale ) || ! is_string( $locale ) ) {
$locale = 'en_US';
}
/**
* Filters the locale ID of the WordPress installation.
*
+ * A non-string or empty value is ignored.
+ *
* @since 1.5.0
*
* @param string $locale The locale ID.
*/
- return apply_filters( 'locale', $locale );
+ $filtered_locale = apply_filters( 'locale', $locale );
+
+ if ( empty( $filtered_locale ) || ! is_string( $filtered_locale ) ) {
+ return $locale;
+ }
+
+ return $filtered_locale;
}
/**
@@ -108,7 +126,11 @@ function get_user_locale( $user = 0 ) {
$locale = $user_object->locale;
- return $locale ? $locale : get_locale();
+ if ( empty( $locale ) || ! is_string( $locale ) ) {
+ return get_locale();
+ }
+
+ return $locale;
}
/**
@@ -162,18 +184,26 @@ function determine_locale() {
}
}
- if ( ! $determined_locale ) {
+ if ( empty( $determined_locale ) || ! is_string( $determined_locale ) ) {
$determined_locale = get_locale();
}
/**
* Filters the locale for the current request.
*
+ * A non-string or empty value is ignored.
+ *
* @since 5.0.0
*
* @param string $determined_locale The locale.
*/
- return apply_filters( 'determine_locale', $determined_locale );
+ $filtered_locale = apply_filters( 'determine_locale', $determined_locale );
+
+ if ( empty( $filtered_locale ) || ! is_string( $filtered_locale ) ) {
+ return $determined_locale;
+ }
+
+ return $filtered_locale;
}
/**
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 28e2675257..516d385c01 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '7.2-alpha-64121';
+$wp_version = '7.2-alpha-64122';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.