Ticket #45142: 45142.2.diff
File 45142.2.diff, 13.2 KB (added by , 6 years ago) |
---|
-
src/wp-includes/class-wp-oembed-controller.php
diff --git src/wp-includes/class-wp-oembed-controller.php src/wp-includes/class-wp-oembed-controller.php index 7ee7950b07..9efeb54ed0 100644
final class WP_oEmbed_Controller { 173 173 $args['height'] = $args['maxheight']; 174 174 } 175 175 176 // Short-circuit process for URLs belonging to the current site. 177 $data = get_oembed_response_data_for_url( $url, $args ); 178 179 if ( $data ) { 180 return $data; 181 } 182 176 183 $data = _wp_oembed_get_object()->get_data( $url, $args ); 177 184 178 185 if ( false === $data ) { 179 186 return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) ); 180 187 } 181 188 189 /** This filter is documented in wp-includes/class-oembed.php */ 190 $data->html = apply_filters( 'oembed_result', _wp_oembed_get_object()->data2html( (object) $data, $url ), $url, $args ); 191 182 192 /** 183 193 * Filters the oEmbed TTL value (time to live). 184 194 * -
src/wp-includes/embed.php
diff --git src/wp-includes/embed.php src/wp-includes/embed.php index 176988057b..efd991104a 100644
function get_oembed_response_data( $post, $width ) { 555 555 return apply_filters( 'oembed_response_data', $data, $post, $width, $height ); 556 556 } 557 557 558 559 /** 560 * Retrieves the oEmbed response data for a given URL. 561 * 562 * @since 5.0.0 563 * 564 * @param string $url The URL that should be inspected for discovery `<link>` tags. 565 * @param array $args oEmbed remote get arguments. 566 * @return object|false oEmbed response data if the URL does belong to the current site. False otherwise. 567 */ 568 function get_oembed_response_data_for_url( $url, $args ) { 569 $switched_blog = false; 570 571 if ( is_multisite() ) { 572 $url_parts = wp_parse_args( wp_parse_url( $url ), array( 573 'host' => '', 574 'path' => '/', 575 ) ); 576 577 $qv = array( 'domain' => $url_parts['host'], 'path' => '/' ); 578 579 // In case of subdirectory configs, set the path. 580 if ( ! is_subdomain_install() ) { 581 $path = explode( '/', ltrim( $url_parts['path'], '/' ) ); 582 $path = reset( $path ); 583 584 if ( $path ) { 585 $qv['path'] = get_network()->path . $path . '/'; 586 } 587 } 588 589 $sites = get_sites( $qv ); 590 $site = reset( $sites ); 591 592 if ( $site && (int) $site->blog_id !== get_current_blog_id() ) { 593 switch_to_blog( $site->blog_id ); 594 $switched_blog = true; 595 } 596 } 597 598 $post_id = url_to_postid( $url ); 599 600 /** This filter is documented in wp-includes/class-wp-oembed-controller.php */ 601 $post_id = apply_filters( 'oembed_request_post_id', $post_id, $url ); 602 603 if ( ! $post_id ) { 604 if ( $switched_blog ) { 605 restore_current_blog(); 606 } 607 608 return false; 609 } 610 611 $width = isset( $args['width'] ) ? $args['width'] : 0; 612 613 $data = get_oembed_response_data( $post_id, $width ); 614 615 if ( $switched_blog ) { 616 restore_current_blog(); 617 } 618 619 return $data ? (object) $data : false; 620 } 621 622 558 623 /** 559 624 * Filters the oEmbed response data to return an iframe embed code. 560 625 * … … function the_embed_site_title() { 1071 1136 * Null if the URL does not belong to the current site. 1072 1137 */ 1073 1138 function wp_filter_pre_oembed_result( $result, $url, $args ) { 1074 $switched_blog = false; 1075 1076 if ( is_multisite() ) { 1077 $url_parts = wp_parse_args( wp_parse_url( $url ), array( 1078 'host' => '', 1079 'path' => '/', 1080 ) ); 1081 1082 $qv = array( 'domain' => $url_parts['host'], 'path' => '/' ); 1083 1084 // In case of subdirectory configs, set the path. 1085 if ( ! is_subdomain_install() ) { 1086 $path = explode( '/', ltrim( $url_parts['path'], '/' ) ); 1087 $path = reset( $path ); 1088 1089 if ( $path ) { 1090 $qv['path'] = get_network()->path . $path . '/'; 1091 } 1092 } 1093 1094 $sites = get_sites( $qv ); 1095 $site = reset( $sites ); 1096 1097 if ( $site && (int) $site->blog_id !== get_current_blog_id() ) { 1098 switch_to_blog( $site->blog_id ); 1099 $switched_blog = true; 1100 } 1101 } 1102 1103 $post_id = url_to_postid( $url ); 1104 1105 /** This filter is documented in wp-includes/class-wp-oembed-controller.php */ 1106 $post_id = apply_filters( 'oembed_request_post_id', $post_id, $url ); 1107 1108 if ( ! $post_id ) { 1109 if ( $switched_blog ) { 1110 restore_current_blog(); 1111 } 1139 $data = get_oembed_response_data_for_url( $url, $args ); 1112 1140 1113 return $result; 1141 if ( $data ) { 1142 return _wp_oembed_get_object()->data2html( $data, $url ); 1114 1143 } 1115 1144 1116 $width = isset( $args['width'] ) ? $args['width'] : 0; 1117 1118 $data = get_oembed_response_data( $post_id, $width ); 1119 $data = _wp_oembed_get_object()->data2html( (object) $data, $url ); 1120 1121 if ( $switched_blog ) { 1122 restore_current_blog(); 1123 } 1124 1125 if ( ! $data ) { 1126 return $result; 1127 } 1128 1129 return $data; 1145 return $result; 1130 1146 } -
tests/phpunit/tests/oembed/controller.php
diff --git tests/phpunit/tests/oembed/controller.php tests/phpunit/tests/oembed/controller.php index 9f9aa6dd46..2d6afaf76c 100644
class Test_oEmbed_Controller extends WP_UnitTestCase { 14 14 protected static $subscriber; 15 15 const YOUTUBE_VIDEO_ID = 'OQSNhk5ICTI'; 16 16 const INVALID_OEMBED_URL = 'https://www.notreallyanoembedprovider.com/watch?v=awesome-cat-video'; 17 const UNTRUSTED_PROVIDER_URL = 'https://www.untrustedprovider.com'; 17 18 18 19 public static function wpSetUpBeforeClass( $factory ) { 19 20 self::$subscriber = $factory->user->create( array( … … class Test_oEmbed_Controller extends WP_UnitTestCase { 71 72 unset( $preempt, $r ); 72 73 73 74 $parsed_url = wp_parse_url( $url ); 74 parse_str( $parsed_url['query'], $query_params ); 75 $query = isset( $parsed_url['query'] ) ? $parsed_url['query'] : ''; 76 parse_str( $query, $query_params ); 75 77 $this->request_count += 1; 76 78 77 79 // Mock request to YouTube Embed. … … class Test_oEmbed_Controller extends WP_UnitTestCase { 80 82 'response' => array( 81 83 'code' => 200, 82 84 ), 83 'body' => wp_json_encode(85 'body' => wp_json_encode( 84 86 array( 85 87 'version' => '1.0', 86 88 'type' => 'video', … … class Test_oEmbed_Controller extends WP_UnitTestCase { 90 92 'width' => $query_params['maxwidth'], 91 93 'thumbnail_height' => $query_params['maxheight'], 92 94 'height' => $query_params['maxheight'], 93 'html' => '< iframe width="' . $query_params['maxwidth'] . '" height="' . $query_params['maxheight'] . '" src="https://www.youtube.com/embed/' . self::YOUTUBE_VIDEO_ID . '?feature=oembed" frameborder="0" allowfullscreen></iframe>',95 'html' => '<b>Unfiltered</b><iframe width="' . $query_params['maxwidth'] . '" height="' . $query_params['maxheight'] . '" src="https://www.youtube.com/embed/' . self::YOUTUBE_VIDEO_ID . '?feature=oembed" frameborder="0" allowfullscreen></iframe>', 94 96 'author_name' => 'Yosemitebear62', 95 97 'thumbnail_url' => 'https://i.ytimg.com/vi/' . self::YOUTUBE_VIDEO_ID . '/hqdefault.jpg', 96 98 'title' => 'Yosemitebear Mountain Double Rainbow 1-8-10', 97 99 ) 98 100 ), 99 101 ); 100 } else { 102 } 103 104 if ( $url === self::UNTRUSTED_PROVIDER_URL ) { 101 105 return array( 102 106 'response' => array( 103 'code' => 404,107 'code' => 200, 104 108 ), 109 'body' => '<html><head><link rel="alternate" type="application/json+oembed" href="' . self::UNTRUSTED_PROVIDER_URL . '" /></head><body></body></html>', 105 110 ); 106 111 } 112 113 if ( ! empty( $query_params['url'] ) && false !== strpos( $query_params['url'], self::UNTRUSTED_PROVIDER_URL ) ) { 114 return array( 115 'response' => array( 116 'code' => 200, 117 ), 118 'body' => wp_json_encode( 119 array( 120 'version' => '1.0', 121 'type' => 'rich', 122 'provider_name' => 'Untrusted', 123 'provider_url' => self::UNTRUSTED_PROVIDER_URL, 124 'html' => '<b>Filtered</b><a href="">Unfiltered</a>', 125 'author_name' => 'Untrusted Embed Author', 126 'title' => 'Untrusted Embed', 127 ) 128 ), 129 ); 130 } 131 132 return array( 133 'response' => array( 134 'code' => 404, 135 ), 136 ); 107 137 } 108 138 109 139 function test_wp_oembed_ensure_format() { … … class Test_oEmbed_Controller extends WP_UnitTestCase { 510 540 $data = $response->get_data(); 511 541 512 542 $this->assertNotEmpty( $data ); 513 $this->assert True( is_object( $data ));543 $this->assertInternalType( 'object', $data ); 514 544 $this->assertEquals( 'YouTube', $data->provider_name ); 515 545 $this->assertEquals( 'https://i.ytimg.com/vi/' . self::YOUTUBE_VIDEO_ID . '/hqdefault.jpg', $data->thumbnail_url ); 516 546 $this->assertEquals( $data->width, $request['maxwidth'] ); … … class Test_oEmbed_Controller extends WP_UnitTestCase { 552 582 $data = $response->get_data(); 553 583 $this->assertEquals( $data['code'], 'rest_invalid_param' ); 554 584 } 585 586 /** 587 * @ticket 45142 588 */ 589 function test_proxy_with_internal_url() { 590 wp_set_current_user( self::$editor ); 591 592 $user = self::factory()->user->create_and_get( array( 593 'display_name' => 'John Doe', 594 ) ); 595 $post = self::factory()->post->create_and_get( array( 596 'post_author' => $user->ID, 597 'post_title' => 'Hello World', 598 ) ); 599 600 $request = new WP_REST_Request( 'GET', '/oembed/1.0/proxy' ); 601 $request->set_param( 'url', get_permalink( $post->ID ) ); 602 $request->set_param( 'maxwidth', 400 ); 603 604 $response = $this->server->dispatch( $request ); 605 $data = $response->get_data(); 606 607 $data = (array) $data; 608 609 $this->assertNotEmpty( $data ); 610 611 $this->assertArrayHasKey( 'version', $data ); 612 $this->assertArrayHasKey( 'provider_name', $data ); 613 $this->assertArrayHasKey( 'provider_url', $data ); 614 $this->assertArrayHasKey( 'author_name', $data ); 615 $this->assertArrayHasKey( 'author_url', $data ); 616 $this->assertArrayHasKey( 'title', $data ); 617 $this->assertArrayHasKey( 'type', $data ); 618 $this->assertArrayHasKey( 'width', $data ); 619 620 $this->assertEquals( '1.0', $data['version'] ); 621 $this->assertEquals( get_bloginfo( 'name' ), $data['provider_name'] ); 622 $this->assertEquals( get_home_url(), $data['provider_url'] ); 623 $this->assertEquals( $user->display_name, $data['author_name'] ); 624 $this->assertEquals( get_author_posts_url( $user->ID, $user->user_nicename ), $data['author_url'] ); 625 $this->assertEquals( $post->post_title, $data['title'] ); 626 $this->assertEquals( 'rich', $data['type'] ); 627 $this->assertTrue( $data['width'] <= $request['maxwidth'] ); 628 } 629 630 /** 631 * @ticket 45142 632 */ 633 function test_proxy_with_static_front_page_url() { 634 wp_set_current_user( self::$editor ); 635 636 $post = self::factory()->post->create_and_get( array( 637 'post_title' => 'Front page', 638 'post_type' => 'page', 639 'post_author' => 0, 640 ) ); 641 642 update_option( 'show_on_front', 'page' ); 643 update_option( 'page_on_front', $post->ID ); 644 645 $request = new WP_REST_Request( 'GET', '/oembed/1.0/proxy' ); 646 $request->set_param( 'url', home_url() ); 647 $request->set_param( 'maxwidth', 400 ); 648 649 $response = $this->server->dispatch( $request ); 650 $data = $response->get_data(); 651 652 $this->assertInternalType( 'object', $data ); 653 654 $data = (array) $data; 655 656 $this->assertNotEmpty( $data ); 657 658 $this->assertArrayHasKey( 'version', $data ); 659 $this->assertArrayHasKey( 'provider_name', $data ); 660 $this->assertArrayHasKey( 'provider_url', $data ); 661 $this->assertArrayHasKey( 'author_name', $data ); 662 $this->assertArrayHasKey( 'author_url', $data ); 663 $this->assertArrayHasKey( 'title', $data ); 664 $this->assertArrayHasKey( 'type', $data ); 665 $this->assertArrayHasKey( 'width', $data ); 666 667 $this->assertEquals( '1.0', $data['version'] ); 668 $this->assertEquals( get_bloginfo( 'name' ), $data['provider_name'] ); 669 $this->assertEquals( get_home_url(), $data['provider_url'] ); 670 $this->assertEquals( get_bloginfo( 'name' ), $data['author_name'] ); 671 $this->assertEquals( get_home_url(), $data['author_url'] ); 672 $this->assertEquals( $post->post_title, $data['title'] ); 673 $this->assertEquals( 'rich', $data['type'] ); 674 $this->assertTrue( $data['width'] <= $request['maxwidth'] ); 675 676 update_option( 'show_on_front', 'posts' ); 677 } 678 679 /** 680 * @ticket 45142 681 */ 682 public function test_proxy_filters_result_of_untrusted_oembed_provider() { 683 wp_set_current_user( self::$editor ); 684 685 $request = new WP_REST_Request( 'GET', '/oembed/1.0/proxy' ); 686 $request->set_param( 'url', self::UNTRUSTED_PROVIDER_URL ); 687 $request->set_param( 'maxwidth', 456 ); 688 $request->set_param( 'maxheight', 789 ); 689 $request->set_param( '_wpnonce', wp_create_nonce( 'wp_rest' ) ); 690 691 $response = $this->server->dispatch( $request ); 692 $data = $response->get_data(); 693 694 $this->assertInternalType( 'object', $data ); 695 696 $this->markTestIncomplete( 'Need to test that the resulting HTML is passed through the oembed_dataparse filter' ); 697 } 698 699 /** 700 * @ticket 45142 701 */ 702 public function test_proxy_does_not_filter_result_of_trusted_oembed_provider() { 703 wp_set_current_user( self::$editor ); 704 705 $request = new WP_REST_Request( 'GET', '/oembed/1.0/proxy' ); 706 $request->set_param( 'url', 'https://www.youtube.com/watch?v=' . self::YOUTUBE_VIDEO_ID ); 707 $request->set_param( 'maxwidth', 456 ); 708 $request->set_param( 'maxheight', 789 ); 709 $request->set_param( '_wpnonce', wp_create_nonce( 'wp_rest' ) ); 710 711 $response = $this->server->dispatch( $request ); 712 $data = $response->get_data(); 713 714 $this->assertInternalType( 'object', $data ); 715 716 $this->assertStringStartsWith( '<b>Unfiltered</b>', $data->html ); 717 } 555 718 }