From 4c26981ce56bfc41b179ec34d7bdaa0538f024a5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Martin=20Haso=C5=88?= Date: Sat, 2 Aug 2014 17:11:21 +0200 Subject: [PATCH] Fixed "starts with" a "ends with" operators for non-string arguments --- lib/Twig/Node/Expression/Binary/EndsWith.php | 10 +++++----- lib/Twig/Node/Expression/Binary/StartsWith.php | 11 ++++++----- .../Twig/Tests/Fixtures/expressions/ends_with.test | 14 ++++++++++++++ .../Tests/Fixtures/expressions/starts_with.test | 2 ++ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/Twig/Node/Expression/Binary/EndsWith.php b/lib/Twig/Node/Expression/Binary/EndsWith.php index 5de6c72..93b3b96 100644 --- a/lib/Twig/Node/Expression/Binary/EndsWith.php +++ b/lib/Twig/Node/Expression/Binary/EndsWith.php @@ -12,14 +12,14 @@ class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary { public function compile(Twig_Compiler $compiler) { + $left = $compiler->getVarName(); + $right = $compiler->getVarName(); $compiler - ->raw('(0 === substr_compare(') + ->raw(sprintf('(is_string($%s = ', $left)) ->subcompile($this->getNode('left')) - ->raw(', ') + ->raw(sprintf(') && is_string($%s = ', $right)) ->subcompile($this->getNode('right')) - ->raw(', -strlen(') - ->subcompile($this->getNode('right')) - ->raw(')))') + ->raw(sprintf(') && (\'\' === $%2$s || $%2$s === substr($%1$s, -strlen($%2$s))))', $left, $right)) ; } diff --git a/lib/Twig/Node/Expression/Binary/StartsWith.php b/lib/Twig/Node/Expression/Binary/StartsWith.php index b7c30b3..d2e30d6 100644 --- a/lib/Twig/Node/Expression/Binary/StartsWith.php +++ b/lib/Twig/Node/Expression/Binary/StartsWith.php @@ -12,13 +12,14 @@ class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary { public function compile(Twig_Compiler $compiler) { - $varName = $compiler->getVarName(); + $left = $compiler->getVarName(); + $right = $compiler->getVarName(); $compiler - ->raw(sprintf("(('' === (\$%s = ", $varName)) - ->subcompile($this->getNode('right')) - ->raw(')) ? true : 0 === strpos(') + ->raw(sprintf('(is_string($%s = ', $left)) ->subcompile($this->getNode('left')) - ->raw(sprintf(', $%s))', $varName)) + ->raw(sprintf(') && is_string($%s = ', $right)) + ->subcompile($this->getNode('right')) + ->raw(sprintf(') && (\'\' === $%2$s || 0 === strpos($%1$s, $%2$s)))', $left, $right)) ; } diff --git a/test/Twig/Tests/Fixtures/expressions/ends_with.test b/test/Twig/Tests/Fixtures/expressions/ends_with.test index d259d11..9ad5e5e 100644 --- a/test/Twig/Tests/Fixtures/expressions/ends_with.test +++ b/test/Twig/Tests/Fixtures/expressions/ends_with.test @@ -4,9 +4,23 @@ Twig supports the "ends with" operator {{ 'foo' ends with 'o' ? 'OK' : 'KO' }} {{ not ('foo' ends with 'f') ? 'OK' : 'KO' }} {{ not ('foo' ends with 'foowaytoolong') ? 'OK' : 'KO' }} +{{ 'foo' ends with '' ? 'OK' : 'KO' }} +{{ '1' ends with true ? 'OK' : 'KO' }} +{{ 1 ends with true ? 'OK' : 'KO' }} +{{ 0 ends with false ? 'OK' : 'KO' }} +{{ '' ends with false ? 'OK' : 'KO' }} +{{ false ends with false ? 'OK' : 'KO' }} +{{ false ends with '' ? 'OK' : 'KO' }} --DATA-- return array() --EXPECT-- OK OK OK +OK +KO +KO +KO +KO +KO +KO diff --git a/test/Twig/Tests/Fixtures/expressions/starts_with.test b/test/Twig/Tests/Fixtures/expressions/starts_with.test index b960c8b..75d331e 100644 --- a/test/Twig/Tests/Fixtures/expressions/starts_with.test +++ b/test/Twig/Tests/Fixtures/expressions/starts_with.test @@ -11,6 +11,7 @@ with 'f' ? 'OK' : 'KO' }} {{ '1' starts with true ? 'OK' : 'KO' }} {{ '' starts with false ? 'OK' : 'KO' }} {{ 'a' starts with false ? 'OK' : 'KO' }} +{{ false starts with '' ? 'OK' : 'KO' }} --DATA-- return array() --EXPECT-- @@ -23,3 +24,4 @@ OK KO KO KO +KO -- 1.7.2.5