From 2c76c39737081017e99760d4d3dd11f79461370a Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Tue, 25 Mar 2008 04:26:58 +0000 Subject: [PATCH] Stack depth limit for expand() --- includes/DefaultSettings.php | 3 ++- includes/ParserOptions.php | 4 +++- includes/Preprocessor_DOM.php | 7 +++++++ includes/Preprocessor_Hash.php | 5 +++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 6d155041a3..3abd7336da 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -920,6 +920,7 @@ $wgMaxPPNodeCount = 1000000; # A complexity limit on template expansion * stop the parser before it hits the xdebug limit. */ $wgMaxTemplateDepth = 40; +$wgMaxPPExpandDepth = 40; $wgExtraSubtitle = ''; $wgSiteSupportPage = ''; # A page where you users can receive donations @@ -2961,4 +2962,4 @@ $wgPagePropLinkInvalidations = array( * Maximum number of links to a redirect page listed on * Special:Whatlinkshere/RedirectDestination */ -$wgMaxRedirectLinksRetrieved = 500; \ No newline at end of file +$wgMaxRedirectLinksRetrieved = 500; diff --git a/includes/ParserOptions.php b/includes/ParserOptions.php index 7be42abf38..a9c031a4d5 100644 --- a/includes/ParserOptions.php +++ b/includes/ParserOptions.php @@ -23,6 +23,7 @@ class ParserOptions var $mTargetLanguage; # Overrides above setting with arbitrary language var $mMaxIncludeSize; # Maximum size of template expansions, in bytes var $mMaxPPNodeCount; # Maximum number of nodes touched by PPFrame::expand() + var $mMaxPPExpandDepth; # Maximum recursion depth in PPFrame::expand() var $mMaxTemplateDepth; # Maximum recursion depth for templates within templates var $mRemoveComments; # Remove HTML comments. ONLY APPLIES TO PREPROCESS OPERATIONS var $mTemplateCallback; # Callback for template fetching @@ -107,7 +108,7 @@ class ParserOptions function initialiseFromUser( $userInput ) { global $wgUseTeX, $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages; global $wgAllowExternalImagesFrom, $wgAllowSpecialInclusion, $wgMaxArticleSize; - global $wgMaxPPNodeCount, $wgMaxTemplateDepth; + global $wgMaxPPNodeCount, $wgMaxTemplateDepth, $wgMaxPPExpandDepth; $fname = 'ParserOptions::initialiseFromUser'; wfProfileIn( $fname ); if ( !$userInput ) { @@ -138,6 +139,7 @@ class ParserOptions $this->mTargetLanguage = null; // default depends on InterfaceMessage setting $this->mMaxIncludeSize = $wgMaxArticleSize * 1024; $this->mMaxPPNodeCount = $wgMaxPPNodeCount; + $this->mMaxPPExpandDepth = $wgMaxPPExpandDepth; $this->mMaxTemplateDepth = $wgMaxTemplateDepth; $this->mRemoveComments = true; $this->mTemplateCallback = array( 'Parser', 'statelessFetchTemplate' ); diff --git a/includes/Preprocessor_DOM.php b/includes/Preprocessor_DOM.php index f476b958f7..f17d70430b 100644 --- a/includes/Preprocessor_DOM.php +++ b/includes/Preprocessor_DOM.php @@ -811,6 +811,7 @@ class PPFrame_DOM implements PPFrame { } function expand( $root, $flags = 0 ) { + static $depth = 0; if ( is_string( $root ) ) { return $root; } @@ -820,6 +821,11 @@ class PPFrame_DOM implements PPFrame { return 'Node-count limit exceeded'; } + if ( $depth > $this->parser->mOptions->mMaxPPExpandDepth ) { + return 'Expansion depth limit exceeded'; + } + ++$depth; + if ( $root instanceof PPNode_DOM ) { $root = $root->node; } @@ -1006,6 +1012,7 @@ class PPFrame_DOM implements PPFrame { } } } + --$depth; return $outStack[0]; } diff --git a/includes/Preprocessor_Hash.php b/includes/Preprocessor_Hash.php index 64ed8eb3c0..85e152cb9c 100644 --- a/includes/Preprocessor_Hash.php +++ b/includes/Preprocessor_Hash.php @@ -804,6 +804,10 @@ class PPFrame_Hash implements PPFrame { { return 'Node-count limit exceeded'; } + if ( $depth > $this->parser->mOptions->mMaxPPExpandDepth ) { + return 'Expansion depth limit exceeded'; + } + ++$depth; $outStack = array( '', '' ); $iteratorStack = array( false, $root ); @@ -956,6 +960,7 @@ class PPFrame_Hash implements PPFrame { } } } + --$depth; return $outStack[0]; } -- 2.20.1