Indefero

Indefero Commit Details


Date:2011-03-18 06:10:42 (13 years 9 months ago)
Author:Thomas Keller
Branch:develop, feature-issue_links, feature.better-home, feature.content-md5, feature.diff-whitespace, feature.download-md5, feature.issue-links, feature.issue-of-others, feature.issue-summary, feature.search-filter, feature.webrepos, feature.wiki-default-page, release-1.1, release-1.2, release-1.3
Commit:734ddda3636fbca636b5656e589ce0798a336763
Parents: 5f008a14f5e78513903e95073ab12c742e99c21a
Message:Fix issue 618 by returning the input unaltered in case PCRE still fails to evaluate it with the expanded backtrack limit.

Changes:

File differences

src/IDF/Template.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2011 CĂ©ondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* PHP sets the backtrack limit quite low, so some (harder to analyze) regexes may fail
* unexpectedly on large inputs or weird cornercases (see issue 618). Unfortunately this
* fix does not always work and the execution time gets bigger the bigger we set the limit,
* so in case PCRE fails to analyze the input string and preg_replace(_callback) returns NULL,
* we at least return the input string unaltered.
*
* @param $pattern The pattern
* @param $mixed Callback or replacement string
* @param $input The input
* @return The output
*/
function IDF_Template_safePregReplace($pattern, $mixed, $input)
{
$pcre_backtrack_limit = ini_get('pcre.backtrack_limit');
ini_set('pcre.backtrack_limit', 10000000);
if (is_string($mixed) && !function_exists($mixed))
$output = preg_replace($pattern, $mixed, $input);
else
$output = preg_replace_callback($pattern, $mixed, $input);
if ($output === null)
$output = $input;
ini_set('pcre.backtrack_limit', $pcre_backtrack_limit);
return $output;
}
src/IDF/Template/IssueComment.php
2222
2323
2424
25
2526
2627
2728
......
3435
3536
3637
37
38
39
40
41
4238
4339
4440
4541
4642
47
48
43
44
4945
5046
51
52
47
48
5349
5450
55
56
51
52
5753
5854
5955
6056
6157
6258
63
64
65
66
59
60
61
62
6763
6864
6965
......
7268
7369
7470
75
76
7771
7872
7973
......
10195
10296
10397
104
105
106
98
99
100
107101
108102
109103
......
138132
139133
140134
141
135
142136
143137
144138
......
170164
171165
172166
173
167
174168
175169
176170
# ***** END LICENSE BLOCK ***** */
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
Pluf::loadFunction('IDF_Template_safePregReplace');
/**
* Make the links to issues and commits.
function start($text, $request, $echo=true, $wordwrap=true, $esc=true, $autolink=true, $nl2br=false)
{
// 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;
$this->scm = IDF_Scm::get($request->project);
if ($esc) $text = Pluf_esc($text);
if ($autolink) {
$text = preg_replace('#([a-z]+://[^\s\(\)]+)#i',
'<a href="\1">\1</a>', $text);
$text = IDF_Template_safePregReplace('#([a-z]+://[^\s\(\)]+)#i',
'<a href="\1">\1</a>', $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);
} else {
return $text;
}
ini_set('pcre.backtrack_limit', $pcre_backtrack_limit);
}
/**
}
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]);
}
/**
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]);
}
/**
{
$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]));
}
src/IDF/Template/Markdown.php
2222
2323
2424
25
2526
2627
2728
......
3435
3536
3637
37
38
39
40
41
4238
4339
4440
......
4743
4844
4945
50
51
52
46
47
48
5349
5450
55
56
57
51
52
53
5854
59
60
61
55
56
57
6258
6359
64
65
6660
6761
6862
# ***** END LICENSE BLOCK ***** */
Pluf::loadFunction('Pluf_Text_MarkDown_parse');
Pluf::loadFunction('IDF_Template_safePregReplace');
/**
* Make the links to issues and commits.
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
// 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)

Archive Download the corresponding diff file

Page rendered in 0.08375s using 14 queries.