From 734ddda3636fbca636b5656e589ce0798a336763 Mon Sep 17 00:00:00 2001 From: Thomas Keller Date: Fri, 18 Mar 2011 12:10:42 +0100 Subject: [PATCH] Fix issue 618 by returning the input unaltered in case PCRE still fails to evaluate it with the expanded backtrack limit. --- src/IDF/Template.php | 51 +++++++++++++++++++++++++++++++ src/IDF/Template/IssueComment.php | 38 ++++++++++------------- src/IDF/Template/Markdown.php | 26 ++++++---------- 3 files changed, 77 insertions(+), 38 deletions(-) create mode 100644 src/IDF/Template.php diff --git a/src/IDF/Template.php b/src/IDF/Template.php new file mode 100644 index 0000000..b7b2668 --- /dev/null +++ b/src/IDF/Template.php @@ -0,0 +1,51 @@ +project = $request->project; $this->request = $request; $this->scm = IDF_Scm::get($request->project); if ($esc) $text = Pluf_esc($text); if ($autolink) { - $text = preg_replace('#([a-z]+://[^\s\(\)]+)#i', - '\1', $text); + $text = IDF_Template_safePregReplace('#([a-z]+://[^\s\(\)]+)#i', + '\1', $text); } if ($request->rights['hasIssuesAccess']) { - $text = preg_replace_callback('#((?:issue|bug|ticket)(s)?\s+|\s+\#)(\d+)(\#ic\d+)?(?(2)((?:[, \w]+(?:\s+\#)?)?\d+(?:\#ic\d+)?){0,})#im', - array($this, 'callbackIssues'), $text); + $text = IDF_Template_safePregReplace('#((?:issue|bug|ticket)(s)?\s+|\s+\#)(\d+)(\#ic\d+)?(?(2)((?:[, \w]+(?:\s+\#)?)?\d+(?:\#ic\d+)?){0,})#im', + array($this, 'callbackIssues'), $text); } if ($request->rights['hasReviewAccess']) { - $text = preg_replace_callback('#(reviews?\s+)(\d+(?:(?:\s+and|\s+or|,)\s+\d+)*)\b#i', - array($this, 'callbackReviews'), $text); + $text = IDF_Template_safePregReplace('#(reviews?\s+)(\d+(?:(?:\s+and|\s+or|,)\s+\d+)*)\b#i', + array($this, 'callbackReviews'), $text); } if ($request->rights['hasSourceAccess']) { $verbs = array('added', 'fixed', 'reverted', 'changed', 'removed'); $nouns = array('commit', 'commits', 'revision', 'revisions', 'rev', 'revs'); $prefix = implode(' in|', $verbs).' in' . '|'. implode('|', $nouns); - $text = preg_replace_callback('#((?:'.$prefix.')(?:\s+r?))([0-9a-f]{1,40}((?:\s+and|\s+or|,)\s+r?[0-9a-f]{1,40})*)\b#i', - array($this, 'callbackCommits'), $text); - $text = preg_replace_callback('=(src:)([^\s@#,\(\)\\\\]+(?:(\\\\)[\s@#][^\s@#,\(\)\\\\]+){0,})+(?:\@([^\s#,]+))(?:#(\d+))?=im', - array($this, 'callbackSource'), $text); + $text = IDF_Template_safePregReplace('#((?:'.$prefix.')(?:\s+r?))([0-9a-f]{1,40}((?:\s+and|\s+or|,)\s+r?[0-9a-f]{1,40})*)\b#i', + array($this, 'callbackCommits'), $text); + $text = IDF_Template_safePregReplace('=(src:)([^\s@#,\(\)\\\\]+(?:(\\\\)[\s@#][^\s@#,\(\)\\\\]+){0,})+(?:\@([^\s#,]+))(?:#(\d+))?=im', + array($this, 'callbackSource'), $text); } if ($wordwrap) $text = Pluf_Text::wrapHtml($text, 69, "\n"); if ($nl2br) $text = nl2br($text); @@ -72,8 +68,6 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag } else { return $text; } - - ini_set('pcre.backtrack_limit', $pcre_backtrack_limit); } /** @@ -101,9 +95,9 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag } return $m[0]; // not existing issue. } - return preg_replace_callback('#(\#)?(\d+)(\#ic\d+)?#', - array($this, 'callbackIssue'), - $m[0]); + return IDF_Template_safePregReplace('#(\#)?(\d+)(\#ic\d+)?#', + array($this, 'callbackIssue'), + $m[0]); } /** @@ -138,7 +132,7 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag return $m[1].call_user_func(array($this, 'callbackCommit'), array($m[2])); } // Multiple commits like 'commits 6e030e6, a25bfc1 and 3c094f8'. - return $m[1].preg_replace_callback('#\b[0-9a-f]{1,40}\b#i', array($this, 'callbackCommit'), $m[2]); + return $m[1].IDF_Template_safePregReplace('#\b[0-9a-f]{1,40}\b#i', array($this, 'callbackCommit'), $m[2]); } /** @@ -170,7 +164,7 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag { $keyword = rtrim($m[1]); if ('reviews' === $keyword) { - return $m[1].preg_replace_callback('#\b(\d+)\b#i', array($this, 'callbackReview'), $m[2]); + return $m[1].IDF_Template_safePregReplace('#\b(\d+)\b#i', array($this, 'callbackReview'), $m[2]); } else if ('review' === $keyword) { return $m[1].call_user_func(array($this, 'callbackReview'), array('', $m[2])); } diff --git a/src/IDF/Template/Markdown.php b/src/IDF/Template/Markdown.php index 9b33a06..2652719 100644 --- a/src/IDF/Template/Markdown.php +++ b/src/IDF/Template/Markdown.php @@ -22,6 +22,7 @@ # ***** END LICENSE BLOCK ***** */ Pluf::loadFunction('Pluf_Text_MarkDown_parse'); +Pluf::loadFunction('IDF_Template_safePregReplace'); /** * Make the links to issues and commits. @@ -34,11 +35,6 @@ class IDF_Template_Markdown extends Pluf_Template_Tag function start($text, $request) { - // PHP sets the backtrack limit quite low, so some regexes may - // fail unexpectedly on large inputs or weird cornercases (see issue 618) - $pcre_backtrack_limit = ini_get('pcre.backtrack_limit'); - ini_set('pcre.backtrack_limit', 10000000); - $this->project = $request->project; $this->request = $request; // Replace like in the issue text @@ -47,22 +43,20 @@ class IDF_Template_Markdown extends Pluf_Template_Tag // Replace [[[path/to/file.mdtext, commit]]] with embedding // the content of the file into the wki page if ($this->request->rights['hasSourceAccess']) { - $text = preg_replace_callback('#\[\[\[([^\,]+)(?:, ([^/]+))?\]\]\]#im', - array($this, 'callbackEmbeddedDoc'), - $text); + $text = IDF_Template_safePregReplace('#\[\[\[([^\,]+)(?:, ([^/]+))?\]\]\]#im', + array($this, 'callbackEmbeddedDoc'), + $text); } // Replace [Page]([[PageName]]) with corresponding link to the page, with link text being Page. - $text = preg_replace_callback('#\[([^\]]+)\]\(\[\[([A-Za-z0-9\-]+)\]\]\)#im', - array($this, 'callbackWikiPage'), - $text); + $text = IDF_Template_safePregReplace('#\[([^\]]+)\]\(\[\[([A-Za-z0-9\-]+)\]\]\)#im', + array($this, 'callbackWikiPage'), + $text); // Replace [[PageName]] with corresponding link to the page. - $text = preg_replace_callback('#\[\[([A-Za-z0-9\-]+)\]\]#im', - array($this, 'callbackWikiPageNoName'), - $text); + $text = IDF_Template_safePregReplace('#\[\[([A-Za-z0-9\-]+)\]\]#im', + array($this, 'callbackWikiPageNoName'), + $text); $filter = new IDF_Template_MarkdownPrefilter(); echo $filter->go(Pluf_Text_MarkDown_parse($text)); - - ini_set('pcre.backtrack_limit', $pcre_backtrack_limit); } function callbackWikiPageNoName($m)