From 4337c258dc1f6f763b416afc96d2141dfe793132 Mon Sep 17 00:00:00 2001 From: Jake Spurlock Date: Fri, 10 Jul 2020 22:21:22 +0000 Subject: [PATCH] Feeds: Ensure that enclosures produce valid XML. Metadata that is stored on newlines has the possibility of missing values, so rather then coercing values, we can check for them and then implicity set the values. Fixes #33591. Props jonnybot, stevenkword, vtieu, birgire, SergeyBiryukov, davidbaumwald, rebasaurus, whyisjake. git-svn-id: https://develop.svn.wordpress.org/trunk@48429 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/feed.php | 31 +++++++++++++- tests/phpunit/tests/feed/atom.php | 71 +++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/feed.php b/src/wp-includes/feed.php index d2fd25ecb0..d56ce8b18e 100644 --- a/src/wp-includes/feed.php +++ b/src/wp-includes/feed.php @@ -519,6 +519,35 @@ function atom_enclosure() { if ( 'enclosure' === $key ) { foreach ( (array) $val as $enc ) { $enclosure = explode( "\n", $enc ); + + $url = ''; + $type = ''; + $length = 0; + + $mimes = get_allowed_mime_types(); + + // Parse url + if ( isset( $enclosure[0] ) && is_string( $enclosure[0] ) ) { + $url = trim( $enclosure[0] ); + } + + // Parse length and type + foreach ( range( 1, 2 ) as $i ) { + if ( isset( $enclosure[ $i ] ) ) { + if ( is_numeric( $enclosure[ $i ] ) ) { + $length = trim( $enclosure[ $i ] ); + } elseif ( in_array( $enclosure[ $i ], $mimes ) ) { + $type = trim( $enclosure[ $i ] ); + } + } + } + + $html_link_tag = sprintf( + "\n", + esc_url( $url ), + esc_attr( $length ), + esc_attr( $type ) + ); /** * Filters the atom enclosure HTML link tag for the current post. * @@ -526,7 +555,7 @@ function atom_enclosure() { * * @param string $html_link_tag The HTML link tag with a URI and other attributes. */ - echo apply_filters( 'atom_enclosure', '' . "\n" ); + echo apply_filters( 'atom_enclosure', $html_link_tag ); } } } diff --git a/tests/phpunit/tests/feed/atom.php b/tests/phpunit/tests/feed/atom.php index 56f15e5d0d..0fe0413233 100644 --- a/tests/phpunit/tests/feed/atom.php +++ b/tests/phpunit/tests/feed/atom.php @@ -205,4 +205,75 @@ class Tests_Feeds_Atom extends WP_UnitTestCase { } } } + + /** + * @test 33591 + */ + function test_atom_enclosure_with_extended_url_length_type_parsing() { + $enclosures = array( + array( + 'actual' => "https://wordpress.dev/wp-content/uploads/2017/09/movie.mp4\n318465\nvideo/mp4", // url length type + 'expected' => array( + 'href' => 'https://wordpress.dev/wp-content/uploads/2017/09/movie.mp4', + 'length' => 318465, + 'type' => 'video/mp4', + ), + ), + array( + 'actual' => "https://wordpress.dev/wp-content/uploads/2017/09/movie.mp4\nvideo/mp4\n318465", // url type length + 'expected' => array( + 'href' => 'https://wordpress.dev/wp-content/uploads/2017/09/movie.mp4', + 'length' => 318465, + 'type' => 'video/mp4', + ), + ), + array( + 'actual' => "https://wordpress.dev/wp-content/uploads/2017/09/movie.mp4\n318465", // url length + 'expected' => array( + 'href' => 'https://wordpress.dev/wp-content/uploads/2017/09/movie.mp4', + 'length' => 318465, + 'type' => '', + ), + ), + array( + 'actual' => "https://wordpress.dev/wp-content/uploads/2017/01/audio.mp3\n\naudio/mpeg", // url type + 'expected' => array( + 'href' => 'https://wordpress.dev/wp-content/uploads/2017/01/audio.mp3', + 'length' => 0, + 'type' => 'audio/mpeg', + ), + ), + array( + 'actual' => 'https://wordpress.dev/wp-content/uploads/2016/01/test.mp4', // url + 'expected' => array( + 'href' => 'https://wordpress.dev/wp-content/uploads/2016/01/test.mp4', + 'length' => 0, + 'type' => '', + ), + ), + ); + + $post_id = end( self::$posts ); + foreach ( $enclosures as $enclosure ) { + add_post_meta( $post_id, 'enclosure', $enclosure['actual'] ); + } + $this->go_to( '/?feed=atom' ); + $feed = $this->do_atom(); + $xml = xml_to_array( $feed ); + $entries = xml_find( $xml, 'feed', 'entry' ); + $entries = array_slice( $entries, 0, 1 ); + + foreach ( $entries as $key => $entry ) { + $links = xml_find( $entries[ $key ]['child'], 'link' ); + $i = 0; + foreach ( (array) $links as $link ) { + if ( 'enclosure' == $link['attributes']['rel'] ) { + $this->assertEquals( $enclosures[ $i ]['expected']['href'], $link['attributes']['href'] ); + $this->assertEquals( $enclosures[ $i ]['expected']['length'], $link['attributes']['length'] ); + $this->assertEquals( $enclosures[ $i ]['expected']['type'], $link['attributes']['type'] ); + $i++; + } + } + } + } }