Merge pull request #209 from smarden1/pr/even_triple_braces
Uneven braces in triples are incorrectly swallowing a character [repost of 208]
This commit is contained in:
+33
-12
@@ -84,6 +84,8 @@ class Mustache_Tokenizer
|
|||||||
/**
|
/**
|
||||||
* Scan and tokenize template source.
|
* Scan and tokenize template source.
|
||||||
*
|
*
|
||||||
|
* @throws Mustache_Exception_SyntaxException when mismatched section tags are encountered.
|
||||||
|
*
|
||||||
* @param string $text Mustache template source to tokenize
|
* @param string $text Mustache template source to tokenize
|
||||||
* @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null)
|
* @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null)
|
||||||
*
|
*
|
||||||
@@ -151,7 +153,7 @@ class Mustache_Tokenizer
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if ($this->tagChange($this->ctag, $this->ctagLen, $text, $i)) {
|
if ($this->tagChange($this->ctag, $this->ctagLen, $text, $i)) {
|
||||||
$this->tokens[] = array(
|
$token = array(
|
||||||
self::TYPE => $this->tagType,
|
self::TYPE => $this->tagType,
|
||||||
self::NAME => trim($this->buffer),
|
self::NAME => trim($this->buffer),
|
||||||
self::OTAG => $this->otag,
|
self::OTAG => $this->otag,
|
||||||
@@ -160,20 +162,39 @@ class Mustache_Tokenizer
|
|||||||
self::INDEX => ($this->tagType === self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen
|
self::INDEX => ($this->tagType === self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($this->tagType === self::T_UNESCAPED) {
|
||||||
|
// Clean up `{{{ tripleStache }}}` style tokens.
|
||||||
|
if ($this->ctag === '}}') {
|
||||||
|
if (($i+2 < $len) && $text[$i + 2] === '}') {
|
||||||
|
$i++;
|
||||||
|
} else {
|
||||||
|
$msg = sprintf(
|
||||||
|
'Uneven closing tag encountered: on line %d',
|
||||||
|
$token[self::LINE]
|
||||||
|
);
|
||||||
|
|
||||||
|
throw new Mustache_Exception_SyntaxException($msg, $token);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$lastName = $token[self::NAME];
|
||||||
|
if (substr($lastName, -1) === '}') {
|
||||||
|
$token[self::NAME] = trim(substr($lastName, 0, -1));
|
||||||
|
} else {
|
||||||
|
$msg = sprintf(
|
||||||
|
'Uneven closing tag encountered: %s on line %d',
|
||||||
|
substr($lastName, -1),
|
||||||
|
$token[self::LINE]
|
||||||
|
);
|
||||||
|
|
||||||
|
throw new Mustache_Exception_SyntaxException($msg, $token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->buffer = '';
|
$this->buffer = '';
|
||||||
$i += $this->ctagLen - 1;
|
$i += $this->ctagLen - 1;
|
||||||
$this->state = self::IN_TEXT;
|
$this->state = self::IN_TEXT;
|
||||||
if ($this->tagType === self::T_UNESCAPED) {
|
$this->tokens[] = $token;
|
||||||
if ($this->ctag === '}}') {
|
|
||||||
$i++;
|
|
||||||
} else {
|
|
||||||
// Clean up `{{{ tripleStache }}}` style tokens.
|
|
||||||
$lastName = $this->tokens[count($this->tokens) - 1][self::NAME];
|
|
||||||
if (substr($lastName, -1) === '}') {
|
|
||||||
$this->tokens[count($this->tokens) - 1][self::NAME] = trim(substr($lastName, 0, -1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$this->buffer .= $text[$i];
|
$this->buffer .= $text[$i];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,28 @@ class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
|
|||||||
$this->assertSame($expected, $tokenizer->scan($text, $delimiters));
|
$this->assertSame($expected, $tokenizer->scan($text, $delimiters));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Mustache_Exception_SyntaxException
|
||||||
|
*/
|
||||||
|
public function testUnevenBracesThrowExceptions()
|
||||||
|
{
|
||||||
|
$tokenizer = new Mustache_Tokenizer;
|
||||||
|
|
||||||
|
$text = "{{{ name }}";
|
||||||
|
$tokenizer->scan($text, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Mustache_Exception_SyntaxException
|
||||||
|
*/
|
||||||
|
public function testUnevenBracesWithCustomDelimiterThrowExceptions()
|
||||||
|
{
|
||||||
|
$tokenizer = new Mustache_Tokenizer;
|
||||||
|
|
||||||
|
$text = "<%{ name %>";
|
||||||
|
$tokenizer->scan($text, "<% %>");
|
||||||
|
}
|
||||||
|
|
||||||
public function getTokens()
|
public function getTokens()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
@@ -188,6 +210,69 @@ class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// custom delimiters don't swallow the next character, even if it is a }, }}}, or the same delimiter
|
||||||
|
array(
|
||||||
|
"<% a %>} <% b %>%> <% c %>}}}",
|
||||||
|
"<% %>",
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||||
|
Mustache_Tokenizer::NAME => 'a',
|
||||||
|
Mustache_Tokenizer::OTAG => '<%',
|
||||||
|
Mustache_Tokenizer::CTAG => '%>',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 7,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::VALUE => "} ",
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||||
|
Mustache_Tokenizer::NAME => 'b',
|
||||||
|
Mustache_Tokenizer::OTAG => '<%',
|
||||||
|
Mustache_Tokenizer::CTAG => '%>',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 16,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::VALUE => "%> ",
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||||
|
Mustache_Tokenizer::NAME => 'c',
|
||||||
|
Mustache_Tokenizer::OTAG => '<%',
|
||||||
|
Mustache_Tokenizer::CTAG => '%>',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 26,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::VALUE => "}}}",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
// unescaped custom delimiters are properly parsed
|
||||||
|
array(
|
||||||
|
"<%{ a }%>",
|
||||||
|
"<% %>",
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
|
||||||
|
Mustache_Tokenizer::NAME => 'a',
|
||||||
|
Mustache_Tokenizer::OTAG => '<%',
|
||||||
|
Mustache_Tokenizer::CTAG => '%>',
|
||||||
|
Mustache_Tokenizer::LINE => 0,
|
||||||
|
Mustache_Tokenizer::INDEX => 9,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user