Skip to content

Commit

Permalink
fixed negative number lexing
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed Oct 14, 2014
1 parent b5f0742 commit bf541bf
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
* 1.16.2 (2014-XX-XX)

* fixed lexing of negative numbers
* fixed macros when using an argument named like a PHP super global (like GET or POST)
* fixed date_modify when working with DateTimeImmutable
* optimized for loops
Expand Down
22 changes: 11 additions & 11 deletions lib/Twig/Lexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Twig_Lexer implements Twig_LexerInterface
const STATE_INTERPOLATION = 4;

const REGEX_NAME = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A';
const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A';
const REGEX_NUMBER = '/\-?[0-9]+(?:\.[0-9]+)?/A';
const REGEX_STRING = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As';
const REGEX_DQ_STRING_DELIM = '/"/A';
const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As';
Expand Down Expand Up @@ -228,8 +228,17 @@ protected function lexExpression()
}
}

// numbers
if (preg_match(self::REGEX_NUMBER, $this->code, $match, null, $this->cursor)) {
$number = (float) $match[0]; // floats
if (ctype_digit($match[0]) && $number <= PHP_INT_MAX) {
$number = (int) $match[0]; // integers lower than the maximum
}
$this->pushToken(Twig_Token::NUMBER_TYPE, $number);
$this->moveCursor($match[0]);
}
// operators
if (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) {
elseif (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) {
$this->pushToken(Twig_Token::OPERATOR_TYPE, preg_replace('/\s+/', ' ', $match[0]));
$this->moveCursor($match[0]);
}
Expand All @@ -238,15 +247,6 @@ protected function lexExpression()
$this->pushToken(Twig_Token::NAME_TYPE, $match[0]);
$this->moveCursor($match[0]);
}
// numbers
elseif (preg_match(self::REGEX_NUMBER, $this->code, $match, null, $this->cursor)) {
$number = (float) $match[0]; // floats
if (ctype_digit($match[0]) && $number <= PHP_INT_MAX) {
$number = (int) $match[0]; // integers lower than the maximum
}
$this->pushToken(Twig_Token::NUMBER_TYPE, $number);
$this->moveCursor($match[0]);
}
// punctuation
elseif (false !== strpos(self::PUNCTUATION, $this->code[$this->cursor])) {
// opening bracket
Expand Down
13 changes: 13 additions & 0 deletions test/Twig/Tests/Fixtures/expressions/negative_numbers.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--TEST--
Twig manages negative numbers correctly
--TEMPLATE--
{% import _self as macros %}
{{ macros.negative_number1() }}
{{ macros.negative_number2() }}
{% macro negative_number1(nb=-1) %}{{ nb }}{% endmacro %}
{% macro negative_number2(nb = -1) %}{{ nb }}{% endmacro %}
--DATA--
return array()
--EXPECT--
-1
-1
17 changes: 17 additions & 0 deletions test/Twig/Tests/LexerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,23 @@ public function testOperatorEndingWithALetterAtTheEndOfALine()
$stream->expect(Twig_Token::OPERATOR_TYPE, 'and');
}

public function testNegativeNumbers()
{
$template = "{{ -3 }}{{ 1 - 2 }}";

$lexer = new Twig_Lexer(new Twig_Environment());
$stream = $lexer->tokenize($template);
$stream->expect(Twig_Token::VAR_START_TYPE);
$stream->expect(Twig_Token::NUMBER_TYPE, -3);
$stream->expect(Twig_Token::VAR_END_TYPE);

$stream->expect(Twig_Token::VAR_START_TYPE);
$stream->expect(Twig_Token::NUMBER_TYPE, 1);
$stream->expect(Twig_Token::OPERATOR_TYPE, '-');
$stream->expect(Twig_Token::NUMBER_TYPE, 2);
$stream->expect(Twig_Token::VAR_END_TYPE);
}

/**
* @expectedException Twig_Error_Syntax
* @expectedExceptionMessage Unclosed "variable" at line 3
Expand Down

0 comments on commit bf541bf

Please sign in to comment.