Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/wp-includes/kses.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
55 changes: 55 additions & 0 deletions tests/phpunit/tests/kses.php
Original file line number Diff line number Diff line change
Expand Up @@ -1596,9 +1596,64 @@ function data_wp_kses_object_tag_allowed() {
'<object type="application/pdf" data="/cat/foo.pdf" />',
'',
),
'url with port number-like path' => array(
'<object type="application/pdf" data="https://example.org/cat:8888/foo.pdf" />',
'<object type="application/pdf" data="https://example.org/cat:8888/foo.pdf" />',
),
);
}

/**
* 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(
'<object type="application/pdf" data="https://example.org:8888/cat/foo.pdf" />',
'<object type="application/pdf" data="https://example.org:8888/cat/foo.pdf" />',
),
'url with port number and http protocol' => array(
'<object type="application/pdf" data="http://example.org:8888/cat/foo.pdf" />',
'<object type="application/pdf" data="http://example.org:8888/cat/foo.pdf" />',
),
'url with wrong port number' => array(
'<object type="application/pdf" data="http://example.org:3333/cat/foo.pdf" />',
'',
),
'url without port number' => array(
'<object type="application/pdf" data="http://example.org/cat/foo.pdf" />',
'',
),
);
}

/**
* 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.
Expand Down