Skip to content

Commit

Permalink
[ExpressionLanguage] fixed issues when parsing postfix expressions
Browse files Browse the repository at this point in the history
Exception shall be thrown when parsing the following expressions:

foo."#", foo."bar", foo.**, foo.123

The original parser didn't throw exception for foo."#", foo.** and
foo.123

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a
  • Loading branch information
zerustech authored and fabpot committed Mar 17, 2015
1 parent 051c3de commit e504ebe
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 5 deletions.
18 changes: 13 additions & 5 deletions src/Symfony/Component/ExpressionLanguage/Parser.php
Expand Up @@ -314,12 +314,20 @@ public function parsePostfixExpression($node)
if (
$token->type !== Token::NAME_TYPE
&&
$token->type !== Token::NUMBER_TYPE
&&
// operators line "not" are valid method or property names
($token->type !== Token::OPERATOR_TYPE && preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A', $token->value))
// Operators like "not" and "matches" are valid method or property names,
//
// In other words, besides NAME_TYPE, OPERATOR_TYPE could also be parsed as a property or method.
// This is because operators are processed by the lexer prior to names. So "not" in "foo.not()" or "matches" in "foo.matches" will be recognized as an operator first.
// But in fact, "not" and "matches" in such expressions shall be parsed as method or property names.
//
// And this ONLY works if the operator consists of valid characters for a property or method name.
//
// Other types, such as STRING_TYPE and NUMBER_TYPE, can't be parsed as property nor method names.
//
// As a result, if $token is NOT an operator OR $token->value is NOT a valid property or method name, an exception shall be thrown.
($token->type !== Token::OPERATOR_TYPE || !preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A', $token->value))
) {
throw new SyntaxError('Expected name or number', $token->cursor);
throw new SyntaxError('Expected name', $token->cursor);
}

$arg = new Node\ConstantNode($token->value);
Expand Down
33 changes: 33 additions & 0 deletions src/Symfony/Component/ExpressionLanguage/Tests/ParserTest.php
Expand Up @@ -161,4 +161,37 @@ private function createGetAttrNode($node, $item, $type)
{
return new Node\GetAttrNode($node, new Node\ConstantNode($item), new Node\ArgumentsNode(), $type);
}

/**
* @dataProvider getInvalidPostfixData
* @expectedException \Symfony\Component\ExpressionLanguage\SyntaxError
*/
public function testParseWithInvalidPostfixData($expr, $names = array())
{
$lexer = new Lexer();
$parser = new Parser(array());
$parser->parse($lexer->tokenize($expr), $names);
}

public function getInvalidPostfixData()
{
return array(
array(
'foo."#"',
array('foo'),
),
array(
'foo."bar"',
array('foo'),
),
array(
'foo.**',
array('foo'),
),
array(
'foo.123',
array('foo'),
),
);
}
}

0 comments on commit e504ebe

Please sign in to comment.