From: fabien Date: Sat, 28 Nov 2009 11:25:56 +0000 (+0000) Subject: fixed a bug when a literal '\n' were present in a template text X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=cd9ca8374c24bbaf96aebbcd7a30177129bccc0c;p=konrad%2Ftwig.git fixed a bug when a literal '\n' were present in a template text git-svn-id: http://svn.twig-project.org/trunk@146 93ef8e89-cb99-4229-a87c-7fa0fa45744b --- diff --git a/CHANGELOG b/CHANGELOG index 6811b4e..01e8629 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ If you have custom loaders, you MUST upgrade them for this release: The Twig_Loader base class has been removed, and the Twig_LoaderInterface has also been changed (see the source code for more information or the documentation). + * fixed a bug when a literal '\n' were present in a template text * refactored loaders * 0.9.3 (2009-11-11) diff --git a/lib/Twig/Compiler.php b/lib/Twig/Compiler.php index aba6004..720f9b0 100644 --- a/lib/Twig/Compiler.php +++ b/lib/Twig/Compiler.php @@ -113,7 +113,7 @@ class Twig_Compiler implements Twig_CompilerInterface */ public function string($value) { - $this->source .= sprintf('"%s"', str_replace('\\\n', "\n", addcslashes($value, "\t\"\$\\"))); + $this->source .= sprintf('"%s"', addcslashes($value, "\t\"\$\\")); return $this; } diff --git a/lib/Twig/Lexer.php b/lib/Twig/Lexer.php index ad1b3a7..fa6b082 100644 --- a/lib/Twig/Lexer.php +++ b/lib/Twig/Lexer.php @@ -29,6 +29,8 @@ class Twig_Lexer implements Twig_LexerInterface protected $env; protected $options; + const LINE_DELIMITER = ''; + const POSITION_DATA = 0; const POSITION_BLOCK = 1; const POSITION_VAR = 2; @@ -59,7 +61,7 @@ class Twig_Lexer implements Twig_LexerInterface */ public function tokenize($code, $filename = 'n/a') { - $this->code = preg_replace('/(\r\n|\r|\n)/', '\n', $code); + $this->code = preg_replace('/(\r\n|\r|\n)/', self::LINE_DELIMITER, $code); $this->filename = $filename; $this->cursor = 0; $this->lineno = 1; @@ -153,7 +155,7 @@ class Twig_Lexer implements Twig_LexerInterface // as simple text token if (!preg_match('/(.*?)('.preg_quote($this->options['tag_comment'][0], '/').'|'.preg_quote($this->options['tag_variable'][0], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')/A', $this->code, $match, null, $this->cursor)) { - $rv = new Twig_Token(Twig_Token::TEXT_TYPE, substr($this->code, $this->cursor), $this->lineno); + $rv = new Twig_Token(Twig_Token::TEXT_TYPE, $this->fixNewLines(substr($this->code, $this->cursor)), $this->lineno); $this->cursor = $this->end; return $rv; @@ -162,8 +164,8 @@ class Twig_Lexer implements Twig_LexerInterface // update the lineno on the instance $lineno = $this->lineno; - $this->cursor += strlen($match[0]); - $this->lineno += substr_count($match[0], '\n'); + $this->moveCursor($match[0]); + $this->moveLineNo($match[0]); // array of tokens $result = array(); @@ -172,8 +174,8 @@ class Twig_Lexer implements Twig_LexerInterface $text = $match[1]; if (!empty($text)) { - $result[] = new Twig_Token(Twig_Token::TEXT_TYPE, $text, $lineno); - $lineno += substr_count($text, '\n'); + $result[] = new Twig_Token(Twig_Token::TEXT_TYPE, $this->fixNewLines($text), $lineno); + $lineno += substr_count($text, self::LINE_DELIMITER); } $token = $match[2]; @@ -184,17 +186,17 @@ class Twig_Lexer implements Twig_LexerInterface { throw new Twig_SyntaxError('unclosed comment', $this->lineno, $this->filename); } - $this->cursor += strlen($match[0]); - $this->lineno += substr_count($match[0], '\n'); + $this->moveCursor($match[0]); + $this->moveLineNo($match[0]); break; case $this->options['tag_block'][0]: // raw data? if (preg_match('/\s*raw\s*'.preg_quote($this->options['tag_block'][1], '/').'(.*?)'.preg_quote($this->options['tag_block'][0], '/').'\s*endraw\s*'.preg_quote($this->options['tag_block'][1], '/').'/A', $this->code, $match, null, $this->cursor)) { - $result[] = new Twig_Token(Twig_Token::TEXT_TYPE, $match[1], $lineno); - $this->cursor += strlen($match[0]); - $this->lineno += substr_count($match[0], '\n'); + $result[] = new Twig_Token(Twig_Token::TEXT_TYPE, $this->fixNewLines($match[1]), $lineno); + $this->moveCursor($match[0]); + $this->moveLineNo($match[0]); $this->position = self::POSITION_DATA; } else @@ -218,8 +220,8 @@ class Twig_Lexer implements Twig_LexerInterface if (preg_match('/\s*'.preg_quote($this->options['tag_block'][1], '/').'/A', $this->code, $match, null, $this->cursor)) { $lineno = $this->lineno; - $this->cursor += strlen($match[0]); - $this->lineno += substr_count($match[0], '\n'); + $this->moveCursor($match[0]); + $this->moveLineNo($match[0]); $this->position = self::POSITION_DATA; return new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $lineno); @@ -233,8 +235,8 @@ class Twig_Lexer implements Twig_LexerInterface if (preg_match('/\s*'.preg_quote($this->options['tag_variable'][1], '/').'/A', $this->code, $match, null, $this->cursor)) { $lineno = $this->lineno; - $this->cursor += strlen($match[0]); - $this->lineno += substr_count($match[0], '\n'); + $this->moveCursor($match[0]); + $this->moveLineNo($match[0]); $this->position = self::POSITION_DATA; return new Twig_Token(Twig_Token::VAR_END_TYPE, '', $lineno); @@ -250,8 +252,8 @@ class Twig_Lexer implements Twig_LexerInterface // whitespace while (preg_match('/\s+/A', $this->code, $match, null, $this->cursor)) { - $this->cursor += strlen($match[0]); - $this->lineno += substr_count($match[0], '\n'); + $this->moveCursor($match[0]); + $this->moveLineNo($match[0]); } // sanity check @@ -263,21 +265,21 @@ class Twig_Lexer implements Twig_LexerInterface // first parse operators if (preg_match(self::REGEX_OPERATOR, $this->code, $match, null, $this->cursor)) { - $this->cursor += strlen($match[0]); + $this->moveCursor($match[0]); return new Twig_Token(Twig_Token::OPERATOR_TYPE, $match[0], $this->lineno); } // now names else if (preg_match(self::REGEX_NAME, $this->code, $match, null, $this->cursor)) { - $this->cursor += strlen($match[0]); + $this->moveCursor($match[0]); return new Twig_Token(Twig_Token::NAME_TYPE, $match[0], $this->lineno); } // then numbers else if (preg_match(self::REGEX_NUMBER, $this->code, $match, null, $this->cursor)) { - $this->cursor += strlen($match[0]); + $this->moveCursor($match[0]); $value = (float)$match[0]; if ((int)$value === $value) { @@ -289,8 +291,8 @@ class Twig_Lexer implements Twig_LexerInterface // and finally strings else if (preg_match(self::REGEX_STRING, $this->code, $match, null, $this->cursor)) { - $this->cursor += strlen($match[0]); - $this->lineno += substr_count($match[0], '\n'); + $this->moveCursor($match[0]); + $this->moveLineNo($match[0]); $value = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2)); return new Twig_Token(Twig_Token::STRING_TYPE, $value, $this->lineno); @@ -299,4 +301,19 @@ class Twig_Lexer implements Twig_LexerInterface // unlexable throw new Twig_SyntaxError(sprintf("Unexpected character '%s'", $this->code[$this->cursor]), $this->lineno, $this->filename); } + + protected function moveLineNo($text) + { + $this->lineno += substr_count($text, self::LINE_DELIMITER); + } + + protected function moveCursor($text) + { + $this->cursor += strlen($text); + } + + protected function fixNewLines($text) + { + return str_replace(self::LINE_DELIMITER, "\n", $text); + } } diff --git a/lib/Twig/TokenStream.php b/lib/Twig/TokenStream.php index cae0be9..b14165e 100644 --- a/lib/Twig/TokenStream.php +++ b/lib/Twig/TokenStream.php @@ -69,10 +69,10 @@ class Twig_TokenStream Twig_Token::BLOCK_END_TYPE === $this->current->getType() && Twig_Token::TEXT_TYPE === $token->getType() && $token->getValue() && - '\n' === substr($token->getValue(), 0, 2) + "\n" === substr($token->getValue(), 0, 1) ) { - $value = substr($token->getValue(), 2); + $value = substr($token->getValue(), 1); if (!$value) {