Make WordPress Core


Ignore:
Timestamp:
12/21/2021 04:12:06 AM (3 years ago)
Author:
hellofromTonya
Message:

REST API: Support . in theme directory names in WP_REST_Global_Styles_Controller, WP_REST_Templates_Controller, and WP_REST_Themes_Controller.

Regex changes from [52376] are reverted to restore the original regex patterns. Why? [52376] used an include characters pattern, which was too limiting. It did not account for localized characters, such as é, or other valid directory name characters.

The original theme directory regex pattern, i.e. [^.\/]+(?:\/[^.\/]+)? excluded the period . character. Removing the . character resolves the reported issue by allowing matching for themes/theme-dirname-1.0/ or themes/<subdirname>/theme-dirname-1.0/.

As the pattern used an exclude approach, all characters are valid for matching except for /. However, not all characters are cross-platform valid for directory names. For example, the characters /:<>*?"| are not valid on Windows OS. The pattern now excludes those characters.

The theme's directory (or subdirectory) name pattern matching is now used in WP_REST_Global_Styles_Controller, WP_REST_Templates_Controller, and WP_REST_Themes_Controller.

Follow-up to [51003], [52051], [52275], [52376].

Props costdev, hellofromTonya, spacedmonkey, TimothyBlynJacobs, bijayyadav, kafleg.
Fixes #54596.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api/rest-global-styles-controller.php

    r52376 r52399  
    9999        $routes = rest_get_server()->get_routes();
    100100        $this->assertArrayHasKey(
    101             '/wp/v2/global-styles/(?P<id>[\/\s%\w\.\(\)\[\]\@_\-]+)',
     101            '/wp/v2/global-styles/(?P<id>[\/\w-]+)',
    102102            $routes,
    103103            'Single global style based on the given ID route does not exist'
     
    105105        $this->assertCount(
    106106            2,
    107             $routes['/wp/v2/global-styles/(?P<id>[\/\s%\w\.\(\)\[\]\@_\-]+)'],
     107            $routes['/wp/v2/global-styles/(?P<id>[\/\w-]+)'],
    108108            'Single global style based on the given ID route does not have exactly two elements'
    109109        );
    110110        $this->assertArrayHasKey(
    111             '/wp/v2/global-styles/themes/(?P<stylesheet>[\/\s%\w\.\(\)\[\]\@_\-]+)',
     111            '/wp/v2/global-styles/themes/(?P<stylesheet>[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)',
    112112            $routes,
    113113            'Theme global styles route does not exist'
     
    115115        $this->assertCount(
    116116            1,
    117             $routes['/wp/v2/global-styles/themes/(?P<stylesheet>[\/\s%\w\.\(\)\[\]\@_\-]+)'],
     117            $routes['/wp/v2/global-styles/themes/(?P<stylesheet>[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)'],
    118118            'Theme global styles route does not have exactly one element'
    119119        );
     
    165165     * @covers WP_REST_Global_Styles_Controller::get_theme_item
    166166     * @ticket 54596
    167      */
    168     public function test_get_theme_item_invalid_theme_dirname( $theme_dirname ) {
     167     *
     168     * @param string $theme_dirname Theme directory to test.
     169     * @param string $expected      Expected error code.
     170     */
     171    public function test_get_theme_item_invalid_theme_dirname( $theme_dirname, $expected ) {
    169172        wp_set_current_user( self::$admin_id );
    170173        switch_theme( $theme_dirname );
     
    172175        $request  = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/' . $theme_dirname );
    173176        $response = rest_get_server()->dispatch( $request );
    174         $this->assertErrorResponse( 'rest_no_route', $response, 404 );
     177        $this->assertErrorResponse( $expected, $response, 404 );
    175178    }
    176179
     
    182185    public function data_get_theme_item_invalid_theme_dirname() {
    183186        return array(
    184             'with |'                 => array( 'my|theme' ),
    185             'with +'                 => array( 'my+theme' ),
    186             'with {}'                => array( 'my{theme}' ),
    187             'with #'                 => array( 'my#theme' ),
    188             'with !'                 => array( 'my!theme' ),
    189             'multiple invalid chars' => array( 'mytheme-[_(+@)]#! v4.0' ),
     187            '+'                      => array(
     188                'theme_dirname' => 'my+theme+',
     189                'expected'      => 'rest_theme_not_found',
     190            ),
     191            ':'                      => array(
     192                'theme_dirname' => 'my:theme:',
     193                'expected'      => 'rest_no_route',
     194            ),
     195            '<>'                     => array(
     196                'theme_dirname' => 'my<theme>',
     197                'expected'      => 'rest_no_route',
     198            ),
     199            '*'                      => array(
     200                'theme_dirname' => 'my*theme*',
     201                'expected'      => 'rest_no_route',
     202            ),
     203            '?'                      => array(
     204                'theme_dirname' => 'my?theme?',
     205                'expected'      => 'rest_no_route',
     206            ),
     207            '"'                      => array(
     208                'theme_dirname' => 'my"theme?"',
     209                'expected'      => 'rest_no_route',
     210            ),
     211            '| (invalid on Windows)' => array(
     212                'theme_dirname' => 'my|theme|',
     213                'expected'      => 'rest_no_route',
     214            ),
     215            // Themes deep in subdirectories.
     216            '2 subdirectories deep'  => array(
     217                'theme_dirname' => 'subdir/subsubdir/mytheme',
     218                'expected'      => 'rest_global_styles_not_found',
     219            ),
    190220        );
    191221    }
     
    195225     * @covers WP_REST_Global_Styles_Controller::get_theme_item
    196226     * @ticket 54596
     227     *
     228     * @param string $theme Theme directory to test.
    197229     */
    198230    public function test_get_theme_item( $theme ) {
     
    217249    public function data_get_theme_item() {
    218250        return array(
    219             'alphabetic chars'   => array( 'mytheme' ),
    220             'alphanumeric chars' => array( 'mythemev1' ),
    221             'space'              => array( 'my theme' ),
    222             '-'                  => array( 'my-theme' ),
    223             '_'                  => array( 'my_theme' ),
    224             '.'                  => array( 'mytheme0.1' ),
    225             '- and .'            => array( 'my-theme-0.1' ),
    226             'space and .'        => array( 'mytheme v0.1' ),
    227             'space, -, _, .'     => array( 'my-theme-v0.1' ),
    228             '[]'                 => array( 'my[theme]' ),
    229             '()'                 => array( 'my(theme)' ),
    230             '@'                  => array( 'my@theme' ),
     251            'alphabetic'                     => array( 'mytheme' ),
     252            'alphanumeric'                   => array( 'mythemev1' ),
     253            'àáâãäåæç'                       => array( 'àáâãäåæç' ),
     254            'space'                          => array( 'my theme' ),
     255            '-_.'                            => array( 'my_theme-0.1' ),
     256            '[]'                             => array( 'my[theme]' ),
     257            '()'                             => array( 'my(theme)' ),
     258            '{}'                             => array( 'my{theme}' ),
     259            '&=#@!$,^~%'                     => array( 'theme &=#@!$,^~%' ),
     260            'all combined'                   => array( 'thémé {}&=@!$,^~%[0.1](-_-)' ),
     261
     262            // Themes in a subdirectory.
     263            'subdir: alphabetic'             => array( 'subdir/mytheme' ),
     264            'subdir: alphanumeric in theme'  => array( 'subdir/mythemev1' ),
     265            'subdir: alphanumeric in subdir' => array( 'subdirv1/mytheme' ),
     266            'subdir: alphanumeric in both'   => array( 'subdirv1/mythemev1' ),
     267            'subdir: àáâãäåæç in theme'      => array( 'subdir/àáâãäåæç' ),
     268            'subdir: àáâãäåæç in subdir'     => array( 'àáâãäåæç/mythemev1' ),
     269            'subdir: àáâãäåæç in both'       => array( 'àáâãäåæç/àáâãäåæç' ),
     270            'subdir: space in theme'         => array( 'subdir/my theme' ),
     271            'subdir: space in subdir'        => array( 'sub dir/mytheme' ),
     272            'subdir: space in both'          => array( 'sub dir/my theme' ),
     273            'subdir: -_. in theme'           => array( 'subdir/my_theme-0.1' ),
     274            'subdir: -_. in subdir'          => array( 'sub_dir-0.1/mytheme' ),
     275            'subdir: -_. in both'            => array( 'sub_dir-0.1/my_theme-0.1' ),
     276            'subdir: all combined in theme'  => array( 'subdir/thémé {}&=@!$,^~%[0.1](-_-)' ),
     277            'subdir: all combined in subdir' => array( 'sűbdīr {}&=@!$,^~%[0.1](-_-)/mytheme' ),
     278            'subdir: all combined in both'   => array( 'sűbdīr {}&=@!$,^~%[0.1](-_-)/thémé {}&=@!$,^~%[0.1](-_-)' ),
    231279        );
    232280    }
Note: See TracChangeset for help on using the changeset viewer.