From 2ba4a4817ad95f3ec63de022988f1cee959f9a55 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sun, 1 Aug 2021 14:54:52 +0000 Subject: [PATCH] Themes: Make sure `get_theme_mods()` always returns an array. This avoids a "Cannot access offset of type string on string" fatal error in `set_theme_mod()` on PHP 8 if the `theme_mods_$theme_slug` option has an incorrect value, e.g. an empty string instead of an array. With this change, `set_theme_mod()` should be able to resolve the issue by saving a correct value. Follow-up to [15736], [15739], [30672], [32629], [32632]. Props xknown. See #51423. git-svn-id: https://develop.svn.wordpress.org/trunk@51524 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/theme.php | 10 +++++++++- tests/phpunit/tests/option/themeMods.php | 9 +++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index dae7ed7e4c..7d1669caf1 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -966,23 +966,31 @@ function validate_theme_requirements( $stylesheet ) { * Retrieves all theme modifications. * * @since 3.1.0 + * @since 5.9.0 The return value is always an array. * - * @return array|void Theme modifications. + * @return array Theme modifications. */ function get_theme_mods() { $theme_slug = get_option( 'stylesheet' ); $mods = get_option( "theme_mods_$theme_slug" ); + if ( false === $mods ) { $theme_name = get_option( 'current_theme' ); if ( false === $theme_name ) { $theme_name = wp_get_theme()->get( 'Name' ); } + $mods = get_option( "mods_$theme_name" ); // Deprecated location. if ( is_admin() && false !== $mods ) { update_option( "theme_mods_$theme_slug", $mods ); delete_option( "mods_$theme_name" ); } } + + if ( ! is_array( $mods ) ) { + $mods = array(); + } + return $mods; } diff --git a/tests/phpunit/tests/option/themeMods.php b/tests/phpunit/tests/option/themeMods.php index 53683f72a0..2ed14f194f 100644 --- a/tests/phpunit/tests/option/themeMods.php +++ b/tests/phpunit/tests/option/themeMods.php @@ -19,6 +19,15 @@ class Tests_Option_Theme_Mods extends WP_UnitTestCase { $this->assertSame( $expected, get_theme_mod( 'test_name' ) ); } + /** + * @ticket 51423 + */ + function test_theme_mod_set_with_invalid_theme_mods_option() { + $theme_slug = get_option( 'stylesheet' ); + update_option( 'theme_mods_' . $theme_slug, '' ); + self::test_theme_mod_set(); + } + function test_theme_mod_update() { set_theme_mod( 'test_update', 'first_value' ); $expected = 'updated_value';