Also set the queue types map when rebuilding the ready queue map
[lhc/web/wiklou.git] / includes / GlobalFunctions.php
index ed99aa9..c95c380 100644 (file)
@@ -104,6 +104,53 @@ if ( !function_exists( 'gzdecode' ) ) {
                return gzinflate( substr( $data, 10, -8 ) );
        }
 }
+
+// hash_equals function only exists in PHP >= 5.6.0
+if ( !function_exists( 'hash_equals' ) ) {
+       /**
+        * Check whether a user-provided string is equal to a fixed-length secret without
+        * revealing bytes of the secret through timing differences.
+        *
+        * This timing guarantee -- that a partial match takes the same time as a complete
+        * mismatch -- is why this function is used in some security-sensitive parts of the code.
+        * For example, it shouldn't be possible to guess an HMAC signature one byte at a time.
+        *
+        * Longer explanation: http://www.emerose.com/timing-attacks-explained
+        *
+        * @codeCoverageIgnore
+        * @param string $known_string Fixed-length secret to compare against
+        * @param string $user_string User-provided string
+        * @return bool True if the strings are the same, false otherwise
+        */
+       function hash_equals( $known_string, $user_string ) {
+               // Strict type checking as in PHP's native implementation
+               if ( !is_string( $known_string ) ) {
+                       trigger_error( 'hash_equals(): Expected known_string to be a string, ' .
+                               gettype( $known_string ) . ' given', E_USER_WARNING );
+
+                       return false;
+               }
+
+               if ( !is_string( $user_string ) ) {
+                       trigger_error( 'hash_equals(): Expected user_string to be a string, ' .
+                               gettype( $user_string ) . ' given', E_USER_WARNING );
+
+                       return false;
+               }
+
+               // Note that we do one thing PHP doesn't: try to avoid leaking information about
+               // relative lengths of $known_string and $user_string, and of multiple $known_strings.
+               // However, lengths may still inevitably leak through, for example, CPU cache misses.
+               $known_string_len = strlen( $known_string );
+               $user_string_len = strlen( $user_string );
+               $result = $known_string_len ^ $user_string_len;
+               for ( $i = 0; $i < $user_string_len; $i++ ) {
+                       $result |= ord( $known_string[$i % $known_string_len] ) ^ ord( $user_string[$i] );
+               }
+
+               return ( $result === 0 );
+       }
+}
 /// @endcond
 
 /**
@@ -497,7 +544,8 @@ function wfAppendQuery( $url, $query ) {
  *    no valid URL can be constructed
  */
 function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) {
-       global $wgServer, $wgCanonicalServer, $wgInternalServer, $wgRequest;
+       global $wgServer, $wgCanonicalServer, $wgInternalServer, $wgRequest,
+               $wgHttpsPort;
        if ( $defaultProto === PROTO_CANONICAL ) {
                $serverUrl = $wgCanonicalServer;
        } elseif ( $defaultProto === PROTO_INTERNAL && $wgInternalServer !== false ) {
@@ -536,6 +584,13 @@ function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) {
        }
 
        $bits = wfParseUrl( $url );
+
+       // ensure proper port for HTTPS arrives in URL
+       // https://bugzilla.wikimedia.org/show_bug.cgi?id=65184
+       if ( $defaultProto === PROTO_HTTPS && $wgHttpsPort != 443 ) {
+               $bits['port'] = $wgHttpsPort;
+       }
+
        if ( $bits && isset( $bits['path'] ) ) {
                $bits['path'] = wfRemoveDotSegments( $bits['path'] );
                return wfAssembleUrl( $bits );
@@ -1007,14 +1062,14 @@ function wfDebugTimer() {
 /**
  * Send a line giving PHP memory usage.
  *
- * @param bool $exact Print exact values instead of kilobytes (default: false)
+ * @param bool $exact Print exact byte values instead of kibibytes (default: false)
  */
 function wfDebugMem( $exact = false ) {
        $mem = memory_get_usage();
        if ( !$exact ) {
-               $mem = floor( $mem / 1024 ) . ' kilobytes';
+               $mem = floor( $mem / 1024 ) . ' KiB';
        } else {
-               $mem .= ' bytes';
+               $mem .= ' B';
        }
        wfDebug( "Memory usage: $mem\n" );
 }
@@ -1726,10 +1781,7 @@ function wfMsgExt( $key, $options ) {
                }
 
                if ( $parseInline ) {
-                       $m = array();
-                       if ( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
-                               $string = $m[1];
-                       }
+                       $string = Parser::stripOuterParagraph( $string );
                }
        } elseif ( in_array( 'parsemag', $options, true ) ) {
                $string = $messageCache->transform( $string,
@@ -4151,39 +4203,23 @@ function wfGetIP() {
  * Checks if an IP is a trusted proxy provider.
  * Useful to tell if X-Forwarded-For data is possibly bogus.
  * Squid cache servers for the site are whitelisted.
+ * @deprecated Since 1.24, use IP::isTrustedProxy()
  *
  * @param string $ip
  * @return bool
  */
 function wfIsTrustedProxy( $ip ) {
-       $trusted = wfIsConfiguredProxy( $ip );
-       wfRunHooks( 'IsTrustedProxy', array( &$ip, &$trusted ) );
-       return $trusted;
+       return IP::isTrustedProxy( $ip );
 }
 
 /**
  * Checks if an IP matches a proxy we've configured.
+ * @deprecated Since 1.24, use IP::isConfiguredProxy()
  *
  * @param string $ip
  * @return bool
  * @since 1.23 Supports CIDR ranges in $wgSquidServersNoPurge
  */
 function wfIsConfiguredProxy( $ip ) {
-       global $wgSquidServers, $wgSquidServersNoPurge;
-
-       // quick check of known proxy servers
-       $trusted = in_array( $ip, $wgSquidServers )
-               || in_array( $ip, $wgSquidServersNoPurge );
-
-       if ( !$trusted ) {
-               // slightly slower check to see if the ip is listed directly or in a CIDR
-               // block in $wgSquidServersNoPurge
-               foreach ( $wgSquidServersNoPurge as $block ) {
-                       if ( strpos( $block, '/' ) !== false && IP::isInRange( $ip, $block ) ) {
-                               $trusted = true;
-                               break;
-                       }
-               }
-       }
-       return $trusted;
+       return IP::isTrustedProxy( $ip );
 }