Skip to content

Commit

Permalink
Merge pull request #108 from stof/fix_function_preconditions
Browse files Browse the repository at this point in the history
Moved the preconditions of function arguments before the function
  • Loading branch information
schmittjoh committed Jan 31, 2013
2 parents 08e0b46 + 0089574 commit 0225405
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
6 changes: 3 additions & 3 deletions Security/Authorization/Expression/ExpressionCompiler.php
Expand Up @@ -129,7 +129,7 @@ public function outdent()
$this->indentationLevel -= 1;

if ($this->indentationLevel < 0) {
throw new RuntimeException('The identation level cannot be less than zero.');
throw new RuntimeException('The indentation level cannot be less than zero.');
}

return $this;
Expand Down Expand Up @@ -266,12 +266,12 @@ public function compilePreconditions(ExpressionInterface $expr)
}

if ($expr instanceof FunctionExpression) {
$this->getFunctionCompiler($expr->name)->compilePreconditions($this, $expr);

foreach ($expr->args as $arg) {
$this->compilePreconditions($arg);
}

$this->getFunctionCompiler($expr->name)->compilePreconditions($this, $expr);

return $this;
}

Expand Down
54 changes: 54 additions & 0 deletions Tests/Security/Authorization/Expression/ExpressionCompilerTest.php
Expand Up @@ -3,6 +3,8 @@
namespace JMS\SecurityExtraBundle\Tests\Security\Authorization\Expression;

use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\ParameterExpressionCompiler;
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func\FunctionCompilerInterface;

use JMS\SecurityExtraBundle\Security\Acl\Expression\HasPermissionFunctionCompiler;

Expand Down Expand Up @@ -110,6 +112,27 @@ public function testCompileWhenParameterIsWrappedInMethodCall()
$this->assertFalse($evaluator($context));
}

public function testCompileInternalInPreconditions()
{
$this->compiler->addTypeCompiler(new ParameterExpressionCompiler());
$this->compiler->addFunctionCompiler(new TestIssue108FunctionCompiler());

// the first call ensure that state is reset correctly
$this->compiler->compileExpression(new Expression(
'testIssue(#project)'));
$evaluator = eval($this->compiler->compileExpression(
new Expression('testIssue(#project)')));

$secureObject = new SecuredObject();
$project = new Project();

$context = array(
'object' => new MethodInvocation(new \ReflectionMethod($secureObject, 'delete'), $secureObject, array($project), array()),
);

$this->assertTrue($evaluator($context));
}

/**
* @dataProvider getUnaryNotTests
*/
Expand Down Expand Up @@ -148,3 +171,34 @@ protected function setUp()
$this->compiler = new ExpressionCompiler();
}
}

class TestIssue108FunctionCompiler implements FunctionCompilerInterface
{
public function getName()
{
return 'testIssue';
}

public function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function)
{
if (1 !== count($function->args)) {
throw new \RuntimeException(sprintf('The %s() function expects exactly one argument, but got "%s".', $this->getName(), var_export($function->args, true)));
}

$argName = $compiler->nextName();

$compiler
->write("\$$argName = ")
->compileInternal($function->args[0])
->writeln(';');

$compiler->attributes['arg_name'] = $argName;
}

public function compile(ExpressionCompiler $compiler, FunctionExpression $function)
{
$argName = $compiler->attributes['arg_name'];

$compiler->write("\$$argName !== null");
}
}

0 comments on commit 0225405

Please sign in to comment.