diff options
Diffstat (limited to 'includes/GlobalFunctions.php')
-rw-r--r-- | includes/GlobalFunctions.php | 448 |
1 files changed, 254 insertions, 194 deletions
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 50758c89..016736f4 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -50,7 +50,7 @@ if ( !function_exists( 'mb_substr' ) ) { * @codeCoverageIgnore * @return string */ - function mb_substr( $str, $start, $count='end' ) { + function mb_substr( $str, $start, $count = 'end' ) { return Fallback::mb_substr( $str, $start, $count ); } @@ -94,7 +94,6 @@ if( !function_exists( 'mb_strrpos' ) ) { } } - // Support for Wietse Venema's taint feature if ( !function_exists( 'istainted' ) ) { /** @@ -168,7 +167,8 @@ function wfArrayLookup( $a, $b ) { * @param $key String|Int * @param $value Mixed * @param $default Mixed - * @param $changed Array to alter + * @param array $changed to alter + * @throws MWException */ function wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed ) { if ( is_null( $changed ) ) { @@ -232,8 +232,8 @@ function wfMergeErrorArrays( /*...*/ ) { /** * Insert array into another array after the specified *KEY* * - * @param $array Array: The array. - * @param $insert Array: The array to insert. + * @param array $array The array. + * @param array $insert The array to insert. * @param $after Mixed: The key to insert after * @return Array */ @@ -311,12 +311,12 @@ function wfRandom() { } /** - * Get a random string containing a number of pesudo-random hex + * Get a random string containing a number of pseudo-random hex * characters. * @note This is not secure, if you are trying to generate some sort * of token please use MWCryptRand instead. * - * @param $length int The length of the string to generate + * @param int $length The length of the string to generate * @return String * @since 1.20 */ @@ -349,7 +349,7 @@ function wfRandomString( $length = 32 ) { * * @param $s String: * @return string -*/ + */ function wfUrlencode( $s ) { static $needle; if ( is_null( $s ) ) { @@ -379,8 +379,8 @@ function wfUrlencode( $s ) { * "days=7&limit=100". Options in the first array override options in the second. * Options set to null or false will not be output. * - * @param $array1 Array ( String|Array ) - * @param $array2 Array ( String|Array ) + * @param array $array1 ( String|Array ) + * @param array $array2 ( String|Array ) * @param $prefix String * @return String */ @@ -391,7 +391,7 @@ function wfArrayToCgi( $array1, $array2 = null, $prefix = '' ) { $cgi = ''; foreach ( $array1 as $key => $value ) { - if ( !is_null($value) && $value !== false ) { + if ( !is_null( $value ) && $value !== false ) { if ( $cgi != '' ) { $cgi .= '&'; } @@ -422,11 +422,11 @@ function wfArrayToCgi( $array1, $array2 = null, $prefix = '' ) { /** * This is the logical opposite of wfArrayToCgi(): it accepts a query string as - * its argument and returns the same string in array form. This allows compa- - * tibility with legacy functions that accept raw query strings instead of nice + * its argument and returns the same string in array form. This allows compatibility + * with legacy functions that accept raw query strings instead of nice * arrays. Of course, keys and values are urldecode()d. * - * @param $query String: query string + * @param string $query query string * @return array Array version of input */ function wfCgiToArray( $query ) { @@ -506,7 +506,7 @@ function wfAppendQuery( $url, $query ) { * @todo this won't work with current-path-relative URLs * like "subdir/foo.html", etc. * - * @param $url String: either fully-qualified or a local path + query + * @param string $url either fully-qualified or a local path + query * @param $defaultProto Mixed: one of the PROTO_* constants. Determines the * protocol to use if $url or $wgServer is * protocol-relative @@ -576,7 +576,7 @@ function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) { * @todo Need to integrate this into wfExpandUrl (bug 32168) * * @since 1.19 - * @param $urlParts Array URL parts, as output from wfParseUrl + * @param array $urlParts URL parts, as output from wfParseUrl * @return string URL assembled from its component parts */ function wfAssembleUrl( $urlParts ) { @@ -628,7 +628,7 @@ function wfAssembleUrl( $urlParts ) { * * @todo Need to integrate this into wfExpandUrl (bug 32168) * - * @param $urlPath String URL path, potentially containing dot-segments + * @param string $urlPath URL path, potentially containing dot-segments * @return string URL path with all dot-segments removed */ function wfRemoveDotSegments( $urlPath ) { @@ -705,7 +705,7 @@ function wfRemoveDotSegments( $urlPath ) { /** * Returns a regular expression of url protocols * - * @param $includeProtocolRelative bool If false, remove '//' from the returned protocol list. + * @param bool $includeProtocolRelative If false, remove '//' from the returned protocol list. * DO NOT USE this directly, use wfUrlProtocolsWithoutProtRel() instead * @return String */ @@ -765,7 +765,7 @@ function wfUrlProtocolsWithoutProtRel() { * 2) Handles protocols that don't use :// (e.g., mailto: and news: , as well as protocol-relative URLs) correctly * 3) Adds a "delimiter" element to the array, either '://', ':' or '//' (see (2)) * - * @param $url String: a URL to parse + * @param string $url a URL to parse * @return Array: bits of the URL in an associative array, per PHP docs */ function wfParseUrl( $url ) { @@ -808,9 +808,14 @@ function wfParseUrl( $url ) { if ( !isset( $bits['host'] ) ) { $bits['host'] = ''; - /* parse_url loses the third / for file:///c:/ urls (but not on variants) */ - if ( substr( $bits['path'], 0, 1 ) !== '/' ) { - $bits['path'] = '/' . $bits['path']; + // bug 45069 + if ( isset( $bits['path'] ) ) { + /* parse_url loses the third / for file:///c:/ urls (but not on variants) */ + if ( substr( $bits['path'], 0, 1 ) !== '/' ) { + $bits['path'] = '/' . $bits['path']; + } + } else { + $bits['path'] = ''; } } @@ -845,8 +850,6 @@ function wfExpandIRI_callback( $matches ) { return urldecode( $matches[1] ); } - - /** * Make URL indexes, appropriate for the el_index field of externallinks. * @@ -903,8 +906,8 @@ function wfMakeUrlIndexes( $url ) { /** * Check whether a given URL has a domain that occurs in a given set of domains - * @param $url string URL - * @param $domains array Array of domains (strings) + * @param string $url URL + * @param array $domains Array of domains (strings) * @return bool True if the host part of $url ends in one of the strings in $domains */ function wfMatchesDomainList( $url, $domains ) { @@ -932,7 +935,7 @@ function wfMatchesDomainList( $url, $domains ) { * $wgDebugComments - if on, some debug items may appear in comments in the HTML output. * * @param $text String - * @param $logonly Bool: set true to avoid appearing in HTML when $wgDebugComments is set + * @param bool $logonly set true to avoid appearing in HTML when $wgDebugComments is set */ function wfDebug( $text, $logonly = false ) { global $wgDebugLogFile, $wgProfileOnly, $wgDebugRawPage, $wgDebugLogPrefix; @@ -1004,7 +1007,7 @@ function wfDebugTimer() { /** * Send a line giving PHP memory usage. * - * @param $exact Bool: print exact values instead of kilobytes (default: false) + * @param bool $exact print exact values instead of kilobytes (default: false) */ function wfDebugMem( $exact = false ) { $mem = memory_get_usage(); @@ -1022,7 +1025,7 @@ function wfDebugMem( $exact = false ) { * * @param $logGroup String * @param $text String - * @param $public Bool: whether to log the event in the public log if no private + * @param bool $public whether to log the event in the public log if no private * log file is specified, (default true) */ function wfDebugLog( $logGroup, $text, $public = true ) { @@ -1036,14 +1039,14 @@ function wfDebugLog( $logGroup, $text, $public = true ) { wfErrorLog( "$time $host $wiki: $text", $wgDebugLogGroups[$logGroup] ); } } elseif ( $public === true ) { - wfDebug( $text, true ); + wfDebug( "[$logGroup] $text", true ); } } /** * Log for database errors * - * @param $text String: database error message. + * @param string $text database error message. */ function wfLogDBError( $text ) { global $wgDBerrorLog, $wgDBerrorLogTZ; @@ -1076,9 +1079,9 @@ function wfLogDBError( $text ) { * Throws a warning that $function is deprecated * * @param $function String - * @param $version String|bool: Version of MediaWiki that the function was deprecated in (Added in 1.19). - * @param $component String|bool: Added in 1.19. - * @param $callerOffset integer: How far up the callstack is the original + * @param string|bool $version Version of MediaWiki that the function was deprecated in (Added in 1.19). + * @param string|bool $component Added in 1.19. + * @param $callerOffset integer: How far up the call stack is the original * caller. 2 = function that called the function that called * wfDeprecated (Added in 1.20) * @@ -1092,7 +1095,7 @@ function wfDeprecated( $function, $version = false, $component = false, $callerO * Send a warning either to the debug log or in a PHP error depending on * $wgDevelopmentWarnings * - * @param $msg String: message to send + * @param string $msg message to send * @param $callerOffset Integer: number of items to go back in the backtrace to * find the correct caller (1 = function calling wfWarn, ...) * @param $level Integer: PHP error level; only used when $wgDevelopmentWarnings @@ -1109,7 +1112,8 @@ function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) { * send lines to the specified port, prefixed by the specified prefix and a space. * * @param $text String - * @param $file String filename + * @param string $file filename + * @throws MWException */ function wfErrorLog( $text, $file ) { if ( substr( $file, 0, 4 ) == 'udp:' ) { @@ -1212,9 +1216,18 @@ function wfLogProfilingData() { if ( $wgUser->isItemLoaded( 'id' ) && $wgUser->isAnon() ) { $forward .= ' anon'; } + + // Command line script uses a FauxRequest object which does not have + // any knowledge about an URL and throw an exception instead. + try { + $requestUrl = $wgRequest->getRequestURL(); + } catch ( MWException $e ) { + $requestUrl = 'n/a'; + } + $log = sprintf( "%s\t%04.3f\t%s\n", gmdate( 'YmdHis' ), $elapsed, - urldecode( $wgRequest->getRequestURL() . $forward ) ); + urldecode( $requestUrl . $forward ) ); wfErrorLog( $log . $profiler->getOutput(), $wgDebugLogFile ); } @@ -1224,17 +1237,21 @@ function wfLogProfilingData() { * * @param $key String * @param $count Int + * @return void */ function wfIncrStats( $key, $count = 1 ) { global $wgStatsMethod; $count = intval( $count ); + if ( $count == 0 ) { + return; + } if( $wgStatsMethod == 'udp' ) { - global $wgUDPProfilerHost, $wgUDPProfilerPort, $wgDBname, $wgAggregateStatsID; + global $wgUDPProfilerHost, $wgUDPProfilerPort, $wgAggregateStatsID; static $socket; - $id = $wgAggregateStatsID !== false ? $wgAggregateStatsID : $wgDBname; + $id = $wgAggregateStatsID !== false ? $wgAggregateStatsID : wfWikiID(); if ( !$socket ) { $socket = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP ); @@ -1366,9 +1383,13 @@ function wfUILang() { } /** - * This is the new function for getting translated interface messages. - * See the Message class for documentation how to use them. - * The intention is that this function replaces all old wfMsg* functions. + * This is the function for getting translated interface messages. + * + * @see Message class for documentation how to use them. + * @see https://www.mediawiki.org/wiki/Manual:Messages_API + * + * This function replaces all old wfMsg* functions. + * * @param $key \string Message key. * Varargs: normal message parameters. * @return Message @@ -1404,7 +1425,7 @@ function wfMessageFallback( /*...*/ ) { * * @deprecated since 1.18 * - * @param $key String: lookup key for the message, usually + * @param string $key lookup key for the message, usually * defined in languages/Language.php * * Parameters to the message, which can be used to insert variable text into @@ -1416,6 +1437,8 @@ function wfMessageFallback( /*...*/ ) { * @return String */ function wfMsg( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + $args = func_get_args(); array_shift( $args ); return wfMsgReal( $key, $args ); @@ -1430,6 +1453,8 @@ function wfMsg( $key ) { * @return String */ function wfMsgNoTrans( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + $args = func_get_args(); array_shift( $args ); return wfMsgReal( $key, $args, true, false, false ); @@ -1456,11 +1481,13 @@ function wfMsgNoTrans( $key ) { * * @deprecated since 1.18 * - * @param $key String: lookup key for the message, usually + * @param string $key lookup key for the message, usually * defined in languages/Language.php * @return String */ function wfMsgForContent( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + global $wgForceUIMsgAsContentMsg; $args = func_get_args(); array_shift( $args ); @@ -1482,6 +1509,8 @@ function wfMsgForContent( $key ) { * @return String */ function wfMsgForContentNoTrans( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + global $wgForceUIMsgAsContentMsg; $args = func_get_args(); array_shift( $args ); @@ -1499,7 +1528,7 @@ function wfMsgForContentNoTrans( $key ) { * * @deprecated since 1.18 * - * @param $key String: key to get. + * @param string $key key to get. * @param $args * @param $useDB Boolean * @param $forContent Mixed: Language code, or false for user lang, true for content lang. @@ -1507,6 +1536,8 @@ function wfMsgForContentNoTrans( $key ) { * @return String: the requested message. */ function wfMsgReal( $key, $args, $useDB = true, $forContent = false, $transform = true ) { + wfDeprecated( __METHOD__, '1.21' ); + wfProfileIn( __METHOD__ ); $message = wfMsgGetKey( $key, $useDB, $forContent, $transform ); $message = wfMsgReplaceArgs( $message, $args ); @@ -1521,12 +1552,14 @@ function wfMsgReal( $key, $args, $useDB = true, $forContent = false, $transform * * @param $key String * @param $useDB Bool - * @param $langCode String: Code of the language to get the message for, or + * @param string $langCode Code of the language to get the message for, or * behaves as a content language switch if it is a boolean. * @param $transform Boolean: whether to parse magic words, etc. * @return string */ function wfMsgGetKey( $key, $useDB = true, $langCode = false, $transform = true ) { + wfDeprecated( __METHOD__, '1.21' ); + wfRunHooks( 'NormalizeMessageKey', array( &$key, &$useDB, &$langCode, &$transform ) ); $cache = MessageCache::singleton(); @@ -1581,6 +1614,8 @@ function wfMsgReplaceArgs( $message, $args ) { * @return string */ function wfMsgHtml( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + $args = func_get_args(); array_shift( $args ); return wfMsgReplaceArgs( htmlspecialchars( wfMsgGetKey( $key ) ), $args ); @@ -1600,6 +1635,8 @@ function wfMsgHtml( $key ) { * @return string */ function wfMsgWikiHtml( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + $args = func_get_args(); array_shift( $args ); return wfMsgReplaceArgs( @@ -1613,8 +1650,8 @@ function wfMsgWikiHtml( $key ) { * * @deprecated since 1.18 * - * @param $key String: key of the message - * @param $options Array: processing rules. Can take the following options: + * @param string $key key of the message + * @param array $options processing rules. Can take the following options: * <i>parse</i>: parses wikitext to HTML * <i>parseinline</i>: parses wikitext to HTML and removes the surrounding * p's added by parser or tidy @@ -1625,12 +1662,14 @@ function wfMsgWikiHtml( $key ) { * <i>content</i>: fetch message for content language instead of interface * Also can accept a single associative argument, of the form 'language' => 'xx': * <i>language</i>: Language object or language code to fetch message for - * (overriden by <i>content</i>). + * (overridden by <i>content</i>). * Behavior for conflicting options (e.g., parse+parseinline) is undefined. * * @return String */ function wfMsgExt( $key, $options ) { + wfDeprecated( __METHOD__, '1.21' ); + $args = func_get_args(); array_shift( $args ); array_shift( $args ); @@ -1703,7 +1742,7 @@ function wfMsgExt( $key, $options ) { /** * Since wfMsg() and co suck, they don't return false if the message key they * looked up didn't exist but a XHTML string, this function checks for the - * nonexistance of messages by checking the MessageCache::get() result directly. + * nonexistence of messages by checking the MessageCache::get() result directly. * * @deprecated since 1.18. Use Message::isDisabled(). * @@ -1711,6 +1750,8 @@ function wfMsgExt( $key, $options ) { * @return Boolean True if the message *doesn't* exist. */ function wfEmptyMsg( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + return MessageCache::singleton()->get( $key, /*useDB*/true, /*content*/false ) === false; } @@ -1718,7 +1759,8 @@ function wfEmptyMsg( $key ) { * Throw a debugging exception. This function previously once exited the process, * but now throws an exception instead, with similar results. * - * @param $msg String: message shown when dying. + * @param string $msg message shown when dying. + * @throws MWException */ function wfDebugDieBacktrace( $msg = '' ) { throw new MWException( $msg ); @@ -1783,13 +1825,13 @@ function wfReportTime() { * * With Zend Optimizer 3.2.0 loaded, this causes segfaults under somewhat * murky circumstances, which may be triggered in part by stub objects - * or other fancy talkin'. + * or other fancy talking'. * * Will return an empty array if Zend Optimizer is detected or if * debug_backtrace is disabled, otherwise the output from * debug_backtrace() (trimmed). * - * @param $limit int This parameter can be used to limit the number of stack frames returned + * @param int $limit This parameter can be used to limit the number of stack frames returned * * @return array of backtrace information */ @@ -1895,7 +1937,7 @@ function wfGetCaller( $level = 2 ) { * Return a string consisting of callers in the stack. Useful sometimes * for profiling specific points. * - * @param $limit int The maximum depth of the stack frame to return, or false for + * @param int $limit The maximum depth of the stack frame to return, or false for * the entire stack. * @return String */ @@ -1920,10 +1962,8 @@ function wfFormatStackFrame( $frame ) { $frame['function']; } - /* Some generic result counters, pulled out of SearchEngine */ - /** * @todo document * @@ -1941,8 +1981,8 @@ function wfShowingResults( $offset, $limit ) { * @param $offset String * @param $limit Integer * @param $link String - * @param $query String: optional URL query parameter string - * @param $atend Bool: optional param for specified if this is the last page + * @param string $query optional URL query parameter string + * @param bool $atend optional param for specified if this is the last page * @return String * @deprecated in 1.19; use Language::viewPrevNext() instead */ @@ -1968,8 +2008,8 @@ function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) { /** * Make a list item, used by various special pages * - * @param $page String Page link - * @param $details String Text between brackets + * @param string $page Page link + * @param string $details Text between brackets * @param $oppositedm Boolean Add the direction mark opposite to your * language, to display text properly * @return String @@ -2018,8 +2058,8 @@ function wfClientAcceptsGzip( $force = false ) { * Obtain the offset and limit values from the request string; * used in special pages * - * @param $deflimit Int default limit if none supplied - * @param $optionname String Name of a user preference to check against + * @param int $deflimit default limit if none supplied + * @param string $optionname Name of a user preference to check against * @return array * */ @@ -2034,7 +2074,7 @@ function wfCheckLimits( $deflimit = 50, $optionname = 'rclimit' ) { * is achieved by substituting certain characters with HTML entities. * As required by the callers, "<nowiki>" is not used. * - * @param $text String: text to be escaped + * @param string $text text to be escaped * @return String */ function wfEscapeWikiText( $text ) { @@ -2050,7 +2090,7 @@ function wfEscapeWikiText( $text ) { } /** - * Get the current unix timetstamp with microseconds. Useful for profiling + * Get the current unix timestamp with microseconds. Useful for profiling * @return Float */ function wfTime() { @@ -2207,7 +2247,7 @@ function wfClearOutputBuffers() { * factors * * @param $accept String - * @param $def String default + * @param string $def default * @return Array */ function wfAcceptToPrefs( $accept, $def = '*/*' ) { @@ -2267,8 +2307,8 @@ function mimeTypeMatch( $type, $avail ) { * array of type to preference (preference is a float between 0.0 and 1.0). * Wildcards in the types are acceptable. * - * @param $cprefs Array: client's acceptable type list - * @param $sprefs Array: server's offered types + * @param array $cprefs client's acceptable type list + * @param array $sprefs server's offered types * @return string * * @todo FIXME: Doesn't handle params like 'text/plain; charset=UTF-8' @@ -2390,11 +2430,6 @@ define( 'TS_ORACLE', 6 ); define( 'TS_POSTGRES', 7 ); /** - * DB2 format time - */ -define( 'TS_DB2', 8 ); - -/** * ISO 8601 basic format with no timezone: 19860209T200000Z. This is used by ResourceLoader */ define( 'TS_ISO_8601_BASIC', 9 ); @@ -2405,7 +2440,7 @@ define( 'TS_ISO_8601_BASIC', 9 ); * @param $outputtype Mixed: A timestamp in one of the supported formats, the * function will autodetect which format is supplied and act * accordingly. - * @param $ts Mixed: the timestamp to convert or 0 for the current timestamp + * @param $ts Mixed: optional timestamp to convert, default 0 for the current time * @return Mixed: String / false The same date in the format specified in $outputtype or false */ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) { @@ -2413,7 +2448,7 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) { $timestamp = new MWTimestamp( $ts ); return $timestamp->getTimestamp( $outputtype ); } catch( TimestampException $e ) { - wfDebug("wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n"); + wfDebug( "wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n" ); return false; } } @@ -2509,9 +2544,10 @@ function wfTempDir() { /** * Make directory, and make all parent directories if they don't exist * - * @param $dir String: full path to directory to create + * @param string $dir full path to directory to create * @param $mode Integer: chmod value to use, default is $wgDirectoryMode - * @param $caller String: optional caller param for debugging. + * @param string $caller optional caller param for debugging. + * @throws MWException * @return bool */ function wfMkdirParents( $dir, $mode = null, $caller = null ) { @@ -2585,12 +2621,14 @@ function wfPercent( $nr, $acc = 2, $round = true ) { /** * Find out whether or not a mixed variable exists in a string * + * @deprecated Just use str(i)pos * @param $needle String * @param $str String * @param $insensitive Boolean * @return Boolean */ function in_string( $needle, $str, $insensitive = false ) { + wfDeprecated( __METHOD__, '1.21' ); $func = 'strpos'; if( $insensitive ) $func = 'stripos'; @@ -2633,9 +2671,9 @@ function wfIniGetBool( $setting ) { * Wrapper function for PHP's dl(). This doesn't work in most situations from * PHP 5.3 onward, and is usually disabled in shared environments anyway. * - * @param $extension String A PHP extension. The file suffix (.so or .dll) + * @param string $extension A PHP extension. The file suffix (.so or .dll) * should be omitted - * @param $fileName String Name of the library, if not $extension.suffix + * @param string $fileName Name of the library, if not $extension.suffix * @return Bool - Whether or not the extension is loaded */ function wfDl( $extension, $fileName = null ) { @@ -2644,8 +2682,7 @@ function wfDl( $extension, $fileName = null ) { } $canDl = false; - $sapi = php_sapi_name(); - if( $sapi == 'cli' || $sapi == 'cgi' || $sapi == 'embed' ) { + if( PHP_SAPI == 'cli' || PHP_SAPI == 'cgi' || PHP_SAPI == 'embed' ) { $canDl = ( function_exists( 'dl' ) && is_callable( 'dl' ) && wfIniGetBool( 'enable_dl' ) && !wfIniGetBool( 'safe_mode' ) ); } @@ -2673,7 +2710,7 @@ function wfDl( $extension, $fileName = null ) { * @param varargs * @return String */ -function wfEscapeShellArg( ) { +function wfEscapeShellArg() { wfInitShellLocale(); $args = func_get_args(); @@ -2729,17 +2766,18 @@ function wfEscapeShellArg( ) { /** * Execute a shell command, with time and memory limits mirrored from the PHP * configuration if supported. - * @param $cmd String Command line, properly escaped for shell. + * @param string $cmd Command line, properly escaped for shell. * @param &$retval null|Mixed optional, will receive the program's exit code. * (non-zero is usually failure) - * @param $environ Array optional environment variables which should be + * @param array $environ optional environment variables which should be * added to the executed command environment. - * @param $limits Array optional array with limits(filesize, memory, time) + * @param array $limits optional array with limits(filesize, memory, time, walltime) * this overwrites the global wgShellMax* limits. * @return string collected stdout as a string (trailing newlines stripped) */ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array() ) { - global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime; + global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime, + $wgMaxShellWallClockTime, $wgShellCgroup; static $disabled; if ( is_null( $disabled ) ) { @@ -2786,15 +2824,27 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array $cmd = $envcmd . $cmd; if ( php_uname( 's' ) == 'Linux' ) { - $time = intval ( isset($limits['time']) ? $limits['time'] : $wgMaxShellTime ); - $mem = intval ( isset($limits['memory']) ? $limits['memory'] : $wgMaxShellMemory ); - $filesize = intval ( isset($limits['filesize']) ? $limits['filesize'] : $wgMaxShellFileSize ); - - if ( $time > 0 && $mem > 0 ) { - $script = "$IP/bin/ulimit4.sh"; - if ( is_executable( $script ) ) { - $cmd = '/bin/bash ' . escapeshellarg( $script ) . " $time $mem $filesize " . escapeshellarg( $cmd ); - } + $time = intval ( isset( $limits['time'] ) ? $limits['time'] : $wgMaxShellTime ); + if ( isset( $limits['walltime'] ) ) { + $wallTime = intval( $limits['walltime'] ); + } elseif ( isset( $limits['time'] ) ) { + $wallTime = $time; + } else { + $wallTime = intval( $wgMaxShellWallClockTime ); + } + $mem = intval ( isset( $limits['memory'] ) ? $limits['memory'] : $wgMaxShellMemory ); + $filesize = intval ( isset( $limits['filesize'] ) ? $limits['filesize'] : $wgMaxShellFileSize ); + + if ( $time > 0 || $mem > 0 || $filesize > 0 || $wallTime > 0 ) { + $cmd = '/bin/bash ' . escapeshellarg( "$IP/includes/limit.sh" ) . ' ' . + escapeshellarg( $cmd ) . ' ' . + escapeshellarg( + "MW_CPU_LIMIT=$time; " . + 'MW_CGROUP=' . escapeshellarg( $wgShellCgroup ) . '; ' . + "MW_MEM_LIMIT=$mem; " . + "MW_FILE_SIZE_LIMIT=$filesize; " . + "MW_WALL_CLOCK_LIMIT=$wallTime" + ); } } wfDebug( "wfShellExec: $cmd\n" ); @@ -2840,9 +2890,9 @@ function wfShellMaintenanceCmd( $script, array $parameters = array(), array $opt * Generate a shell-escaped command line string to run a MediaWiki cli script. * Note that $parameters should be a flat array and an option with an argument * should consist of two consecutive items in the array (do not use "--option value"). - * @param $script string MediaWiki cli script path - * @param $parameters Array Arguments and options to the script - * @param $options Array Associative array of options: + * @param string $script MediaWiki cli script path + * @param array $parameters Arguments and options to the script + * @param array $options Associative array of options: * 'php': The path to the php executable * 'wrapper': Path to a PHP wrapper to handle the maintenance script * @return Array @@ -2891,15 +2941,19 @@ function wfMerge( $old, $mine, $yours, &$result ) { $mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ), 'w' ); $yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ), 'w' ); - fwrite( $oldtextFile, $old ); + # NOTE: diff3 issues a warning to stderr if any of the files does not end with + # a newline character. To avoid this, we normalize the trailing whitespace before + # creating the diff. + + fwrite( $oldtextFile, rtrim( $old ) . "\n" ); fclose( $oldtextFile ); - fwrite( $mytextFile, $mine ); + fwrite( $mytextFile, rtrim( $mine ) . "\n" ); fclose( $mytextFile ); - fwrite( $yourtextFile, $yours ); + fwrite( $yourtextFile, rtrim( $yours ) . "\n" ); fclose( $yourtextFile ); # Check for a conflict - $cmd = $wgDiff3 . ' -a --overlap-only ' . + $cmd = wfEscapeShellArg( $wgDiff3 ) . ' -a --overlap-only ' . wfEscapeShellArg( $mytextName ) . ' ' . wfEscapeShellArg( $oldtextName ) . ' ' . wfEscapeShellArg( $yourtextName ); @@ -2913,7 +2967,7 @@ function wfMerge( $old, $mine, $yours, &$result ) { pclose( $handle ); # Merge differences - $cmd = $wgDiff3 . ' -a -e --merge ' . + $cmd = wfEscapeShellArg( $wgDiff3 ) . ' -a -e --merge ' . wfEscapeShellArg( $mytextName, $oldtextName, $yourtextName ); $handle = popen( $cmd, 'r' ); $result = ''; @@ -2940,9 +2994,9 @@ function wfMerge( $old, $mine, $yours, &$result ) { * Returns unified plain-text diff of two texts. * Useful for machine processing of diffs. * - * @param $before String: the text before the changes. - * @param $after String: the text after the changes. - * @param $params String: command-line options for the diff command. + * @param string $before the text before the changes. + * @param string $after the text after the changes. + * @param string $params command-line options for the diff command. * @return String: unified diff of $before and $after */ function wfDiff( $before, $after, $params = '-u' ) { @@ -3022,6 +3076,7 @@ function wfDiff( $before, $after, $params = '-u' ) { * * @param $req_ver Mixed: the version to check, can be a string, an integer, or * a float + * @throws MWException */ function wfUsePHP( $req_ver ) { $php_ver = PHP_VERSION; @@ -3043,6 +3098,7 @@ function wfUsePHP( $req_ver ) { * * @param $req_ver Mixed: the version to check, can be a string, an integer, or * a float + * @throws MWException */ function wfUseMW( $req_ver ) { global $wgVersion; @@ -3061,7 +3117,7 @@ function wfUseMW( $req_ver ) { * We'll consider it so always, as we don't want '\s' in our Unix paths either. * * @param $path String - * @param $suffix String: to remove if present + * @param string $suffix to remove if present * @return String */ function wfBaseName( $path, $suffix = '' ) { @@ -3081,8 +3137,8 @@ function wfBaseName( $path, $suffix = '' ) { * May explode on non-matching case-insensitive paths, * funky symlinks, etc. * - * @param $path String: absolute destination path including target filename - * @param $from String: Absolute source path, directory only + * @param string $path absolute destination path including target filename + * @param string $from Absolute source path, directory only * @return String */ function wfRelativePath( $path, $from ) { @@ -3140,91 +3196,105 @@ function wfDoUpdates( $commit = '' ) { * Supports base 2 through 36; digit values 10-36 are represented * as lowercase letters a-z. Input is case-insensitive. * - * @param $input String: of digits - * @param $sourceBase Integer: 2-36 - * @param $destBase Integer: 2-36 - * @param $pad Integer: 1 or greater - * @param $lowercase Boolean - * @return String or false on invalid input - */ -function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1, $lowercase = true ) { - $input = strval( $input ); - if( $sourceBase < 2 || + * @param string $input Input number + * @param int $sourceBase Base of the input number + * @param int $destBase Desired base of the output + * @param int $pad Minimum number of digits in the output (pad with zeroes) + * @param bool $lowercase Whether to output in lowercase or uppercase + * @param string $engine Either "gmp", "bcmath", or "php" + * @return string|bool The output number as a string, or false on error + */ +function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1, $lowercase = true, $engine = 'auto' ) { + $input = (string)$input; + if( + $sourceBase < 2 || $sourceBase > 36 || $destBase < 2 || $destBase > 36 || - $pad < 1 || - $sourceBase != intval( $sourceBase ) || - $destBase != intval( $destBase ) || - $pad != intval( $pad ) || - !is_string( $input ) || - $input == '' ) { + $sourceBase != (int) $sourceBase || + $destBase != (int) $destBase || + $pad != (int) $pad || + !preg_match( "/^[" . substr( '0123456789abcdefghijklmnopqrstuvwxyz', 0, $sourceBase ) . "]+$/i", $input ) + ) { return false; } - $digitChars = ( $lowercase ) ? '0123456789abcdefghijklmnopqrstuvwxyz' : '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $inDigits = array(); - $outChars = ''; - // Decode and validate input string - $input = strtolower( $input ); - for( $i = 0; $i < strlen( $input ); $i++ ) { - $n = strpos( $digitChars, $input[$i] ); - if( $n === false || $n > $sourceBase ) { - return false; + static $baseChars = array ( + 10 => 'a', 11 => 'b', 12 => 'c', 13 => 'd', 14 => 'e', 15 => 'f', + 16 => 'g', 17 => 'h', 18 => 'i', 19 => 'j', 20 => 'k', 21 => 'l', + 22 => 'm', 23 => 'n', 24 => 'o', 25 => 'p', 26 => 'q', 27 => 'r', + 28 => 's', 29 => 't', 30 => 'u', 31 => 'v', 32 => 'w', 33 => 'x', + 34 => 'y', 35 => 'z', + + '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, + '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'a' => 10, 'b' => 11, + 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15, 'g' => 16, 'h' => 17, + 'i' => 18, 'j' => 19, 'k' => 20, 'l' => 21, 'm' => 22, 'n' => 23, + 'o' => 24, 'p' => 25, 'q' => 26, 'r' => 27, 's' => 28, 't' => 29, + 'u' => 30, 'v' => 31, 'w' => 32, 'x' => 33, 'y' => 34, 'z' => 35 + ); + + if( extension_loaded( 'gmp' ) && ( $engine == 'auto' || $engine == 'gmp' ) ) { + $result = gmp_strval( gmp_init( $input, $sourceBase ), $destBase ); + } elseif( extension_loaded( 'bcmath' ) && ( $engine == 'auto' || $engine == 'bcmath' ) ) { + $decimal = '0'; + foreach( str_split( strtolower( $input ) ) as $char ) { + $decimal = bcmul( $decimal, $sourceBase ); + $decimal = bcadd( $decimal, $baseChars[$char] ); } - $inDigits[] = $n; - } - // Iterate over the input, modulo-ing out an output digit - // at a time until input is gone. - while( count( $inDigits ) ) { - $work = 0; - $workDigits = array(); + for( $result = ''; bccomp( $decimal, 0 ); $decimal = bcdiv( $decimal, $destBase, 0 ) ) { + $result .= $baseChars[bcmod( $decimal, $destBase )]; + } - // Long division... - foreach( $inDigits as $digit ) { - $work *= $sourceBase; - $work += $digit; + $result = strrev( $result ); + } else { + $inDigits = array(); + foreach( str_split( strtolower( $input ) ) as $char ) { + $inDigits[] = $baseChars[$char]; + } - if( $work < $destBase ) { - // Gonna need to pull another digit. - if( count( $workDigits ) ) { - // Avoid zero-padding; this lets us find - // the end of the input very easily when - // length drops to zero. - $workDigits[] = 0; - } - } else { - // Finally! Actual division! - $workDigits[] = intval( $work / $destBase ); + // Iterate over the input, modulo-ing out an output digit + // at a time until input is gone. + $result = ''; + while( $inDigits ) { + $work = 0; + $workDigits = array(); + + // Long division... + foreach( $inDigits as $digit ) { + $work *= $sourceBase; + $work += $digit; - // Isn't it annoying that most programming languages - // don't have a single divide-and-remainder operator, - // even though the CPU implements it that way? - $work = $work % $destBase; + if( $workDigits || $work >= $destBase ) { + $workDigits[] = (int) ( $work / $destBase ); + } + $work %= $destBase; } - } - // All that division leaves us with a remainder, - // which is conveniently our next output digit. - $outChars .= $digitChars[$work]; + // All that division leaves us with a remainder, + // which is conveniently our next output digit. + $result .= $baseChars[$work]; + + // And we continue! + $inDigits = $workDigits; + } - // And we continue! - $inDigits = $workDigits; + $result = strrev( $result ); } - while( strlen( $outChars ) < $pad ) { - $outChars .= '0'; + if( !$lowercase ) { + $result = strtoupper( $result ); } - return strrev( $outChars ); + return str_pad( $result, $pad, '0', STR_PAD_LEFT ); } /** * Create an object with a given name and an array of construct parameters * * @param $name String - * @param $p Array: parameters + * @param array $p parameters * @return object * @deprecated since 1.18, warnings in 1.18, removal in 1.20 */ @@ -3251,7 +3321,7 @@ function wfHttpOnlySafe() { } /** - * Check if there is sufficent entropy in php's built-in session generation + * Check if there is sufficient entropy in php's built-in session generation * @return bool true = there is sufficient entropy */ function wfCheckEntropy() { @@ -3414,7 +3484,7 @@ function wfSplitWikiID( $wiki ) { * belongs to. May contain a single string if the query is only * in one group. * - * @param $wiki String: the wiki ID, or false for the current wiki + * @param string $wiki the wiki ID, or false for the current wiki * * Note: multiple calls to wfGetDB(DB_SLAVE) during the course of one request * will always return the same object, unless the underlying connection or load @@ -3432,7 +3502,7 @@ function &wfGetDB( $db, $groups = array(), $wiki = false ) { /** * Get a load balancer object. * - * @param $wiki String: wiki ID, or false for the current wiki + * @param string $wiki wiki ID, or false for the current wiki * @return LoadBalancer */ function wfGetLB( $wiki = false ) { @@ -3452,8 +3522,8 @@ function &wfGetLBFactory() { * Find a file. * Shortcut for RepoGroup::singleton()->findFile() * - * @param $title String or Title object - * @param $options array Associative array of options: + * @param string $title or Title object + * @param array $options Associative array of options: * time: requested time for an archived image, or false for the * current version. An image object will be returned which was * created at the specified time. @@ -3511,7 +3581,7 @@ function wfQueriesMustScale() { * extensions; this is a wrapper around $wgScriptExtension etc. * except for 'index' and 'load' which use $wgScript/$wgLoadScript * - * @param $script String: script filename, sans extension + * @param string $script script filename, sans extension * @return String */ function wfScript( $script = 'index' ) { @@ -3560,16 +3630,6 @@ function wfBoolToStr( $value ) { } /** - * Load an extension messages file - * - * @deprecated since 1.16, warnings in 1.18, remove in 1.20 - * @codeCoverageIgnore - */ -function wfLoadExtensionMessages() { - wfDeprecated( __FUNCTION__, '1.16' ); -} - -/** * Get a platform-independent path to the null file, e.g. /dev/null * * @return string @@ -3642,8 +3702,8 @@ function wfCountDown( $n ) { * characters before hashing. * @return string * @codeCoverageIgnore - * @deprecated since 1.20; Please use MWCryptRand for security purposes and wfRandomString for pesudo-random strings - * @warning This method is NOT secure. Additionally it has many callers that use it for pesudo-random purposes. + * @deprecated since 1.20; Please use MWCryptRand for security purposes and wfRandomString for pseudo-random strings + * @warning This method is NOT secure. Additionally it has many callers that use it for pseudo-random purposes. */ function wfGenerateToken( $salt = '' ) { wfDeprecated( __METHOD__, '1.20' ); @@ -3732,7 +3792,7 @@ function wfShorthandToInteger( $string = '' ) { * Get the normalised IETF language tag * See unit test for examples. * - * @param $code String: The language code. + * @param string $code The language code. * @return String: The language code which complying with BCP 47 standards. */ function wfBCP47( $code ) { @@ -3815,8 +3875,8 @@ function wfGetLangConverterCacheStorage() { /** * Call hook functions defined in $wgHooks * - * @param $event String: event name - * @param $args Array: parameters passed to hook functions + * @param string $event event name + * @param array $args parameters passed to hook functions * @return Boolean True if no handler aborted the hook */ function wfRunHooks( $event, $args = array() ) { @@ -3826,9 +3886,9 @@ function wfRunHooks( $event, $args = array() ) { /** * Wrapper around php's unpack. * - * @param $format String: The format string (See php's docs) + * @param string $format The format string (See php's docs) * @param $data: A binary string of binary data - * @param $length integer or false: The minimun length of $data. This is to + * @param $length integer or false: The minimum length of $data. This is to * 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 @@ -3868,9 +3928,9 @@ function wfUnpack( $format, $data, $length=false ) { * * Any subsequent links on the same line are considered to be exceptions, * i.e. articles where the image may occur inline. * - * @param $name string the image name to check + * @param string $name the image name to check * @param $contextTitle Title|bool the page on which the image occurs, if known - * @param $blacklist string wikitext of a file blacklist + * @param string $blacklist wikitext of a file blacklist * @return bool */ function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) { |