Make WordPress Core


Ignore:
Timestamp:
12/14/2021 02:59:33 PM (5 years ago)
Author:
hellofromTonya
Message:

Formatting: Use is_scalar() in sanitize_key().

This is a follow-up to [52292] which introduced is_string() to check the given key is a string to be sanitized, else the key is set to an empty string.

sanitize_key() is clearly identified (in the documentation) to only work with string keys. However, it had a bug in it that allowed non-strings to pass through it:

  • A non-scalar "key" would throw a PHP Warning (which was resolved in [52292].
  • A non-string scalar "key" was handled by the PHP native strtolower() which converted it into a string.

While is_string() is valid, non-string scalar types passed as the key to be sanitized were being set to an empty string. Given that strtolower() handles these without error or deprecation as of PHP 8.1, is_scalar() protects the website from issues while retaining the past behavior of converting integer keys (for example) into a string.

Changes include:

  • Using is_scalar() instead of is_string()
  • Refactor for readability and less code
  • More tests

Please note, this does not change the behavior of the function, nor redefine it to now accept non-string scalars.

References:

Follow-up [52292].

Props wppunk, hellofromTonya, costdev, jrf.
Fixes #54160.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/formatting/sanitizeKey.php

    r52292 r52370  
    88
    99        /**
    10          * @ticket 54160
     10         * @ticket       54160
    1111         * @dataProvider data_sanitize_key
    1212         *
    13          * @param mixed $key       The key to sanitize.
    14          * @param mixed $expected The expected value.
     13         * @param string $key      The key to sanitize.
     14         * @param string $expected The expected value.
    1515         */
    1616        public function test_sanitize_key( $key, $expected ) {
     
    1818        }
    1919
     20        /**
     21         * Data provider.
     22         *
     23         * @return array
     24         */
    2025        public function data_sanitize_key() {
    2126                return array(
    2227                        'an empty string key'            => array(
    2328                                'key'      => '',
    24                                 'expected' => '',
    25                         ),
    26                         'a null key'                     => array(
    27                                 'key'      => null,
    28                                 'expected' => '',
    29                         ),
    30                         'an int 0 key'                   => array(
    31                                 'key'      => 0,
    32                                 'expected' => '',
    33                         ),
    34                         'a true key'                     => array(
    35                                 'key'      => true,
    36                                 'expected' => '',
    37                         ),
    38                         'an array key'                   => array(
    39                                 'key'      => array( 'Howdy, admin!' ),
    4029                                'expected' => '',
    4130                        ),
     
    7261
    7362        /**
    74          * @ticket 54160
     63         * @ticket       54160
     64         * @dataProvider data_sanitize_key_nonstring_scalar
    7565         *
    76          * @covers WP_Hook::sanitize_key
     66         * @param mixed  $key      The key to sanitize.
     67         * @param string $expected The expected value.
    7768         */
    78         public function test_filter_sanitize_key() {
    79                 $key = 'Howdy, admin!';
     69        public function test_sanitize_key_nonstring_scalar( $key, $expected ) {
     70                $this->assertSame( $expected, sanitize_key( $key ) );
     71        }
    8072
     73        /**
     74         * Data provider.
     75         *
     76         * @return array
     77         */
     78        public function data_sanitize_key_nonstring_scalar() {
     79                return array(
     80                        'integer type'  => array(
     81                                'key'      => 0,
     82                                'expected' => '0',
     83                        ),
     84                        'boolean true'  => array(
     85                                'key'      => true,
     86                                'expected' => '1',
     87                        ),
     88                        'boolean false' => array(
     89                                'key'      => false,
     90                                'expected' => '',
     91                        ),
     92                        'float type'    => array(
     93                                'key'      => 0.123,
     94                                'expected' => '0123',
     95                        ),
     96                );
     97        }
     98
     99        /**
     100         * @ticket       54160
     101         * @dataProvider data_sanitize_key_with_non_scalars
     102         *
     103         * @param mixed $nonscalar_key A non-scalar data type given as a key.
     104         */
     105        public function test_sanitize_key_with_non_scalars( $nonscalar_key ) {
    81106                add_filter(
    82107                        'sanitize_key',
    83                         static function( $key ) {
    84                                 return 'Howdy, admin!';
    85                         }
     108                        function ( $sanitized_key, $key ) use ( $nonscalar_key ) {
     109                                $this->assertEmpty( $sanitized_key, 'Empty string not passed as first filtered argument' );
     110                                $this->assertSame( $nonscalar_key, $key, 'Given unsanitized key not passed as second filtered argument' );
     111                                return $sanitized_key;
     112                        },
     113                        10,
     114                        2
    86115                );
     116                $this->assertEmpty( sanitize_key( $nonscalar_key ), 'Non-scalar key did not return empty string' );
     117        }
    87118
    88                 $this->assertSame( $key, sanitize_key( $key ) );
     119        /**
     120         * Data provider.
     121         *
     122         * @return array
     123         */
     124        public function data_sanitize_key_with_non_scalars() {
     125                return array(
     126                        'array type' => array(
     127                                'key'      => array( 'key' ),
     128                                'expected' => '',
     129                        ),
     130                        'null'       => array(
     131                                'key'      => null,
     132                                'expected' => '',
     133                        ),
     134                        'object'     => array(
     135                                'key'      => new stdClass(),
     136                                'expected' => '',
     137                        ),
     138                );
    89139        }
    90140}
Note: See TracChangeset for help on using the changeset viewer.