From cbea717875e7bc67af2259157b1fcfd0eee38116 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Fri, 3 Dec 2021 02:42:17 +0000 Subject: [PATCH] KSES: Accept port number in PDF upload paths. Improves the URL validation in `_wp_kses_allow_pdf_objects()` to account for sites using an upload path that contains a port, for example wp.org:8080. Follow up to [51963], [52304]. Props ocean90, ramonopoly, talldanwp. See #54261. git-svn-id: https://develop.svn.wordpress.org/trunk@52309 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/kses.php | 12 ++++---- tests/phpunit/tests/kses.php | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/kses.php b/src/wp-includes/kses.php index 025ef5d66b..3d35eb2c20 100644 --- a/src/wp-includes/kses.php +++ b/src/wp-includes/kses.php @@ -2591,21 +2591,23 @@ function _wp_add_global_attributes( $value ) { * @param string $url The URL to check. * @return bool True if the URL is safe, false otherwise. */ -function _wp_kses_allow_pdf_objects( $value ) { +function _wp_kses_allow_pdf_objects( $url ) { // We're not interested in URLs that contain query strings or fragments. - if ( strpos( $value, '?' ) !== false || strpos( $value, '#' ) !== false ) { + if ( strpos( $url, '?' ) !== false || strpos( $url, '#' ) !== false ) { return false; } // If it doesn't have a PDF extension, it's not safe. - if ( 0 !== substr_compare( $value, '.pdf', -4, 4, true ) ) { + if ( 0 !== substr_compare( $url, '.pdf', -4, 4, true ) ) { return false; } // If the URL host matches the current site's media URL, it's safe. $upload_info = wp_upload_dir( null, false ); - $upload_host = wp_parse_url( $upload_info['url'], PHP_URL_HOST ); - if ( 0 === strpos( $value, "http://$upload_host/" ) || 0 === strpos( $value, "https://$upload_host/" ) ) { + $parsed_url = wp_parse_url( $upload_info['url'] ); + $upload_host = isset( $parsed_url['host'] ) ? $parsed_url['host'] : ''; + $upload_port = isset( $parsed_url['port'] ) ? ':' . $parsed_url['port'] : ''; + if ( 0 === strpos( $url, "http://$upload_host$upload_port/" ) || 0 === strpos( $url, "https://$upload_host$upload_port/" ) ) { return true; } diff --git a/tests/phpunit/tests/kses.php b/tests/phpunit/tests/kses.php index 8c857fe7d8..cda6d3d7e4 100644 --- a/tests/phpunit/tests/kses.php +++ b/tests/phpunit/tests/kses.php @@ -1596,9 +1596,64 @@ EOF; '', '', ), + 'url with port number-like path' => array( + '', + '', + ), ); } + /** + * Test that object tags are allowed when there is a port number in the URL. + * + * @ticket 54261 + * + * @dataProvider data_wp_kses_object_data_url_with_port_number_allowed + * + * @param string $html A string of HTML to test. + * @param string $expected The expected result from KSES. + */ + function test_wp_kses_object_data_url_with_port_number_allowed( $html, $expected ) { + add_filter( 'upload_dir', array( $this, 'wp_kses_upload_dir_filter' ), 10, 2 ); + $this->assertSame( $expected, wp_kses_post( $html ) ); + } + + /** + * Data provider for test_wp_kses_object_data_url_with_port_number_allowed(). + */ + function data_wp_kses_object_data_url_with_port_number_allowed() { + return array( + 'url with port number' => array( + '', + '', + ), + 'url with port number and http protocol' => array( + '', + '', + ), + 'url with wrong port number' => array( + '', + '', + ), + 'url without port number' => array( + '', + '', + ), + ); + } + + /** + * Filter upload directory for tests using port number. + * + * @param array $param See wp_upload_dir() + * @return array $param with a modified `url`. + */ + public function wp_kses_upload_dir_filter( $param ) { + $url_with_port_number = is_string( $param['url'] ) ? str_replace( 'example.org', 'example.org:8888', $param['url'] ) : $param['url']; + $param['url'] = $url_with_port_number; + return $param; + } + /** * Test that object tags will continue to function if they've been added using the * 'wp_kses_allowed_html' filter.