Skip to content

Commit 8c2155c

Browse files
committed
Prevent hydration errors in query string data init
1 parent c73a24e commit 8c2155c

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

src/LiveComponent/src/Util/QueryStringPropsExtractor.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
namespace Symfony\UX\LiveComponent\Util;
1313

1414
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\UX\LiveComponent\Exception\HydrationException;
1516
use Symfony\UX\LiveComponent\LiveComponentHydrator;
1617
use Symfony\UX\LiveComponent\Metadata\LiveComponentMetadata;
18+
use Symfony\UX\LiveComponent\Metadata\LivePropMetadata;
1719

1820
/**
1921
* @author Nicolas Rigaud <[email protected]>
@@ -46,12 +48,21 @@ public function extract(Request $request, LiveComponentMetadata $metadata, objec
4648
if (\is_array($value) && $this->isNumericIndexedArray($value)) {
4749
// Sort numeric array
4850
ksort($value);
49-
} elseif (('' === $value) && (!$livePropMetadata->isBuiltIn() || 'array' === $livePropMetadata->getType())) {
51+
} elseif ('' === $value && null !== $livePropMetadata->getType() && (!$livePropMetadata->isBuiltIn() || 'array' === $livePropMetadata->getType())) {
5052
// Cast empty string to empty array for objects and arrays
5153
$value = [];
5254
}
5355

54-
$data[$livePropMetadata->getName()] = $this->hydrator->hydrateValue($value, $livePropMetadata, $component);
56+
try {
57+
$hydratedValue = $this->hydrator->hydrateValue($value, $livePropMetadata, $component);
58+
59+
if ($this->isValueTypeConsistent($hydratedValue, $livePropMetadata)) {
60+
// Only set data if hydrated value type is consistent with prop metadata type
61+
$data[$livePropMetadata->getName()] = $hydratedValue;
62+
}
63+
} catch (HydrationException) {
64+
// Skip hydration errors (e.g. with objects)
65+
}
5566
}
5667
}
5768
}
@@ -63,4 +74,14 @@ private function isNumericIndexedArray(array $array): bool
6374
{
6475
return 0 === \count(array_filter(array_keys($array), 'is_string'));
6576
}
77+
78+
private function isValueTypeConsistent(mixed $value, LivePropMetadata $livePropMetadata): bool
79+
{
80+
$propType = $livePropMetadata->getType();
81+
82+
return
83+
\in_array($propType, [null, 'mixed'])
84+
|| $livePropMetadata->isBuiltIn() && ('\is_'.$propType)($value)
85+
|| !$livePropMetadata->isBuiltIn() && $value instanceof $propType;
86+
}
6687
}

0 commit comments

Comments
 (0)