From f1c0c05223b26d589d1ed7bdce9df2a245179f15 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 24 May 2013 09:19:57 +0200 Subject: Fix fatal error when xdebug.max_nesting_level was exceeded in rcube_washtml (#1489110) --- CHANGELOG | 1 + program/lib/Roundcube/rcube_washtml.php | 33 +++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b36788c36..138cdf522 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Fix fatal error when xdebug.max_nesting_level was exceeded in rcube_washtml (#1489110) - Fix PHP warning in html_table::set_row_attribs() in PHP 5.4 (#1489094) - Fix invalid option selected in default_font selector when font is unset (#1489112) - Fix displaying contact with ID divisible by 100 in sql addressbook (#1489121) diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php index 27dff9f48..a11371c61 100644 --- a/program/lib/Roundcube/rcube_washtml.php +++ b/program/lib/Roundcube/rcube_washtml.php @@ -140,6 +140,9 @@ class rcube_washtml /* Allowed HTML attributes */ private $_html_attribs = array(); + /* Max nesting level */ + private $max_nesting_level; + /** * Class constructor @@ -284,12 +287,26 @@ class rcube_washtml * It output only allowed tags with allowed attributes * and allowed inline styles */ - private function dumpHtml($node) + private function dumpHtml($node, $level = 0) { if (!$node->hasChildNodes()) { return ''; } + $level++; + + if ($this->max_nesting_level > 0 && $level == $this->max_nesting_level - 1) { + // log error message once + if (!$this->max_nesting_level_error) { + $this->max_nesting_level_error = true; + rcube::raise_error(array('code' => 500, 'type' => 'php', + 'line' => __LINE__, 'file' => __FILE__, + 'message' => "Maximum nesting level exceeded (xdebug.max_nesting_level={$this->max_nesting_level})"), + true, false); + } + return ''; + } + $node = $node->firstChild; $dump = ''; @@ -299,10 +316,10 @@ class rcube_washtml $tagName = strtolower($node->tagName); if ($callback = $this->handlers[$tagName]) { $dump .= call_user_func($callback, $tagName, - $this->wash_attribs($node), $this->dumpHtml($node), $this); + $this->wash_attribs($node), $this->dumpHtml($node, $level), $this); } else if (isset($this->_html_elements[$tagName])) { - $content = $this->dumpHtml($node); + $content = $this->dumpHtml($node, $level); $dump .= '<' . $tagName . $this->wash_attribs($node) . ($content != '' || isset($this->_block_elements[$tagName]) ? ">$content" : ' />'); } @@ -311,7 +328,7 @@ class rcube_washtml } else { $dump .= ''; - $dump .= $this->dumpHtml($node); // ignore tags not its content + $dump .= $this->dumpHtml($node, $level); // ignore tags not its content } break; @@ -324,14 +341,14 @@ class rcube_washtml break; case XML_HTML_DOCUMENT_NODE: - $dump .= $this->dumpHtml($node); + $dump .= $this->dumpHtml($node, $level); break; case XML_DOCUMENT_TYPE_NODE: break; default: - $dump . ''; + $dump .= ''; } } while($node = $node->nextSibling); @@ -358,6 +375,9 @@ class rcube_washtml $this->config['base_url'] = ''; } + // Detect max nesting level (for dumpHTML) (#1489110) + $this->max_nesting_level = (int) @ini_get('xdebug.max_nesting_level'); + @$node->loadHTML($html); return $this->dumpHtml($node); } @@ -405,6 +425,7 @@ class rcube_washtml rcube::raise_error(array('code' => 620, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__, 'message' => $errstr), true, false); + return ''; } -- cgit v1.2.3