Skip to content

Commit

Permalink
Prevent hydration errors in query string data init
Browse files Browse the repository at this point in the history
  • Loading branch information
squrious committed Nov 16, 2023
1 parent c73a24e commit 8c2155c
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 deletions src/LiveComponent/src/Util/QueryStringPropsExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
namespace Symfony\UX\LiveComponent\Util;

use Symfony\Component\HttpFoundation\Request;
use Symfony\UX\LiveComponent\Exception\HydrationException;
use Symfony\UX\LiveComponent\LiveComponentHydrator;
use Symfony\UX\LiveComponent\Metadata\LiveComponentMetadata;
use Symfony\UX\LiveComponent\Metadata\LivePropMetadata;

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

$data[$livePropMetadata->getName()] = $this->hydrator->hydrateValue($value, $livePropMetadata, $component);
try {
$hydratedValue = $this->hydrator->hydrateValue($value, $livePropMetadata, $component);

if ($this->isValueTypeConsistent($hydratedValue, $livePropMetadata)) {
// Only set data if hydrated value type is consistent with prop metadata type
$data[$livePropMetadata->getName()] = $hydratedValue;
}
} catch (HydrationException) {
// Skip hydration errors (e.g. with objects)
}
}
}
}
Expand All @@ -63,4 +74,14 @@ private function isNumericIndexedArray(array $array): bool
{
return 0 === \count(array_filter(array_keys($array), 'is_string'));
}

private function isValueTypeConsistent(mixed $value, LivePropMetadata $livePropMetadata): bool
{
$propType = $livePropMetadata->getType();

return
\in_array($propType, [null, 'mixed'])
|| $livePropMetadata->isBuiltIn() && ('\is_'.$propType)($value)
|| !$livePropMetadata->isBuiltIn() && $value instanceof $propType;
}
}

0 comments on commit 8c2155c

Please sign in to comment.