Make WordPress Core

Ticket #16859: 16859.diff

File 16859.diff, 7.3 KB (added by johnbillion, 10 years ago)
  • src/wp-includes/formatting.php

     
    20772077        $ret = '';
    20782078        $dest = $matches[2];
    20792079        $dest = 'http://' . $dest;
    2080         $dest = esc_url($dest);
    2081         if ( empty($dest) )
    2082                 return $matches[0];
    20832080
    20842081        // removed trailing [.,;:)] from URL
    20852082        if ( in_array( substr($dest, -1), array('.', ',', ';', ':', ')') ) === true ) {
    20862083                $ret = substr($dest, -1);
    20872084                $dest = substr($dest, 0, strlen($dest)-1);
    20882085        }
     2086
     2087        $dest = esc_url($dest);
     2088        if ( empty($dest) )
     2089                return $matches[0];
     2090
    20892091        return $matches[1] . "<a href=\"$dest\" rel=\"nofollow\">$dest</a>$ret";
    20902092}
    20912093
     
    32783280 * (the default behaviour) ampersands are also replaced. The 'clean_url' filter
    32793281 * is applied to the returned cleaned URL.
    32803282 *
     3283 * See RFC3986
     3284 *
    32813285 * @since 2.8.0
    32823286 *
    32833287 * @param string $url       The URL to be cleaned.
     
    32933297                return $url;
    32943298
    32953299        $url = str_replace( ' ', '%20', $url );
    3296         $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);
     3300        $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url);
    32973301
    32983302        if ( '' === $url ) {
    32993303                return $url;
     
    33063310
    33073311        $url = str_replace(';//', '://', $url);
    33083312        /* If the URL doesn't appear to contain a scheme, we
    3309          * presume it needs http:// appended (unless a relative
     3313         * presume it needs http:// prepended (unless a relative
    33103314         * link starting with /, # or ? or a php file).
    33113315         */
    33123316        if ( strpos($url, ':') === false && ! in_array( $url[0], array( '/', '#', '?' ) ) &&
     
    33203324                $url = str_replace( "'", '&#039;', $url );
    33213325        }
    33223326
     3327        if ( ( false !== strpos( $url, '[' ) ) || ( false !== strpos( $url, ']' ) ) ) {
     3328
     3329                $parsed = parse_url( $url );
     3330                $front  = '';
     3331
     3332                if ( isset( $parsed['scheme'] ) ) {
     3333                        $front .= $parsed['scheme'] . '://';
     3334                } elseif ( '/' === $url[0] ) {
     3335                        $front .= '//';
     3336                }
     3337
     3338                if ( isset( $parsed['user'] ) ) {
     3339                        $front .= $parsed['user'];
     3340                }
     3341
     3342                if ( isset( $parsed['pass'] ) ) {
     3343                        $front .= ':' . $parsed['pass'];
     3344                }
     3345
     3346                if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) {
     3347                        $front .= '@';
     3348                }
     3349
     3350                if ( isset( $parsed['host'] ) ) {
     3351                        $front .= $parsed['host'];
     3352                }
     3353
     3354                if ( isset( $parsed['port'] ) ) {
     3355                        $front .= ':' . $parsed['port'];
     3356                }
     3357
     3358                $end_dirty = str_replace( $front, '', $url );
     3359                $end_clean = str_replace( array( '[', ']' ), array( '%5B', '%5D' ), $end_dirty );
     3360                $url       = str_replace( $end_dirty, $end_clean, $url );
     3361
     3362        }
     3363
    33233364        if ( '/' === $url[0] ) {
    33243365                $good_protocol_url = $url;
    33253366        } else {
  • tests/phpunit/tests/formatting/EscUrl.php

     
    4040        }
    4141
    4242        function test_all_url_parts() {
    43                 $url = 'https://user:password@host.example.com:1234/path;p=1?q=2&r=3#fragment';
    44                 $this->assertEquals( $url, esc_url_raw( $url ) );
    45 
    46                 $this->assertEquals( 'https://user:password@host.example.com:1234/path;p=1?q=2&#038;r=3#fragment', esc_url( $url ) );
     43                $url = 'https://user:pass@host.example.com:1234/path;p=1?query=2&r[]=3#fragment';
    4744
    48                 $this->assertEquals( 'http://example.com?foo', esc_url( 'http://example.com?foo' ) );
     45                $this->assertEquals( array(
     46                        'scheme'   => 'https',
     47                        'host'     => 'host.example.com',
     48                        'port'     => 1234,
     49                        'user'     => 'user',
     50                        'pass'     => 'pass',
     51                        'path'     => '/path;p=1',
     52                        'query'    => 'query=2&r[]=3',
     53                        'fragment' => 'fragment',
     54                ), parse_url( $url ) );
     55                $this->assertEquals( 'https://user:pass@host.example.com:1234/path;p=1?query=2&r%5B%5D=3#fragment', esc_url_raw( $url ) );
     56                $this->assertEquals( 'https://user:pass@host.example.com:1234/path;p=1?query=2&#038;r%5B%5D=3#fragment', esc_url( $url ) );
     57        }
     58
     59        function test_all_url_parts_ipv6() {
     60                $url = 'https://user:pass@[::FFFF::127.0.0.1]:1234/path;p=1?query=2&r[]=3#fragment';
     61
     62                $this->assertEquals( array(
     63                        'scheme'   => 'https',
     64                        'host'     => '[::FFFF::127.0.0.1]',
     65                        'port'     => 1234,
     66                        'user'     => 'user',
     67                        'pass'     => 'pass',
     68                        'path'     => '/path;p=1',
     69                        'query'    => 'query=2&r[]=3',
     70                        'fragment' => 'fragment',
     71                ), parse_url( $url ) );
     72                $this->assertEquals( 'https://user:pass@[::FFFF::127.0.0.1]:1234/path;p=1?query=2&r%5B%5D=3#fragment', esc_url_raw( $url ) );
     73                $this->assertEquals( 'https://user:pass@[::FFFF::127.0.0.1]:1234/path;p=1?query=2&#038;r%5B%5D=3#fragment', esc_url( $url ) );
    4974        }
    5075
    5176        function test_bare() {
     77                $this->assertEquals( 'http://example.com?foo', esc_url( 'example.com?foo' ) );
    5278                $this->assertEquals( 'http://example.com', esc_url( 'example.com' ) );
    5379                $this->assertEquals( 'http://localhost', esc_url( 'localhost' ) );
    5480                $this->assertEquals( 'http://example.com/foo', esc_url( 'example.com/foo' ) );
     
    126152        }
    127153
    128154        /**
     155         * @ticket 16859
     156         */
     157        function test_square_brackets() {
     158                $this->assertEquals( '/example.php?one%5B%5D=two', esc_url( '/example.php?one[]=two' ) );
     159                $this->assertEquals( '?foo%5Bbar%5D=baz', esc_url( '?foo[bar]=baz' ) );
     160                $this->assertEquals( '//example.com/?foo%5Bbar%5D=baz', esc_url( '//example.com/?foo[bar]=baz' ) );
     161                $this->assertEquals( 'http://example.com/?foo%5Bbar%5D=baz', esc_url( 'example.com/?foo[bar]=baz' ) );
     162                $this->assertEquals( 'http://localhost?foo%5Bbar%5D=baz', esc_url( 'localhost?foo[bar]=baz' ) );
     163                $this->assertEquals( 'http://example.com/?foo%5Bbar%5D=baz', esc_url( 'http://example.com/?foo[bar]=baz' ) );
     164                $this->assertEquals( 'http://example.com/?foo%5Bbar%5D=baz', esc_url( 'http://example.com/?foo%5Bbar%5D=baz' ) );
     165                $this->assertEquals( 'http://example.com/?baz=bar&#038;foo%5Bbar%5D=baz', esc_url( 'http://example.com/?baz=bar&foo[bar]=baz' ) );
     166                $this->assertEquals( 'http://example.com/?baz=bar&#038;foo%5Bbar%5D=baz', esc_url( 'http://example.com/?baz=bar&#038;foo%5Bbar%5D=baz' ) );
     167        }
     168
     169        /**
     170         * @ticket 16859
     171         */
     172        function test_ipv6_hosts() {
     173                $this->assertEquals( '//[::127.0.0.1]', esc_url( '//[::127.0.0.1]' ) );
     174                $this->assertEquals( 'http://[::FFFF::127.0.0.1]', esc_url( 'http://[::FFFF::127.0.0.1]' ) );
     175                $this->assertEquals( 'http://[::127.0.0.1]', esc_url( 'http://[::127.0.0.1]' ) );
     176                $this->assertEquals( 'http://[::DEAD:BEEF:DEAD:BEEF:DEAD:BEEF:DEAD:BEEF]', esc_url( 'http://[::DEAD:BEEF:DEAD:BEEF:DEAD:BEEF:DEAD:BEEF]' ) );
     177
     178                // IPv6 with square brackets in the query? Why not.
     179                $this->assertEquals( '//[::FFFF::127.0.0.1]/?foo%5Bbar%5D=baz', esc_url( '//[::FFFF::127.0.0.1]/?foo[bar]=baz' ) );
     180                $this->assertEquals( 'http://[::FFFF::127.0.0.1]/?foo%5Bbar%5D=baz', esc_url( 'http://[::FFFF::127.0.0.1]/?foo[bar]=baz' ) );
     181        }
     182
     183        /**
     184         * Courtesy of http://blog.lunatech.com/2009/02/03/what-every-web-developer-must-know-about-url-encoding
     185         */
     186        function test_reserved_characters() {
     187                $url = "http://example.com/:@-._~!$&'()*+,=;:@-._~!$&'()*+,=:@-._~!$&'()*+,==?/?:@-._~!$%27()*+,;=/?:@-._~!$%27()*+,;==#/?:@-._~!$&'()*+,;=";
     188                $this->assertEquals( $url, esc_url_raw( $url ) );
     189        }
     190
     191        /**
    129192         * @ticket 21974
    130193         */
    131194        function test_protocol_relative_with_colon() {
     
    175238         * @ticket 28015
    176239         */
    177240        function test_invalid_charaters() {
    178                 $this->assertEmpty( esc_url_raw('"^[]<>{}`') );
     241                $this->assertEmpty( esc_url_raw('"^<>{}`') );
    179242        }
    180243
    181244}