Skip to content

Commit

Permalink
bug #24041 [ExpressionLanguage] throws an exception on calling uncall…
Browse files Browse the repository at this point in the history
…able method (fmata)

This PR was merged into the 2.7 branch.

Discussion
----------

[ExpressionLanguage] throws an exception on calling uncallable method

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

When we evaluate an expression, if a callable is incorrect (not exists or not accessible) a warning is printed.
This PR handles this case and throws a \RuntimeException when `is_callable()` returns `false` :

```php
$el = new ExpressionLanguage();
$el->evaluate('foo.myfunction()', array('foo' => new \stdClass()));
```

**Before:**
`Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'stdClass' does not have a method 'myfunction' in /home/.../src/Symfony/Component/ExpressionLanguage/Node/GetAttrNode.php on line 84`

**After:**
`Fatal error: Uncaught RuntimeException: Unable to call method "myfunction" of object "stdClass". in /home/.../src/Symfony/Component/ExpressionLanguage/Node/GetAttrNode.php:81`

Commits
-------

c8b65ae [ExpressionLanguage] throws an exception on calling uncallable method
  • Loading branch information
fabpot committed Sep 5, 2017
2 parents fd568ac + c8b65ae commit a819038
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
Expand Up @@ -77,8 +77,11 @@ public function evaluate($functions, $values)
if (!is_object($obj)) {
throw new \RuntimeException('Unable to get a property on a non-object.');
}
if (!is_callable($toCall = array($obj, $this->nodes['attribute']->attributes['value']))) {
throw new \RuntimeException(sprintf('Unable to call method "%s" of object "%s".', $this->nodes['attribute']->attributes['value'], get_class($obj)));
}

return call_user_func_array(array($obj, $this->nodes['attribute']->attributes['value']), $this->nodes['arguments']->evaluate($functions, $values));
return call_user_func_array($toCall, $this->nodes['arguments']->evaluate($functions, $values));

case self::ARRAY_CALL:
$array = $this->nodes['node']->evaluate($functions, $values);
Expand Down
Expand Up @@ -163,6 +163,16 @@ public function testRegisterAfterEval($registerCallback)
$registerCallback($el);
}

/**
* @expectedException \RuntimeException
* @expectedExceptionMessageRegExp /Unable to call method "\w+" of object "\w+"./
*/
public function testCallBadCallable()
{
$el = new ExpressionLanguage();
$el->evaluate('foo.myfunction()', array('foo' => new \stdClass()));
}

/**
* @dataProvider getRegisterCallbacks
* @expectedException \LogicException
Expand Down

0 comments on commit a819038

Please sign in to comment.