Opened 33 hours ago
Last modified 5 hours ago
#66106 assigned defect (bug)
get_locale(), get_user_locale() and determine_locale() can return a non-string
| Reported by: | jonsurrell | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | 7.2 |
| Component: | I18N | Version: | |
| Severity: | normal | Keywords: | has-patch has-unit-tests |
| Cc: | Focuses: |
Description (last modified by )
get_locale(), get_user_locale() and determine_locale() can return a non-string values. All three functions are documented @return string, but they read from untyped data sources that may be invalid.
Once an unexpected value gets through, the first just-in-time translation of an unloaded text domain reaches WP_Textdomain_Registry::set(), which uses the locale as an array key: TypeError: Cannot access offset of type array on array.
This is not theoretical, it was discovered from fatal errors observed in production environments.
Change History (4)
This ticket was mentioned in PR #13335 on WordPress/wordpress-develop by @jonsurrell.
33 hours ago
#2
- Keywords has-patch has-unit-tests added
@jonsurrell commented on PR #13335:
32 hours ago
#3
@josephscott This is ready for review if you'd like to take a look.
#4
@
5 hours ago
This is not theoretical, it was discovered from fatal errors observed in production environments.
I'm curious as to the themes/plugins responsible for these errors. Clearly they are doing it wrong. Is there a better way to let them know they're doing it wrong besides what static analysis would have told them?
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Prevent non-string locale values from causing a
TypeErrorduring just-in-time translation. Arrays can come from stored options, user meta, globals, filters, or requests such aswp-login.php?wp_lang[]=de_DE; the existing truthiness checks accept them.Add
is_string()checks toget_locale(),get_user_locale()anddetermine_locale(). Invalid values use the existing fallbacks:en_USfor the site locale,get_locale()for the user or request locale, and the unfiltered locale for invalid filter results. Empty globals and emptylocaleordetermine_localefilter results now use these fallbacks too. Locale string syntax is unchanged.Writers are unchanged:
wp_insert_user(),meta_inputand direct metadata writes can still store non-strings, so the getters validate on read.Adds regression tests for stored values, globals, filters and request parameters, including translation calls with array locales.
Trac ticket: https://core.trac.wordpress.org/ticket/66106
## Use of AI Tools
AI assistance: Yes
Tools: Claude Code (Claude Opus 5, Claude Fable 5.1), Codex
Used for: Investigation, implementation, tests, review and description. Codex revised the description.