diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index 9d72c7fb05..d9ff86e1fa 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -41,7 +41,14 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { // List themes global styles. register_rest_route( $this->namespace, - '/' . $this->rest_base . '/themes/(?P[\/\s%\w\.\(\)\[\]\@_\-]+)', + // The route. + sprintf( + '/%s/themes/(?P%s)', + $this->rest_base, + // Matches theme's directory: `/themes///` or `/themes//`. + // Excludes invalid directory name characters: `/:<>*?"|`. + '[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?' + ), array( array( 'methods' => WP_REST_Server::READABLE, @@ -61,7 +68,7 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { // Lists/updates a single global style variation based on the given id. register_rest_route( $this->namespace, - '/' . $this->rest_base . '/(?P[\/\s%\w\.\(\)\[\]\@_\-]+)', + '/' . $this->rest_base . '/(?P[\/\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, @@ -88,8 +95,8 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { /** * Sanitize the global styles ID or stylesheet to decode endpoint. - * For example, `wp/v2/global-styles/templatetwentytwo%200.4.0` - * would be decoded to `templatetwentytwo 0.4.0`. + * For example, `wp/v2/global-styles/twentytwentytwo%200.4.0` + * would be decoded to `twentytwentytwo 0.4.0`. * * @since 5.9.0 * diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php index dae9d88931..8306774160 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php @@ -68,7 +68,16 @@ class WP_REST_Templates_Controller extends WP_REST_Controller { // Lists/updates a single template based on the given id. register_rest_route( $this->namespace, - '/' . $this->rest_base . '/(?P[\/\s%\w\.\(\)\[\]\@_\-]+)', + // The route. + sprintf( + '/%s/(?P%s%s)', + $this->rest_base, + // Matches theme's directory: `/themes///` or `/themes//`. + // Excludes invalid directory name characters: `/:<>*?"|`. + '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', + // Matches the template name. + '[\/\w-]+' + ), array( 'args' => array( 'id' => array( @@ -149,7 +158,6 @@ class WP_REST_Templates_Controller extends WP_REST_Controller { * @return string Sanitized template ID. */ public function _sanitize_template_id( $id ) { - // Decode empty space. $id = urldecode( $id ); $last_slash_pos = strrpos( $id, '/' ); diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php index 0d6ffd0da2..05cd65c47a 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php @@ -16,7 +16,11 @@ */ class WP_REST_Themes_Controller extends WP_REST_Controller { - const PATTERN = '[^.\/]+(?:\/[^.\/]+)?'; + /** + * Matches theme's directory: `/themes///` or `/themes//`. + * Excludes invalid directory name characters: `/:<>*?"|`. + */ + const PATTERN = '[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?'; /** * Constructor. @@ -56,8 +60,9 @@ class WP_REST_Themes_Controller extends WP_REST_Controller { array( 'args' => array( 'stylesheet' => array( - 'description' => __( "The theme's stylesheet. This uniquely identifies the theme." ), - 'type' => 'string', + 'description' => __( "The theme's stylesheet. This uniquely identifies the theme." ), + 'type' => 'string', + 'sanitize_callback' => array( $this, '_sanitize_stylesheet_callback' ), ), ), array( @@ -70,6 +75,18 @@ class WP_REST_Themes_Controller extends WP_REST_Controller { ); } + /** + * Sanitize the stylesheet to decode endpoint. + * + * @since 5.9.0 + * + * @param string $stylesheet The stylesheet name. + * @return string Sanitized stylesheet. + */ + public function _sanitize_stylesheet_callback( $stylesheet ) { + return urldecode( $stylesheet ); + } + /** * Checks if a given request has access to read the theme. * diff --git a/wp-includes/version.php b/wp-includes/version.php index d7786c75fe..38b3c1593b 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '5.9-beta3-52398'; +$wp_version = '5.9-beta3-52399'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.