use Wikimedia\ScopedCallback;
use Wikimedia\Rdbms\DBReplicationWaitError;
-// Hide compatibility functions from Doxygen
-/// @cond
-/**
- * Compatibility functions
- *
- * We support PHP 5.5.9 and up.
- * Re-implementations of newer functions or functions in non-standard
- * PHP extensions may be included here.
- */
-
-// hash_equals function only exists in PHP >= 5.6.0
-// https://secure.php.net/hash_equals
-if ( !function_exists( 'hash_equals' ) ) {
- /**
- * Check whether a user-provided string is equal to a fixed-length secret string
- * without revealing bytes of the secret string through timing differences.
- *
- * The usual way to compare strings (PHP's === operator or the underlying memcmp()
- * function in C) is to compare corresponding bytes and stop at the first difference,
- * which would take longer for a partial match than for a complete mismatch. This
- * is not secure when one of the strings (e.g. an HMAC or token) must remain secret
- * and the other may come from an attacker. Statistical analysis of timing measurements
- * over many requests may allow the attacker to guess the string's bytes one at a time
- * (and check his guesses) even if the timing differences are extremely small.
- *
- * When making such a security-sensitive comparison, it is essential that the sequence
- * in which instructions are executed and memory locations are accessed not depend on
- * the secret string's value. HOWEVER, for simplicity, we do not attempt to minimize
- * the inevitable leakage of the string's length. That is generally known anyway as
- * a chararacteristic of the hash function used to compute the secret value.
- *
- * Longer explanation: http://www.emerose.com/timing-attacks-explained
- *
- * @codeCoverageIgnore
- * @param string $known_string Fixed-length secret string 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;
- }
-
- $known_string_len = strlen( $known_string );
- if ( $known_string_len !== strlen( $user_string ) ) {
- return false;
- }
-
- $result = 0;
- for ( $i = 0; $i < $known_string_len; $i++ ) {
- $result |= ord( $known_string[$i] ) ^ ord( $user_string[$i] );
- }
-
- return ( $result === 0 );
- }
-}
-/// @endcond
-
/**
* Load an extension
*
if ( is_string( $a ) && is_string( $b ) ) {
return strcmp( $a, $b );
} elseif ( count( $a ) !== count( $b ) ) {
- return count( $a ) < count( $b ) ? -1 : 1;
+ return count( $a ) <=> count( $b );
} else {
reset( $a );
reset( $b );
if ( $cache !== null ) {
return $cache;
}
- # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
+ // Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
+ // phpcs:ignore MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals
if ( ( isset( $_GET['action'] ) && $_GET['action'] == 'raw' )
|| (
isset( $_SERVER['SCRIPT_NAME'] )
* This function replaces all old wfMsg* functions.
*
* @param string|string[]|MessageSpecifier $key Message key, or array of keys, or a MessageSpecifier
- * @param mixed $params,... Normal message parameters
+ * @param string[]|string[][] ...$params Normal message parameters
* @return Message
*
* @since 1.17
*
* @see Message::__construct
*/
-function wfMessage( $key /*...*/ ) {
+function wfMessage( $key, ...$params ) {
$message = new Message( $key );
// We call Message::params() to reduce code duplication
- $params = func_get_args();
- array_shift( $params );
if ( $params ) {
- call_user_func_array( [ $message, 'params' ], $params );
+ $message->params( ...$params );
}
return $message;
* for the first message which is non-empty. If all messages are empty then an
* instance of the first message key is returned.
*
- * @param string|string[] $keys,... Message keys
+ * @param string[] ...$keys Message keys
* @return Message
*
* @since 1.18
*
* @see Message::newFallbackSequence
*/
-function wfMessageFallback( /*...*/ ) {
- $args = func_get_args();
- return call_user_func_array( 'Message::newFallbackSequence', $args );
+function wfMessageFallback( ...$keys ) {
+ return Message::newFallbackSequence( ...$keys );
}
/**
* hostname of the server handling the request.
*
* @param string $nonce Value from OutputPage::getCSPNonce
- * @return string
+ * @return string|WrappedString HTML
*/
function wfReportTime( $nonce = null ) {
global $wgShowHostnames;
$frames = array_map( function ( $frame ) use ( $frameFormat ) {
$file = !empty( $frame['file'] ) ? basename( $frame['file'] ) : '-';
- $line = isset( $frame['line'] ) ? $frame['line'] : '-';
+ $line = $frame['line'] ?? '-';
$call = $frame['function'];
if ( !empty( $frame['class'] ) ) {
$call = $frame['class'] . $frame['type'] . $call;
* @deprecated since 1.30 use MediaWiki\Shell::escape()
*/
function wfEscapeShellArg( /*...*/ ) {
- $args = func_get_args();
-
- return call_user_func_array( Shell::class . '::escape', $args );
+ return Shell::escape( ...func_get_args() );
}
/**
}
$includeStderr = isset( $options['duplicateStderr'] ) && $options['duplicateStderr'];
- $profileMethod = isset( $options['profileMethod'] ) ? $options['profileMethod'] : wfGetCaller();
+ $profileMethod = $options['profileMethod'] ?? wfGetCaller();
try {
$result = Shell::command( [] )
return false;
}
+/**
+ * @since 1.32
+ * @param string[] $data Array with string keys/values to export
+ * @param string $header
+ * @return string PHP code
+ */
+function wfMakeStaticArrayFile( array $data, $header = 'Automatically generated' ) {
+ $format = "\t%s => %s,\n";
+ $code = "<?php\n"
+ . "// " . implode( "\n// ", explode( "\n", $header ) ) . "\n"
+ . "return [\n";
+ foreach ( $data as $key => $value ) {
+ $code .= sprintf(
+ $format,
+ var_export( $key, true ),
+ var_export( $value, true )
+ );
+ }
+ $code .= "];\n";
+ return $code;
+}
+
/**
* Make a cache key for the local wiki.
*
* @return string
*/
function wfMemcKey( /*...*/ ) {
- return call_user_func_array(
- [ ObjectCache::getLocalClusterInstance(), 'makeKey' ],
- func_get_args()
- );
+ return ObjectCache::getLocalClusterInstance()->makeKey( ...func_get_args() );
}
/**
function wfForeignMemcKey( $db, $prefix /*...*/ ) {
$args = array_slice( func_get_args(), 2 );
$keyspace = $prefix ? "$db-$prefix" : $db;
- return call_user_func_array(
- [ ObjectCache::getLocalClusterInstance(), 'makeKeyInternal' ],
- [ $keyspace, $args ]
- );
+ return ObjectCache::getLocalClusterInstance()->makeKeyInternal( $keyspace, $args );
}
/**
* @return string
*/
function wfGlobalCacheKey( /*...*/ ) {
- return call_user_func_array(
- [ ObjectCache::getLocalClusterInstance(), 'makeGlobalKey' ],
- func_get_args()
- );
+ return ObjectCache::getLocalClusterInstance()->makeGlobalKey( ...func_get_args() );
}
/**
return ObjectCache::getInstance( $wgMessageCacheType );
}
-/**
- * Get the cache object used by the parser cache
- *
- * @deprecated since 1.30, use MediaWikiServices::getParserCache()->getCacheStorage()
- * @return BagOStuff
- */
-function wfGetParserCacheStorage() {
- global $wgParserCacheType;
- return ObjectCache::getInstance( $wgParserCacheType );
-}
-
/**
* Call hook functions defined in $wgHooks
*
* @param string $format The format string (See php's docs)
* @param string $data A binary string of binary data
* @param int|bool $length The minimum length of $data or false. This is to
- * prevent reading beyond the end of $data. false to disable the check.
+ * prevent reading beyond the end of $data. false to disable the check.
*
* Also be careful when using this function to read unsigned 32 bit integer
* because php might make it negative.