Merge "Do not encode '~' as %7E. Fixes redirect loop in chrome."
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 9 Jul 2015 11:06:22 +0000 (11:06 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 9 Jul 2015 11:06:22 +0000 (11:06 +0000)
includes/GlobalFunctions.php
resources/src/mediawiki/mediawiki.util.js
tests/parser/parserTests.txt
tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php
tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js

index 97042fd..00d3d3a 100644 (file)
@@ -402,12 +402,17 @@ function wfRandomString( $length = 32 ) {
  *
  * ;:@&=$-_.+!*'(),
  *
+ * RFC 1738 says ~ is unsafe, however RFC 3986 considers it an unreserved
+ * character which should not be encoded. More importantly, google chrome
+ * always converts %7E back to ~, and converting it in this function can
+ * cause a redirect loop (T105265).
+ *
  * But + is not safe because it's used to indicate a space; &= are only safe in
  * paths and not in queries (and we don't distinguish here); ' seems kind of
  * scary; and urlencode() doesn't touch -_. to begin with.  Plus, although /
  * is reserved, we don't care.  So the list we unescape is:
  *
- * ;:@$!*(),/
+ * ;:@$!*(),/~
  *
  * However, IIS7 redirects fail when the url contains a colon (Bug 22709),
  * so no fancy : for IIS7.
@@ -426,7 +431,7 @@ function wfUrlencode( $s ) {
        }
 
        if ( is_null( $needle ) ) {
-               $needle = array( '%3B', '%40', '%24', '%21', '%2A', '%28', '%29', '%2C', '%2F' );
+               $needle = array( '%3B', '%40', '%24', '%21', '%2A', '%28', '%29', '%2C', '%2F', '%7E' );
                if ( !isset( $_SERVER['SERVER_SOFTWARE'] ) ||
                        ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/7' ) === false )
                ) {
@@ -437,7 +442,7 @@ function wfUrlencode( $s ) {
        $s = urlencode( $s );
        $s = str_ireplace(
                $needle,
-               array( ';', '@', '$', '!', '*', '(', ')', ',', '/', ':' ),
+               array( ';', '@', '$', '!', '*', '(', ')', ',', '/', '~', ':' ),
                $s
        );
 
index 13bf455..93a1b3b 100644 (file)
@@ -82,6 +82,7 @@
                                .replace( /%29/g, ')' )
                                .replace( /%2C/g, ',' )
                                .replace( /%2F/g, '/' )
+                               .replace( /%7E/g, '~' )
                                .replace( /%3A/g, ':' );
                },
 
index b3944fb..6700225 100644 (file)
@@ -7075,7 +7075,7 @@ Link containing a tilde
 !! wikitext
 [[Foo~bar]]
 !! html/php
-<p><a href="/wiki/Foo%7Ebar" title="Foo~bar">Foo~bar</a>
+<p><a href="/wiki/Foo~bar" title="Foo~bar">Foo~bar</a>
 </p>
 !! html/parsoid
 <p><a rel="mw:WikiLink" href="./Foo~bar" title="Foo~bar">Foo~bar</a></p>
index d11668b..d4df7b0 100644 (file)
@@ -112,6 +112,8 @@ class WfUrlencodeTest extends MediaWikiTestCase {
                        ### Other tests
                        // slash remain unchanged. %2F seems to break things
                        array( '/', '/' ),
+                       // T105265
+                       array( '~', '~' ),
 
                        // Other 'funnies' chars
                        array( '[]', '%5B%5D' ),
index 8a3e100..b73d2e3 100644 (file)
@@ -92,7 +92,7 @@
                assert.equal( mw.util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
        } );
 
-       QUnit.test( 'wikiUrlencode', 10, function ( assert ) {
+       QUnit.test( 'wikiUrlencode', 11, function ( assert ) {
                assert.equal( mw.util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
                // See also wfUrlencodeTest.php#provideURLS
                $.each( {
                        ':': ':',
                        ';@$-_.!*': ';@$-_.!*',
                        '/': '/',
+                       '~': '~',
                        '[]': '%5B%5D',
                        '<>': '%3C%3E',
                        '\'': '%27'