const OT_WIKI = 2;
const OT_PREPROCESS = 3;
const OT_MSG = 3;
-
+
+ // Marker Suffix needs to be accessible staticly.
+ const MARKER_SUFFIX = "-QINU\x7f";
+
/**#@+
* @private
*/
# Persistent:
var $mTagHooks, $mTransparentTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables,
- $mImageParams, $mImageParamsMagicArray, $mStripList, $mMarkerSuffix, $mMarkerIndex,
- $mExtLinkBracketedRegex, $mPreprocessor, $mDefaultStripList, $mVarCache, $mConf;
+ $mImageParams, $mImageParamsMagicArray, $mStripList, $mMarkerIndex, $mPreprocessor,
+ $mExtLinkBracketedRegex, $mDefaultStripList, $mVarCache, $mConf;
# Cleared with clearState():
var $mIncludeSizes, $mPPNodeCount, $mDefaultSort;
var $mTplExpandCache; // empty-frame expansion cache
var $mTplRedirCache, $mTplDomCache, $mHeadings, $mDoubleUnderscores;
+ var $mExpensiveFunctionCount; // number of expensive parser function calls
# Temporary
# These are variables reset at least once per parse regardless of $clearState
$this->mFunctionHooks = array();
$this->mFunctionSynonyms = array( 0 => array(), 1 => array() );
$this->mDefaultStripList = $this->mStripList = array( 'nowiki', 'gallery' );
- $this->mMarkerSuffix = "-QINU\x7f";
$this->mExtLinkBracketedRegex = '/\[(\b(' . wfUrlProtocols() . ')'.
'[^][<>"\\x00-\\x20\\x7F]+) *([^\]\\x0a\\x0d]*?)\]/S';
$this->mVarCache = array();
$this->mDefaultSort = false;
$this->mHeadings = array();
$this->mDoubleUnderscores = array();
+ $this->mExpensiveFunctionCount = 0;
# Fix cloning
if ( isset( $this->mPreprocessor ) && $this->mPreprocessor->parser !== $this ) {
array_values( $tidyregs ),
$text );
}
+ global $wgExpensiveParserFunctionLimit;
+ if ( $this->mExpensiveFunctionCount > $wgExpensiveParserFunctionLimit ) {
+ if ( is_callable( array( $this->mOutput, 'addWarning' ) ) ) {
+ $warning = wfMsg( 'expensive-parserfunction-warning', $this->mExpensiveFunctionCount, $wgExpensiveParserFunctionLimit );
+ $this->mOutput->addWarning( $warning );
+ $cat = Title::makeTitleSafe( NS_CATEGORY, wfMsgForContent( 'expensive-parserfunction-category' ) );
+ if ( $cat ) {
+ $this->mOutput->addCategory( $cat->getDBkey(), $this->getDefaultSort() );
+ }
+ }
+ }
wfRunHooks( 'ParserAfterTidy', array( &$this, &$text ) );
# Information on include size limits, for the benefit of users who try to skirt them
if ( $this->mOptions->getEnableLimitReport() ) {
+ global $wgExpensiveParserFunctionLimit;
$max = $this->mOptions->getMaxIncludeSize();
+ $PFreport = "Expensive parser function count: {$this->mExpensiveFunctionCount}/$wgExpensiveParserFunctionLimit\n";
$limitReport =
"NewPP limit report\n" .
"Preprocessor node count: {$this->mPPNodeCount}/{$this->mOptions->mMaxPPNodeCount}\n" .
"Post-expand include size: {$this->mIncludeSizes['post-expand']}/$max bytes\n" .
- "Template argument size: {$this->mIncludeSizes['arg']}/$max bytes\n";
+ "Template argument size: {$this->mIncludeSizes['arg']}/$max bytes\n".
+ $PFreport;
wfRunHooks( 'ParserLimitReport', array( $this, &$limitReport ) );
$text .= "\n<!-- \n$limitReport-->\n";
}
$inside = $p[4];
}
- $marker = "$uniq_prefix-$element-" . sprintf('%08X', $n++) . $this->mMarkerSuffix;
+ $marker = "$uniq_prefix-$element-" . sprintf('%08X', $n++) . self::MARKER_SUFFIX;
$stripped .= $marker;
if ( $close === '/>' ) {
* @private
*/
function insertStripItem( $text ) {
- $rnd = "{$this->mUniqPrefix}-item-{$this->mMarkerIndex}-{$this->mMarkerSuffix}";
+ $rnd = "{$this->mUniqPrefix}-item-{$this->mMarkerIndex}-" . self::MARKER_SUFFIX;
$this->mMarkerIndex++;
$this->mStripState->general->setPair( $rnd, $text );
return $rnd;
$text = $this->doDoubleUnderscore( $text );
$text = $this->doHeadings( $text );
if($this->mOptions->getUseDynamicDates()) {
- $df =& DateFormatter::getInstance();
+ $df = DateFormatter::getInstance();
$text = $df->reformat( $this->mOptions->getDateFormat(), $text );
}
$text = $this->doAllQuotes( $text );
# SUBST
wfProfileIn( __METHOD__.'-modifiers' );
if ( !$found ) {
- $mwSubst =& MagicWord::get( 'subst' );
+ $mwSubst = MagicWord::get( 'subst' );
if ( $mwSubst->matchStartAndRemove( $part1 ) xor $this->ot['wiki'] ) {
# One of two possibilities is true:
# 1) Found SUBST but not in the PST phase
# MSG, MSGNW and RAW
if ( !$found ) {
# Check for MSGNW:
- $mwMsgnw =& MagicWord::get( 'msgnw' );
+ $mwMsgnw = MagicWord::get( 'msgnw' );
if ( $mwMsgnw->matchStartAndRemove( $part1 ) ) {
$nowiki = true;
} else {
# Remove obsolete MSG:
- $mwMsg =& MagicWord::get( 'msg' );
+ $mwMsg = MagicWord::get( 'msg' );
$mwMsg->matchStartAndRemove( $part1 );
}
# Check for RAW:
- $mwRaw =& MagicWord::get( 'raw' );
+ $mwRaw = MagicWord::get( 'raw' );
if ( $mwRaw->matchStartAndRemove( $part1 ) ) {
$forceRawInterwiki = true;
}
$attrText = !isset( $params['attr'] ) ? null : $frame->expand( $params['attr'] );
$content = !isset( $params['inner'] ) ? null : $frame->expand( $params['inner'] );
- $marker = "{$this->mUniqPrefix}-$name-" . sprintf('%08X', $this->mMarkerIndex++) . $this->mMarkerSuffix;
+ $marker = "{$this->mUniqPrefix}-$name-" . sprintf('%08X', $this->mMarkerIndex++) . self::MARKER_SUFFIX;
if ( $this->ot['html'] ) {
$name = strtolower( $name );
$prevlevel = 0;
$toclevel = 0;
$prevtoclevel = 0;
- $markerRegex = "{$this->mUniqPrefix}-h-(\d+)-{$this->mMarkerSuffix}";
+ $markerRegex = "{$this->mUniqPrefix}-h-(\d+)-" . self::MARKER_SUFFIX;
$baseTitleText = $this->mTitle->getPrefixedDBkey();
$tocraw = array();
if($prevtoclevel < $wgMaxTocLevel) {
# Unindent only if the previous toc level was shown :p
$toc .= $sk->tocUnindent( $prevtoclevel - $toclevel );
+ $prevtoclevel = $toclevel;
} else {
$toc .= $sk->tocLineEnd();
}
$colours = array();
$linkcolour_ids = array();
$sk = $this->mOptions->getSkin();
- $linkCache =& LinkCache::singleton();
+ $linkCache = LinkCache::singleton();
if ( !empty( $this->mLinkHolders['namespaces'] ) ) {
wfProfileIn( $fname.'-check' );
# Not in the link cache, add it to the query
if ( !isset( $current ) ) {
$current = $ns;
- $query = "SELECT page_id, page_namespace, page_title, page_is_redirect";
- if ( $threshold > 0 ) {
- $query .= ', page_len';
- }
+ $query = "SELECT page_id, page_namespace, page_title, page_is_redirect, page_len";
$query .= " FROM $page WHERE (page_namespace=$ns AND page_title IN(";
} elseif ( $current != $ns ) {
$current = $ns;
while ( $s = $dbr->fetchObject($res) ) {
$title = Title::makeTitle( $s->page_namespace, $s->page_title );
$pdbk = $title->getPrefixedDBkey();
- $linkCache->addGoodLinkObj( $s->page_id, $title );
+ $linkCache->addGoodLinkObj( $s->page_id, $title, $s->page_len, $s->page_is_redirect );
$this->mOutput->addLink( $title, $s->page_id );
- $colours[$pdbk] = $sk->getLinkColour( $s, $threshold );
+ $colours[$pdbk] = $sk->getLinkColour( $title, $threshold );
//add id to the extension todolist
$linkcolour_ids[$s->page_id] = $pdbk;
}
// construct query
$titleClause = $linkBatch->constructSet('page', $dbr);
- $variantQuery = "SELECT page_id, page_namespace, page_title, page_is_redirect";
- if ( $threshold > 0 ) {
- $variantQuery .= ', page_len';
- }
+ $variantQuery = "SELECT page_id, page_namespace, page_title, page_is_redirect, page_len";
$variantQuery .= " FROM $page WHERE $titleClause";
if ( $options & RLH_FOR_UPDATE ) {
$holderKeys = array();
if(isset($variantMap[$varPdbk])){
$holderKeys = $variantMap[$varPdbk];
- $linkCache->addGoodLinkObj( $s->page_id, $variantTitle );
+ $linkCache->addGoodLinkObj( $s->page_id, $variantTitle, $s->page_len, $s->page_is_redirect );
$this->mOutput->addLink( $variantTitle, $s->page_id );
}
// set pdbk and colour
$pdbks[$key] = $varPdbk;
- $colours[$varPdbk] = $sk->getLinkColour( $s, $threshold );
+ $colours[$varPdbk] = $sk->getLinkColour( $variantTitle, $threshold );
$linkcolour_ids[$s->page_id] = $pdbk;
}
wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
* Parse image options text and use it to make an image
*/
function makeImage( $title, $options ) {
- # @TODO: let the MediaHandler specify its transform parameters
- #
# Check if the options text is of the form "options|alt text"
# Options are:
# * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
'horizAlign' => array(), 'vertAlign' => array() );
foreach( $parts as $part ) {
list( $magicName, $value ) = $mwArray->matchVariableStartToEnd( $part );
- if ( isset( $paramMap[$magicName] ) ) {
+ $validated = false;
+ if( isset( $paramMap[$magicName] ) ) {
list( $type, $paramName ) = $paramMap[$magicName];
- $params[$type][$paramName] = $value;
-
+
// Special case; width and height come in one variable together
if( $type == 'handler' && $paramName == 'width' ) {
$m = array();
- if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $value, $m ) ) {
- $params[$type]['width'] = intval( $m[1] );
- $params[$type]['height'] = intval( $m[2] );
+ # (bug 13500) In both cases (width/height and width only),
+ # permit trailing "px" for backward compatibility.
+ if ( preg_match( '/^([0-9]*)x([0-9]*)\s*(?:px)?\s*$/', $value, $m ) ) {
+ $width = intval( $m[1] );
+ $height = intval( $m[2] );
+ if ( $handler->validateParam( 'width', $width ) ) {
+ $params[$type]['width'] = $width;
+ $validated = true;
+ }
+ if ( $handler->validateParam( 'height', $height ) ) {
+ $params[$type]['height'] = $height;
+ $validated = true;
+ }
+ } elseif ( preg_match( '/^[0-9]*\s*(?:px)?\s*$/', $value ) ) {
+ $width = intval( $value );
+ if ( $handler->validateParam( 'width', $width ) ) {
+ $params[$type]['width'] = $width;
+ $validated = true;
+ }
+ } // else no validation -- bug 13436
+ } else {
+ if ( $type == 'handler' ) {
+ # Validate handler parameter
+ $validated = $handler->validateParam( $paramName, $value );
} else {
- $params[$type]['width'] = intval( $value );
+ # Validate internal parameters
+ switch( $paramName ) {
+ case "manualthumb":
+ /// @fixme - possibly check validity here?
+ /// downstream behavior seems odd with missing manual thumbs.
+ $validated = true;
+ break;
+ default:
+ // Most other things appear to be empty or numeric...
+ $validated = ( $value === false || is_numeric( trim( $value ) ) );
+ }
+ }
+
+ if ( $validated ) {
+ $params[$type][$paramName] = $value;
}
}
- } else {
+ }
+ if ( !$validated ) {
$caption = $part;
}
}
$params['frame']['valign'] = key( $params['vertAlign'] );
}
- # Validate the handler parameters
- if ( $handler ) {
- foreach ( $params['handler'] as $name => $value ) {
- if ( !$handler->validateParam( $name, $value ) ) {
- unset( $params['handler'][$name] );
- }
- }
- }
-
# Strip bad stuff out of the alt text
$alt = $this->replaceLinkHoldersText( $caption );
break;
} else {
$out .= call_user_func( $callback, substr( $s, $i, $markerStart - $i ) );
- $markerEnd = strpos( $s, $this->mMarkerSuffix, $markerStart );
+ $markerEnd = strpos( $s, self::MARKER_SUFFIX, $markerStart );
if ( $markerEnd === false ) {
$out .= substr( $s, $markerStart );
break;
} else {
- $markerEnd += strlen( $this->mMarkerSuffix );
+ $markerEnd += strlen( self::MARKER_SUFFIX );
$out .= substr( $s, $markerStart, $markerEnd - $markerStart );
$i = $markerEnd;
}