Ticket #36356: 36356-wp_parse_url-revisited.patch
File 36356-wp_parse_url-revisited.patch, 8.3 KB (added by , 8 years ago) |
---|
-
src/wp-includes/http.php
From 12e06a10ac46b7216bfbac41bc0015ff7bf49380 Mon Sep 17 00:00:00 2001 From: jrfnl <github_nospam@adviesenzo.nl> Date: Fri, 30 Sep 2016 22:59:58 +0200 Subject: [PATCH] Add the $component parameter to the wp_parse_url() function. --- src/wp-includes/http.php | 73 +++++++++++++++++++++++++++---------- tests/phpunit/tests/http/http.php | 77 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 129 insertions(+), 21 deletions(-) diff --git a/src/wp-includes/http.php b/src/wp-includes/http.php index 130eae3..3738b79 100644
a b function ms_allowed_http_request_hosts( $is_external, $host ) { 633 633 * when URL parsing failed. 634 634 * 635 635 * @since 4.4.0 636 * 637 * @param string $url The URL to parse. 638 * @return bool|array False on failure; Array of URL components on success; 639 * See parse_url()'s return values. 636 * @since 4.7.0 The $component parameter was added for parity with PHP's parse_url(). 637 * 638 * @param string $url The URL to parse. 639 * @param int $component The specific component to retrieve. Use one of the PHP 640 * predefined constants to specify which one. 641 * Defaults to -1 (= return all parts as an array). 642 * @see http://php.net/manual/en/function.parse-url.php 643 * @return mixed False on failure; Array of URL components on success; 644 * When a specific component has been requested: null if the component doesn't 645 * exist in the given URL; a sting or - in the case of PHP_URL_PORT - integer 646 * when it does; See parse_url()'s return values. 640 647 */ 641 function wp_parse_url( $url ) { 642 $parts = @parse_url( $url ); 643 if ( ! $parts ) { 644 // < PHP 5.4.7 compat, trouble with relative paths including a scheme break in the path 648 function wp_parse_url( $url, $component = -1 ) { 649 $parts = @parse_url( $url, $component ); 650 651 if ( version_compare( PHP_VERSION, '5.4.7', '>=' ) ) { 652 return $parts; 653 } 654 655 if ( false === $parts ) { 656 // < PHP 5.4.7 compat, trouble with relative paths including a scheme break in the path. 645 657 if ( '/' == $url[0] && false !== strpos( $url, '://' ) ) { 646 // Since we know it's a relative path, prefix with a scheme/host placeholder and try again 647 if ( ! $parts = @parse_url( 'placeholder://placeholder' . $url ) ) { 658 if ( in_array( $component, array( PHP_URL_SCHEME, PHP_URL_HOST ), true ) ) { 659 return null; 660 } 661 // Since we know it's a relative path, prefix with a scheme/host placeholder and try again. 662 if ( ! $parts = @parse_url( 'placeholder://placeholder' . $url, $component ) ) { 648 663 return $parts; 649 664 } 650 // Remove the placeholder values 651 unset( $parts['scheme'], $parts['host'] ); 665 // Remove the placeholder values. 666 if ( -1 === $component ) { 667 unset( $parts['scheme'], $parts['host'] ); 668 } 652 669 } else { 653 670 return $parts; 654 671 } 655 672 } 656 673 657 // < PHP 5.4.7 compat, doesn't detect schemeless URL's host field 658 if ( '//' == substr( $url, 0, 2 ) && ! isset( $parts['host'] ) ) { 659 $path_parts = explode( '/', substr( $parts['path'], 2 ), 2 ); 660 $parts['host'] = $path_parts[0]; 661 if ( isset( $path_parts[1] ) ) { 662 $parts['path'] = '/' . $path_parts[1]; 663 } else { 664 unset( $parts['path'] ); 674 // < PHP 5.4.7 compat, doesn't detect a schemeless URL's host field. 675 if ( '//' == substr( $url, 0, 2 ) ) { 676 if ( -1 === $component && ! isset( $parts['host'] ) ) { 677 $path_parts = explode( '/', substr( $parts['path'], 2 ), 2 ); 678 $parts['host'] = $path_parts[0]; 679 if ( isset( $path_parts[1] ) ) { 680 $parts['path'] = '/' . $path_parts[1]; 681 } else { 682 unset( $parts['path'] ); 683 } 684 } elseif ( PHP_URL_HOST === $component || PHP_URL_PATH === $component ) { 685 $all_parts = @parse_url( $url ); 686 if ( ! isset( $all_parts['host'] ) ) { 687 $path_parts = explode( '/', substr( $all_parts['path'], 2 ), 2 ); 688 if ( PHP_URL_PATH === $component ) { 689 if ( isset( $path_parts[1] ) ) { 690 $parts = '/' . $path_parts[1]; 691 } else { 692 $parts = null; 693 } 694 } elseif ( PHP_URL_HOST === $component ) { 695 $parts = $path_parts[0]; 696 } 697 } 665 698 } 666 699 } 667 700 -
tests/phpunit/tests/http/http.php
diff --git a/tests/phpunit/tests/http/http.php b/tests/phpunit/tests/http/http.php index ed0b9ee..607eb47 100644
a b 6 6 */ 7 7 class Tests_HTTP_HTTP extends WP_UnitTestCase { 8 8 9 const FULL_TEST_URL = 'http://username:password@host.name:9090/path?arg1=value1&arg2=value2#anchor'; 10 9 11 /** 10 12 * @dataProvider make_absolute_url_testcases 11 13 */ … … class Tests_HTTP_HTTP extends WP_UnitTestCase { 78 80 function parse_url_testcases() { 79 81 // 0: The URL, 1: The expected resulting structure 80 82 return array( 83 array( self::FULL_TEST_URL, array( 84 'scheme' => 'http', 85 'host' => 'host.name', 86 'port' => 9090, 87 'user' => 'username', 88 'pass' => 'password', 89 'path' => '/path', 90 'query' => 'arg1=value1&arg2=value2', 91 'fragment' => 'anchor', 92 ) ), 81 93 array( 'http://example.com/', array( 'scheme' => 'http', 'host' => 'example.com', 'path' => '/' ) ), 82 94 83 95 // < PHP 5.4.7: Schemeless URL … … class Tests_HTTP_HTTP extends WP_UnitTestCase { 85 97 array( '//example.com/', array( 'host' => 'example.com', 'path' => '/' ) ), 86 98 array( 'http://example.com//path/', array( 'scheme' => 'http', 'host' => 'example.com', 'path' => '//path/' ) ), 87 99 88 // < PHP 5.4.7: Scheme sep erator in the URL100 // < PHP 5.4.7: Scheme separator in the URL. 89 101 array( 'http://example.com/http://example.net/', array( 'scheme' => 'http', 'host' => 'example.com', 'path' => '/http://example.net/' ) ), 90 102 array( '/path/http://example.net/', array( 'path' => '/path/http://example.net/' ) ), 91 103 … … class Tests_HTTP_HTTP extends WP_UnitTestCase { 104 116 } 105 117 106 118 /** 119 * @ticket 36356 120 */ 121 function test_wp_parse_url_with_default_component() { 122 $actual = wp_parse_url( self::FULL_TEST_URL, -1 ); 123 $this->assertEquals( array( 124 'scheme' => 'http', 125 'host' => 'host.name', 126 'port' => 9090, 127 'user' => 'username', 128 'pass' => 'password', 129 'path' => '/path', 130 'query' => 'arg1=value1&arg2=value2', 131 'fragment' => 'anchor', 132 ), $actual ); 133 } 134 135 /** 136 * @ticket 36356 137 * 138 * @dataProvider parse_url_component_testcases 139 */ 140 function test_wp_parse_url_with_component( $url, $component, $expected ) { 141 $actual = wp_parse_url( $url, $component ); 142 $this->assertSame( $expected, $actual ); 143 } 144 145 function parse_url_component_testcases() { 146 // 0: The URL, 1: The requested component, 2: The expected resulting structure. 147 return array( 148 array( self::FULL_TEST_URL, PHP_URL_SCHEME, 'http' ), 149 array( self::FULL_TEST_URL, PHP_URL_USER, 'username' ), 150 array( self::FULL_TEST_URL, PHP_URL_PASS, 'password' ), 151 array( self::FULL_TEST_URL, PHP_URL_HOST, 'host.name' ), 152 array( self::FULL_TEST_URL, PHP_URL_PORT, 9090 ), 153 array( self::FULL_TEST_URL, PHP_URL_PATH, '/path' ), 154 array( self::FULL_TEST_URL, PHP_URL_QUERY, 'arg1=value1&arg2=value2' ), 155 array( self::FULL_TEST_URL, PHP_URL_FRAGMENT, 'anchor' ), 156 157 // < PHP 5.4.7: Schemeless URL. 158 array( '//example.com/path/', PHP_URL_HOST, 'example.com' ), 159 array( '//example.com/path/', PHP_URL_PATH, '/path/' ), 160 array( '//example.com/', PHP_URL_HOST, 'example.com' ), 161 array( '//example.com/', PHP_URL_PATH, '/' ), 162 array( 'http://example.com//path/', PHP_URL_HOST, 'example.com' ), 163 array( 'http://example.com//path/', PHP_URL_PATH, '//path/' ), 164 165 // < PHP 5.4.7: Scheme separator in the URL. 166 array( 'http://example.com/http://example.net/', PHP_URL_HOST, 'example.com' ), 167 array( 'http://example.com/http://example.net/', PHP_URL_PATH, '/http://example.net/' ), 168 array( '/path/http://example.net/', PHP_URL_HOST, null ), 169 array( '/path/http://example.net/', PHP_URL_PATH, '/path/http://example.net/' ), 170 171 // < PHP 5.4.7: IPv6 literals in schemeless URLs are handled incorrectly. 172 array( '//[::FFFF::127.0.0.1]/', PHP_URL_HOST, '[::FFFF::127.0.0.1]' ), 173 array( '//[::FFFF::127.0.0.1]/', PHP_URL_PATH, '/' ), 174 175 // PHP's parse_url() calls this an invalid URL, we handle it as a path. 176 array( '/://example.com/', PHP_URL_PATH, '/://example.com/' ), 177 178 ); 179 } 180 181 /** 107 182 * @ticket 35426 108 183 */ 109 184 public function test_http_response_code_constants() {