[Core] Fix cycle() with non-countable ArrayAccess+Traversable objects

This commit is contained in:
Younes ENNAJI
2025-11-23 04:08:21 +01:00
parent 2b7cc0ba9f
commit 473653d19b
2 changed files with 42 additions and 3 deletions
+1 -3
View File
@@ -417,10 +417,8 @@ final class CoreExtension extends AbstractExtension
trigger_deprecation('twig/twig', '3.12', 'Passing a non-countable sequence of values to "%s()" is deprecated.', __METHOD__);
return $values;
$values = self::toArray($values, false);
}
$values = self::toArray($values, false);
}
if (!$count = \count($values)) {
+41
View File
@@ -21,6 +21,7 @@ namespace Twig\Tests\Extension;
*/
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Twig\Environment;
use Twig\Error\RuntimeError;
use Twig\Extension\CoreExtension;
@@ -31,6 +32,8 @@ use Twig\Sandbox\SecurityPolicy;
class CoreTest extends TestCase
{
use ExpectDeprecationTrait;
/**
* @dataProvider provideCycleCases
*/
@@ -407,6 +410,44 @@ class CoreTest extends TestCase
{
$this->assertGreaterThan(1000000000, (new CoreExtension())->getLastModified());
}
/**
* @group legacy
*/
public function testCycleWithArrayAccessAndTraversableButNotCountable()
{
$this->expectDeprecation('Since twig/twig 3.12: Passing a non-countable sequence of values to "Twig\Extension\CoreExtension::cycle()" is deprecated.');
$seq = new class implements \ArrayAccess, \IteratorAggregate {
public function offsetExists($offset): bool
{
return true;
}
public function offsetGet($offset): mixed
{
return 'val';
}
public function offsetSet($offset, $value): void
{
}
public function offsetUnset($offset): void
{
}
public function getIterator(): \Traversable
{
yield 'odd';
yield 'even';
}
};
$result = CoreExtension::cycle($seq, 0);
$this->assertEquals('odd', $result, 'cycle should return the first item from the traversable sequence, not the sequence itself.');
}
}
final class CoreTestIteratorAggregate implements \IteratorAggregate