diff --git a/src/wp-includes/kses.php b/src/wp-includes/kses.php index 35327e1a01cce..31aae08740ed4 100644 --- a/src/wp-includes/kses.php +++ b/src/wp-includes/kses.php @@ -2474,7 +2474,13 @@ function wp_filter_global_styles_post( $data ) { $data_to_encode = WP_Theme_JSON::remove_insecure_properties( $decoded_data, 'custom' ); $data_to_encode['isGlobalStylesUserThemeJSON'] = true; - return wp_slash( wp_json_encode( $data_to_encode ) ); + /** + * JSON encode the data stored in post content. + * Escape characters that are likely be mangled by HTML filters: "<>&". + * + * This matches the escaping in {@see WP_REST_Global_Styles_Controller::prepare_item_for_database}. + */ + return wp_slash( wp_json_encode( $data_to_encode, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) ); } return $data; } diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index 908ebe4bcc777..b66ae3537ba1d 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -253,12 +253,6 @@ protected function prepare_item_for_database( $request ) { if ( isset( $request['styles'] ) || isset( $request['settings'] ) ) { $config = array(); if ( isset( $request['styles'] ) ) { - if ( isset( $request['styles']['css'] ) ) { - $css_validation_result = $this->validate_custom_css( $request['styles']['css'] ); - if ( is_wp_error( $css_validation_result ) ) { - return $css_validation_result; - } - } $config['styles'] = $request['styles']; } elseif ( isset( $existing_config['styles'] ) ) { $config['styles'] = $existing_config['styles']; @@ -275,7 +269,14 @@ protected function prepare_item_for_database( $request ) { } $config['isGlobalStylesUserThemeJSON'] = true; $config['version'] = WP_Theme_JSON::LATEST_SCHEMA; - $changes->post_content = wp_json_encode( $config ); + /** + * JSON encode the data stored in post content. + * Escape characters that are likely be mangled by HTML filters: "<>&". + * + * This data is later re-encoded by {@see wp_filter_global_styles_post}. + * The escaping is also applied here as a precaution. + */ + $changes->post_content = wp_json_encode( $config, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); } // Post title. @@ -657,24 +658,17 @@ public function get_theme_items( $request ) { } /** - * Validate style.css as valid CSS. - * - * Currently just checks for invalid markup. - * * @since 6.2.0 * @since 6.4.0 Changed method visibility to protected. + * @deprecated 7.0.0 This method is deprecated and always returns true. + * + * @ignore * * @param string $css CSS to validate. - * @return true|WP_Error True if the input was validated, otherwise WP_Error. + * @return true|WP_Error Always returns true. */ protected function validate_custom_css( $css ) { - if ( preg_match( '#?\w+#', $css ) ) { - return new WP_Error( - 'rest_custom_css_illegal_markup', - __( 'Markup is not allowed in CSS.' ), - array( 'status' => 400 ) - ); - } + _deprecated_function( __METHOD__, '7.0.0' ); return true; } } diff --git a/tests/phpunit/tests/rest-api/rest-global-styles-controller.php b/tests/phpunit/tests/rest-api/rest-global-styles-controller.php index 59986e597c71b..126ecd28bf53b 100644 --- a/tests/phpunit/tests/rest-api/rest-global-styles-controller.php +++ b/tests/phpunit/tests/rest-api/rest-global-styles-controller.php @@ -647,25 +647,6 @@ public function test_update_item_valid_styles_css() { $this->assertSame( 'body { color: red; }', $data['styles']['css'] ); } - /** - * @covers WP_REST_Global_Styles_Controller::update_item - * @ticket 57536 - */ - public function test_update_item_invalid_styles_css() { - wp_set_current_user( self::$admin_id ); - if ( is_multisite() ) { - grant_super_admin( self::$admin_id ); - } - $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id ); - $request->set_body_params( - array( - 'styles' => array( 'css' => '
test
body { color: red; }' ), - ) - ); - $response = rest_get_server()->dispatch( $request ); - $this->assertErrorResponse( 'rest_custom_css_illegal_markup', $response, 400 ); - } - /** * Tests the submission of a custom block style variation that was defined * within a theme style variation and wouldn't be registered at the time @@ -826,4 +807,38 @@ public function test_global_styles_route_args_schema() { $this->assertArrayHasKey( 'type', $route_data[0]['args']['id'] ); $this->assertSame( 'integer', $route_data[0]['args']['id']['type'] ); } + + /** + * @covers WP_REST_Global_Styles_Controller::update_item + * @ticket 64418 + */ + public function test_update_allows_valid_css_with_more_syntax() { + wp_set_current_user( self::$admin_id ); + if ( is_multisite() ) { + grant_super_admin( self::$admin_id ); + } + $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id ); + $css = <<<'CSS' +@property --animate { + syntax: "