summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Andreev <narf@devilix.net>2014-01-06 13:38:00 +0100
committerAndrey Andreev <narf@devilix.net>2014-01-06 13:38:00 +0100
commita9c7d18dc4ba53507d6e606221f06aa3fafeaa8e (patch)
treed48c6a9ee35dbedc484740ef9d1850a8f9677627
parent45549a2919892e31782fc4381d7db8c6f3293bcb (diff)
Fix #2237: Parser library failed if the same tag pair is used more than once within a template
(manually applying PR #2238 + updated unit tests)
-rw-r--r--system/libraries/Parser.php30
-rw-r--r--tests/codeigniter/libraries/Parser_test.php4
-rw-r--r--user_guide_src/source/changelog.rst1
3 files changed, 22 insertions, 13 deletions
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php
index c1f1ad73b..399131cdd 100644
--- a/system/libraries/Parser.php
+++ b/system/libraries/Parser.php
@@ -187,26 +187,34 @@ class CI_Parser {
*/
protected function _parse_pair($variable, $data, $string)
{
- if (FALSE === ($match = $this->_match_pair($string, $variable)))
+ if (FALSE === ($matches = $this->_match_pair($string, $variable)))
{
return $string;
}
$str = '';
- foreach ($data as $row)
+ $search = $replace = array();
+ foreach ($matches as $match)
{
- $temp = $match[1];
- foreach ($row as $key => $val)
+ $str = '';
+ foreach ($data as $row)
{
- $temp = is_array($val)
+ $temp = $match[1];
+ foreach ($row as $key => $val)
+ {
+ $temp = is_array($val)
? $this->_parse_pair($key, $val, $temp)
: $this->_parse_single($key, $val, $temp);
+ }
+
+ $str .= $temp;
}
- $str .= $temp;
+ $search[] = $match[0];
+ $replace[] = $str;
}
- return str_replace($match[0], $str, $string);
+ return str_replace($search, $replace, $string);
}
// --------------------------------------------------------------------
@@ -214,14 +222,14 @@ class CI_Parser {
/**
* Matches a variable pair
*
- * @param string
- * @param string
+ * @param string $string
+ * @param string $variable
* @return mixed
*/
protected function _match_pair($string, $variable)
{
- return preg_match('|'.preg_quote($this->l_delim).$variable.preg_quote($this->r_delim).'(.+?)'.preg_quote($this->l_delim).'/'.$variable.preg_quote($this->r_delim).'|s',
- $string, $match)
+ return preg_match_all('|'.preg_quote($this->l_delim).$variable.preg_quote($this->r_delim).'(.+?)'.preg_quote($this->l_delim).'/'.$variable.preg_quote($this->r_delim).'|s',
+ $string, $match, PREG_SET_ORDER)
? $match : FALSE;
}
diff --git a/tests/codeigniter/libraries/Parser_test.php b/tests/codeigniter/libraries/Parser_test.php
index 394c22692..6e5c192dd 100644
--- a/tests/codeigniter/libraries/Parser_test.php
+++ b/tests/codeigniter/libraries/Parser_test.php
@@ -76,9 +76,9 @@ class Parser_test extends CI_TestCase {
)
);
- $template = "{title}\n{powers}{invisibility}\n{flying}{/powers}";
+ $template = "{title}\n{powers}{invisibility}\n{flying}{/powers}\nsecond:{powers} {invisibility} {flying}{/powers}";
- $this->assertEquals("Super Heroes\nyes\nno", $this->parser->parse_string($template, $data, TRUE));
+ $this->assertEquals("Super Heroes\nyes\nno\nsecond: yes no", $this->parser->parse_string($template, $data, TRUE));
}
// --------------------------------------------------------------------
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 7cc27eb5a..6d0ceb6c3 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -631,6 +631,7 @@ Bug fixes for 3.0
- Fixed a bug - Redis :doc:`Caching <libraries/caching>` driver didn't handle connection failures properly.
- Fixed a bug (#2756) - :doc:`Database Class <database/index>` executed the MySQL-specific `SET SESSION sql_mode` query for all drivers when the 'stricton' option is set.
- Fixed a bug (#2579) - :doc:`Query Builder <database/query_builder>`s "no escape" functionality didn't work properly with query cache.
+- Fixed a bug (#2237) - :doc:`Parser Library <libraries/parser>` failed if the same tag pair is used more than once within a template.
Version 2.1.4
=============