Loading...
 
Skip to main content

Limited number of single nested plugins, which should not be limited

Status
Closed
Subject
Limited number of single nested plugins, which should not be limited
Version
17.x
8.x
Category
  • Consistency
  • Less than 30-minutes fix
Resolution status
Partially solved
Submitted by
edwinbennink
Volunteered to solve
Jonny Bradley
Lastmod by
drsassafras
Rating
(0)
Description

When you place more then 167 nested plugins of for example DIV (so not nested in nested in nested..., just plugins with only one nested plugin each). It will eventually not parse the plugin anymore.

Wikicode:

Copy to clipboard
. . . {DIV(id="test1")}test1{DIV(id="test2")}test2{DIV}{DIV} {DIV(id="test1")}test1{DIV(id="test2")}test2{DIV}{DIV} {DIV(id="test1")}test1{DIV(id="test2")}test2{DIV}{DIV} . . .


The result will be:

Copy to clipboard
test1 test2 . . . test1 test2 test1{DIV(id="test2")}test2{DIV} . . . test1{DIV(id="test2")}test2{DIV}


This is due to a counter (passes) within the PluginMatcher.php which is limited to 500. But I'm guessing this counter is meant to avoid 500 nested in nested in nested in nested...etc (which indeed make sense to me), but not that this keeps counting when you start a new plugin.

I think there should be some attention to the levels. It seems that level zero is the whole text and that level one is simply the detection of the plugin, level two is the detection of a nested plugin, level 3 is the detection of a nested in nested plugin etc.

I haven't figured it out completely, but I have found a workaround to make the counter count as espected. But this is again a workaround and a real solution is needed.

Edit: More info...it "goes wrong" when the performReplace function is called, which itself calls the getSubMatcher function again, which increases the level (for which I believe should not happen the first time it is called). Whithin the findMatches (which also calls the getSubMatcher) there is a test whether the $this->level is empty and if so, the passes-counter is restored to zero. This test is missing within performReplace, but should maybe also be added? The problem is then that the passes-counter should be also known by the other functions. Shouldn't be difficult to do.

Solution

A preference was added to tiki in r62772 that allows one to increase the maximum number of passes, thus increasing the number of passes.

I've added the $this-level-is empty test within the performReplace function. To do this I globally defined the passes variable.

Copy to clipboard
*** old//lib/core/WikiParser/PluginMatcher.php Sat Oct 1 20:18:38 2011 --- new//lib/core/WikiParser/PluginMatcher.php Wed May 9 10:41:13 2012 *************** *** 19,24 **** --- 19,26 ---- private $leftOpen = 0; + private $passes = 0; + public static function match( $text ) { $matcher = new self; *************** *** 32,37 **** --- 34,40 ---- { $sub = new self; $sub->level = $this->level + 1; + $sub->passes = $this->passes; $sub->text = $this->text; $sub->findMatches( $start, $end ); *************** *** 53,65 **** function findMatches( $start, $end ) { - static $passes; - if ($this->level === 0) { ! $passes = 0; } ! if (++$passes > 500) { return; } --- 56,66 ---- function findMatches( $start, $end ) { if ($this->level === 0) { ! $this->passes = 0; } ! if (++$this->passes > 500) { return; } *************** *** 115,121 **** $pos = $match->getEnd(); --$this->leftOpen; if (empty($this->level)) ! $passes = 0; break; } --- 116,122 ---- $pos = $match->getEnd(); --$this->leftOpen; if (empty($this->level)) ! $this->passes = 0; break; } *************** *** 270,275 **** --- 271,278 ---- $sub = $this->getSubMatcher( $start, $start + strlen( $string ) ); if ($sub->isComplete()) { $this->appendSubMatcher($sub); + if (empty($this->level)) + $this->passes = 0; } ksort( $this->ends );
Workaround

Because level one seem to be the detection of the plugin, the check when the counter (passes) should be restored to one, needs to be adjusted.

Change in line 58 in file <tikiroot>/lib/core/WikiParser/PluginMatcher.php:

Copy to clipboard
if ($this->level === 0) { $passes = 0; }


for:

Copy to clipboard
if ($this->level <= 1) { $passes = 0; }

Importance
5
Priority
25
Demonstrate Bug on Tiki 19+
Demonstrate Bug (older Tiki versions)
Ticket ID
4217
Created
Wednesday 09 May, 2012 08:04:11 UTC
by edwinbennink
LastModif
Sunday 28 May, 2017 00:25:31 UTC


Show PHP error messages