wordpress-develop/tests/phpunit/tests/formatting/sanitizeKey.php
Tonya Mork d3a851d0d1 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:
* https://developer.wordpress.org/reference/functions/sanitize_key/
* https://www.php.net/manual/en/function.strtolower.php

Follow-up [52292].

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

git-svn-id: https://develop.svn.wordpress.org/trunk@52370 602fd350-edb4-49c9-b593-d223f7449a82
2021-12-14 14:59:33 +00:00

141 lines
3.3 KiB
PHP

<?php
/**
* @group formatting
* @covers ::sanitize_key
*/
class Tests_Formatting_SanitizeKey extends WP_UnitTestCase {
/**
* @ticket 54160
* @dataProvider data_sanitize_key
*
* @param string $key The key to sanitize.
* @param string $expected The expected value.
*/
public function test_sanitize_key( $key, $expected ) {
$this->assertSame( $expected, sanitize_key( $key ) );
}
/**
* Data provider.
*
* @return array
*/
public function data_sanitize_key() {
return array(
'an empty string key' => array(
'key' => '',
'expected' => '',
),
'a lowercase key with commas' => array(
'key' => 'howdy,admin',
'expected' => 'howdyadmin',
),
'a lowercase key with commas' => array(
'key' => 'HOWDY,ADMIN',
'expected' => 'howdyadmin',
),
'a mixed case key with commas' => array(
'key' => 'HoWdY,aDmIn',
'expected' => 'howdyadmin',
),
'a key with dashes' => array(
'key' => 'howdy-admin',
'expected' => 'howdy-admin',
),
'a key with spaces' => array(
'key' => 'howdy admin',
'expected' => 'howdyadmin',
),
'a key with a HTML entity' => array(
'key' => 'howdy&nbsp;admin',
'expected' => 'howdynbspadmin',
),
'a key with a unicode character' => array(
'key' => 'howdy' . chr( 140 ) . 'admin',
'expected' => 'howdyadmin',
),
);
}
/**
* @ticket 54160
* @dataProvider data_sanitize_key_nonstring_scalar
*
* @param mixed $key The key to sanitize.
* @param string $expected The expected value.
*/
public function test_sanitize_key_nonstring_scalar( $key, $expected ) {
$this->assertSame( $expected, sanitize_key( $key ) );
}
/**
* Data provider.
*
* @return array
*/
public function data_sanitize_key_nonstring_scalar() {
return array(
'integer type' => array(
'key' => 0,
'expected' => '0',
),
'boolean true' => array(
'key' => true,
'expected' => '1',
),
'boolean false' => array(
'key' => false,
'expected' => '',
),
'float type' => array(
'key' => 0.123,
'expected' => '0123',
),
);
}
/**
* @ticket 54160
* @dataProvider data_sanitize_key_with_non_scalars
*
* @param mixed $nonscalar_key A non-scalar data type given as a key.
*/
public function test_sanitize_key_with_non_scalars( $nonscalar_key ) {
add_filter(
'sanitize_key',
function ( $sanitized_key, $key ) use ( $nonscalar_key ) {
$this->assertEmpty( $sanitized_key, 'Empty string not passed as first filtered argument' );
$this->assertSame( $nonscalar_key, $key, 'Given unsanitized key not passed as second filtered argument' );
return $sanitized_key;
},
10,
2
);
$this->assertEmpty( sanitize_key( $nonscalar_key ), 'Non-scalar key did not return empty string' );
}
/**
* Data provider.
*
* @return array
*/
public function data_sanitize_key_with_non_scalars() {
return array(
'array type' => array(
'key' => array( 'key' ),
'expected' => '',
),
'null' => array(
'key' => null,
'expected' => '',
),
'object' => array(
'key' => new stdClass(),
'expected' => '',
),
);
}
}