From b71c362368e4c14493d22cb0288c7460dad63c9a Mon Sep 17 00:00:00 2001 From: Khokan Sardar Date: Thu, 21 May 2026 00:26:08 +0530 Subject: [PATCH] General Settings: Reject empty custom date and time formats. Validate custom date and time format fields on the General Settings screen before saving. When either custom field is empty, restore the previous value, show an admin error, and reject empty values in sanitize_option() as well. Fixes #65281. --- src/wp-admin/options.php | 29 +++++++++++++- src/wp-includes/formatting.php | 4 ++ tests/phpunit/tests/option/sanitizeOption.php | 39 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/wp-admin/options.php b/src/wp-admin/options.php index b45cbb00387ce..2c16b6930a23a 100644 --- a/src/wp-admin/options.php +++ b/src/wp-admin/options.php @@ -267,16 +267,41 @@ if ( 'general' === $option_page ) { // Handle custom date/time formats. + $invalid_date_time_format = false; + if ( ! empty( $_POST['date_format'] ) && isset( $_POST['date_format_custom'] ) && '\c\u\s\t\o\m' === wp_unslash( $_POST['date_format'] ) ) { - $_POST['date_format'] = $_POST['date_format_custom']; + $date_format_custom = trim( wp_unslash( $_POST['date_format_custom'] ) ); + + if ( '' === $date_format_custom ) { + $_POST['date_format'] = get_option( 'date_format' ); + $invalid_date_time_format = true; + } else { + $_POST['date_format'] = $date_format_custom; + } } if ( ! empty( $_POST['time_format'] ) && isset( $_POST['time_format_custom'] ) && '\c\u\s\t\o\m' === wp_unslash( $_POST['time_format'] ) ) { - $_POST['time_format'] = $_POST['time_format_custom']; + $time_format_custom = trim( wp_unslash( $_POST['time_format_custom'] ) ); + + if ( '' === $time_format_custom ) { + $_POST['time_format'] = get_option( 'time_format' ); + $invalid_date_time_format = true; + } else { + $_POST['time_format'] = $time_format_custom; + } + } + + if ( $invalid_date_time_format ) { + add_settings_error( + 'general', + 'invalid_date_time_format', + __( 'Please configure a valid date and time format.' ), + 'error' + ); } // Map UTC+- timezones to gmt_offsets and set timezone_string to empty. diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 498d676f5c20f..761306ff90c0c 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -4957,6 +4957,10 @@ function sanitize_option( $option, $value ) { } else { $value = strip_tags( $value ); $value = wp_kses_data( $value ); + + if ( ( 'date_format' === $option || 'time_format' === $option ) && '' === $value ) { + $error = __( 'Please configure a valid date and time format.' ); + } } break; diff --git a/tests/phpunit/tests/option/sanitizeOption.php b/tests/phpunit/tests/option/sanitizeOption.php index 68597b8acdaea..deaf2c170721a 100644 --- a/tests/phpunit/tests/option/sanitizeOption.php +++ b/tests/phpunit/tests/option/sanitizeOption.php @@ -175,4 +175,43 @@ public function data_sanitize_option_permalink_structure() { array( new WP_Error( 'wpdb_get_table_charset_failure' ), false, false ), // @ticket 53986 ); } + + /** + * @ticket 65281 + * + * @covers ::sanitize_option + * @covers ::get_settings_errors + * + * @dataProvider data_sanitize_option_date_time_format + */ + public function test_sanitize_option_date_time_format( $option_name, $provided, $expected, $valid ) { + global $wp_settings_errors; + + $old_wp_settings_errors = (array) $wp_settings_errors; + + update_option( $option_name, $expected ); + + $actual = sanitize_option( $option_name, $provided ); + $errors = get_settings_errors( $option_name ); + + $wp_settings_errors = $old_wp_settings_errors; + + if ( $valid ) { + $this->assertEmpty( $errors ); + } else { + $this->assertNotEmpty( $errors ); + $this->assertSame( 'invalid_' . $option_name, $errors[0]['code'] ); + } + + $this->assertSame( $expected, $actual ); + } + + public function data_sanitize_option_date_time_format() { + return array( + array( 'date_format', 'F j, Y', 'F j, Y', true ), + array( 'date_format', '', 'Y-m-d', false ), + array( 'time_format', 'g:i a', 'g:i a', true ), + array( 'time_format', '', 'g:i a', false ), + ); + } }