$wgMaxTocLevel = 999;
/**
- * A complexity limit on template expansion
+ * A complexity limit on template expansion: the maximum number of nodes visited
+ * by PPFrame::expand()
*/
$wgMaxPPNodeCount = 1000000;
+/**
+ * A complexity limit on template expansion: the maximum number of nodes
+ * generated by Preprocessor::preprocessToObj()
+ */
+$wgMaxGeneratedPPNodeCount = 1000000;
+
+
/**
* Maximum recursion depth for templates within templates.
* The current parser adds two levels to the PHP call stack for each template,
var $mLinkHolders;
var $mLinkID;
- var $mIncludeSizes, $mPPNodeCount, $mHighestExpansionDepth, $mDefaultSort;
+ var $mIncludeSizes, $mPPNodeCount, $mGeneratedPPNodeCount, $mHighestExpansionDepth;
+ var $mDefaultSort;
var $mTplExpandCache; # empty-frame expansion cache
var $mTplRedirCache, $mTplDomCache, $mHeadings, $mDoubleUnderscores;
var $mExpensiveFunctionCount; # number of expensive parser function calls
'arg' => 0,
);
$this->mPPNodeCount = 0;
+ $this->mGeneratedPPNodeCount = 0;
$this->mHighestExpansionDepth = 0;
$this->mDefaultSort = false;
$this->mHeadings = array();
$PFreport = "Expensive parser function count: {$this->mExpensiveFunctionCount}/{$this->mOptions->getExpensiveParserFunctionLimit()}\n";
$limitReport =
"NewPP limit report\n" .
- "Preprocessor node count: {$this->mPPNodeCount}/{$this->mOptions->getMaxPPNodeCount()}\n" .
+ "Preprocessor visited node count: {$this->mPPNodeCount}/{$this->mOptions->getMaxPPNodeCount()}\n" .
+ "Preprocessor generated node count: " .
+ "{$this->mGeneratedPPNodeCount}/{$this->mOptions->getMaxGeneratedPPNodeCount()}\n" .
"Post-expand include size: {$this->mIncludeSizes['post-expand']}/$max bytes\n" .
"Template argument size: {$this->mIncludeSizes['arg']}/$max bytes\n".
"Highest expansion depth: {$this->mHighestExpansionDepth}/{$this->mOptions->getMaxPPExpandDepth()}\n".
* Maximum number of nodes touched by PPFrame::expand()
*/
var $mMaxPPNodeCount;
+
+ /**
+ * Maximum number of nodes generated by Preprocessor::preprocessToObj()
+ */
+ var $mMaxGeneratedPPNodeCount;
/**
* Maximum recursion depth in PPFrame::expand()
function getTargetLanguage() { return $this->mTargetLanguage; }
function getMaxIncludeSize() { return $this->mMaxIncludeSize; }
function getMaxPPNodeCount() { return $this->mMaxPPNodeCount; }
+ function getMaxGeneratedPPNodeCount() { return $this->mMaxGeneratedPPNodeCount; }
function getMaxPPExpandDepth() { return $this->mMaxPPExpandDepth; }
function getMaxTemplateDepth() { return $this->mMaxTemplateDepth; }
/* @since 1.20 */
function setTargetLanguage( $x ) { return wfSetVar( $this->mTargetLanguage, $x, true ); }
function setMaxIncludeSize( $x ) { return wfSetVar( $this->mMaxIncludeSize, $x ); }
function setMaxPPNodeCount( $x ) { return wfSetVar( $this->mMaxPPNodeCount, $x ); }
+ function setMaxGeneratedPPNodeCount( $x ) { return wfSetVar( $this->mMaxGeneratedPPNodeCount, $x ); }
function setMaxTemplateDepth( $x ) { return wfSetVar( $this->mMaxTemplateDepth, $x ); }
/* @since 1.20 */
function setExpensiveParserFunctionLimit( $x ) { return wfSetVar( $this->mExpensiveParserFunctionLimit, $x ); }
global $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages,
$wgAllowExternalImagesFrom, $wgEnableImageWhitelist, $wgAllowSpecialInclusion,
$wgMaxArticleSize, $wgMaxPPNodeCount, $wgMaxTemplateDepth, $wgMaxPPExpandDepth,
- $wgCleanSignatures, $wgExternalLinkTarget, $wgExpensiveParserFunctionLimit;
+ $wgCleanSignatures, $wgExternalLinkTarget, $wgExpensiveParserFunctionLimit,
+ $wgMaxGeneratedPPNodeCount;
wfProfileIn( __METHOD__ );
$this->mAllowSpecialInclusion = $wgAllowSpecialInclusion;
$this->mMaxIncludeSize = $wgMaxArticleSize * 1024;
$this->mMaxPPNodeCount = $wgMaxPPNodeCount;
+ $this->mMaxGeneratedPPNodeCount = $wgMaxGeneratedPPNodeCount;
$this->mMaxPPExpandDepth = $wgMaxPPExpandDepth;
$this->mMaxTemplateDepth = $wgMaxTemplateDepth;
$this->mExpensiveParserFunctionLimit = $wgExpensiveParserFunctionLimit;
}
}
+
+ // Fail if the number of elements exceeds acceptable limits
+ // Do not attempt to generate the DOM
+ $this->parser->mGeneratedPPNodeCount += substr_count( $xml, '<' );
+ $max = $this->parser->mOptions->getMaxGeneratedPPNodeCount();
+ if ( $this->parser->mGeneratedPPNodeCount > $max ) {
+ throw new MWException( __METHOD__.': generated node count limit exceeded' );
+ }
+
wfProfileIn( __METHOD__.'-loadXML' );
$dom = new DOMDocument;
wfSuppressWarnings();