Skip to content

Commit

Permalink
[BUGFIX] Throw array conversion exception in `AbstractNode->castToStr…
Browse files Browse the repository at this point in the history
…ing()`

`AbstractNode->castToString()` already checked for objects which could not
converted to a string representation due to missing `__toString()` method.
It's possible that the value could be an array, which per nature is not
really convertable to a string anyway. Older php versions simply converted
it to an `Array` string along with a notices, which has been raised to a
warning in newer PHP versions.

There is no way to properly convert an array, therefore the PHP warning
should always lead to an parser exception like for object not convertable.

This change now checks explicitly for an array and throws a corresponding
`TYPO3Fluid\Fluid\Core\Parser\Exception` with a meaningfull message.

Test is extended to cover this case.

Resolves: #826
  • Loading branch information
sbuerk committed Oct 31, 2023
1 parent 7d0b084 commit 3c4e938
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/Core/Parser/SyntaxTree/AbstractNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ protected function castToString($value)
if (is_object($value) && !method_exists($value, '__toString')) {
throw new Parser\Exception('Cannot cast object of type "' . get_class($value) . '" to string.', 1273753083);
}
if (is_array($value)) {
throw new Parser\Exception('Cannot cast an array to string.', 1698750868);
}
$output = (string)$value;
return $output;
}
Expand Down
17 changes: 14 additions & 3 deletions tests/Unit/Core/Parser/SyntaxTree/AbstractNodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,31 @@ public function evaluateChildNodesReturnsNullIfNoChildNodesExist(): void

/**
* @test
* @dataProvider getChildNodeThrowsExceptionFiChildNodeCannotBeCastToStringTestValues
*/
public function evaluateChildNodeThrowsExceptionIfChildNodeCannotBeCastToString(): void
public function evaluateChildNodeThrowsExceptionIfChildNodeCannotBeCastToString(mixed $value, string $exceptionClass, int $exceptionCode, string $exceptionMessage): void
{
$this->expectException(Exception::class);
$this->expectException($exceptionClass);
$this->expectExceptionCode($exceptionCode);
$this->expectExceptionMessage($exceptionMessage);

$renderingContextMock = $this->createMock(RenderingContextInterface::class);
$childNode = $this->createMock(NodeInterface::class);
$childNode->expects(self::once())->method('evaluate')->with($renderingContextMock)->willReturn(new \DateTime('now'));
$childNode->expects(self::once())->method('evaluate')->with($renderingContextMock)->willReturn($value);
$subject = $this->getMockBuilder(AbstractNode::class)->onlyMethods(['evaluate'])->getMock();
$subject->addChildNode($childNode);
$method = new \ReflectionMethod($subject, 'evaluateChildNode');
$method->invoke($subject, $childNode, $renderingContextMock, true);
}

public static function getChildNodeThrowsExceptionFiChildNodeCannotBeCastToStringTestValues(): array
{
return [
[new \DateTime('now'), Exception::class, 1273753083, 'Cannot cast object of type "' . \DateTime::class . '" to string.'],
[['some' => 'value'], Exception::class, 1698750868, 'Cannot cast an array to string.'],
];
}

/**
* @test
*/
Expand Down

0 comments on commit 3c4e938

Please sign in to comment.