Page MenuHomePhabricator

Remove — at least increase — the "template expansion depth limit"
Open, Needs TriagePublic


Sometimes, on Wikipedia, a limit with a barbar name gives a blocking error: "template expansion depth limit".

This prevents us from making the templates we want. Because of this:

  1. Sometimes we leave incorrect presentation.
  2. Sometimes we write template wikicode more complicated, more repetitive or less efficient.
  3. ...

It would be nice to remove this technical limit. At least, as long as this limit is not removed, increasing it would be nice.

Thank you.


Event Timeline

Nnemo raised the priority of this task from to Needs Triage.
Nnemo updated the task description. (Show Details)
Nnemo added a project: MediaWiki-General.
Nnemo added a subscriber: Nnemo.
Nnemo updated the task description. (Show Details)
Nnemo set Security to None.

IIRC the reason it's 40 is because at the time it was introduced, xdebug would raise a fatal error when the PHP stack depth exceeded 100. Expansion required 2 PHP stack frames for every expansion level, so a limit of 40 would require 80 PHP stack frames, leaving 20 for the parser's caller.

We haven't used xdebug for a long time. HHVM has the runtime option VMStackElms which is 16384 by default, which seems to be a slot count which is incremented by a few for each recursion level, depending on the argument count.

I tested the new effective limit with eval.php as follows:

function test($n) {
  global $wgParser;
  $opts = new ParserOptions;
  $text = str_repeat('{{#if:|', $n) . str_repeat(' }}', $n);
  var_dump($wgParser->parse($text, Title::newMainPage(), $opts)->getLimitReportData()['limitreport-expansiondepth']);

$wgMaxPPExpandDepth = 1e8;
for ( $i = 0; $i < 800; $i++) {

This terminated with a fatal error at an expansion depth of 166. So with the default VMStackElms, we actually can't raise the limit by very much.

The expansion depth at which it terminates depends sensitively on whether parser functions are called, and how much stack space the parser functions use. If the conditional part of the #if is recursive, i.e. {{#if:{{#if:{{#if:... then it gets up to a depth of 240. There are probably test cases where termination happens at a level much lower than 166.