Skip to content

Commit 72a2c5d

Browse files
authored
Merge pull request from GHSA-vr2x-7687-h6qv
1 parent e5d9941 commit 72a2c5d

4 files changed

+31
-1
lines changed

AbstractCollectionNormalizer.php

+9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Serializer;
1515

1616
use ApiPlatform\Api\ResourceClassResolverInterface;
17+
use ApiPlatform\Metadata\Operation;
1718
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
1819
use ApiPlatform\State\Pagination\PaginatorInterface;
1920
use ApiPlatform\State\Pagination\PartialPaginatorInterface;
@@ -89,6 +90,7 @@ public function normalize(mixed $object, string $format = null, array $context =
8990

9091
unset($context['operation']);
9192
unset($context['operation_type'], $context['operation_name']);
93+
9294
$itemsData = $this->getItemsData($object, $format, $context);
9395

9496
return array_merge_recursive($data, $paginationData, $itemsData);
@@ -137,6 +139,13 @@ protected function getPaginationConfig(iterable $object, array $context = []): a
137139
return [$paginator, $paginated, $currentPage, $itemsPerPage, $lastPage, $pageTotalItems, $totalItems];
138140
}
139141

142+
protected function getOperation(array $context = []): Operation
143+
{
144+
$metadata = $this->resourceMetadataFactory->create($context['resource_class'] ?? '');
145+
146+
return $metadata->getOperation($context['operation_name'] ?? null);
147+
}
148+
140149
/**
141150
* Gets the pagination data.
142151
*/

AbstractItemNormalizer.php

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use ApiPlatform\Exception\InvalidArgumentException;
2020
use ApiPlatform\Exception\ItemNotFoundException;
2121
use ApiPlatform\Metadata\ApiProperty;
22+
use ApiPlatform\Metadata\CollectionOperationInterface;
2223
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
2324
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
2425
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
@@ -114,6 +115,11 @@ public function normalize(mixed $object, string $format = null, array $context =
114115
return $this->serializer->normalize($object, $format, $context);
115116
}
116117

118+
if (isset($context['operation']) && $context['operation'] instanceof CollectionOperationInterface) {
119+
unset($context['operation']);
120+
unset($context['iri']);
121+
}
122+
117123
if ($this->resourceClassResolver->isResourceClass($resourceClass)) {
118124
$context = $this->initContext($resourceClass, $context);
119125
}

CacheKeyTrait.php

+11-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313

1414
namespace ApiPlatform\Serializer;
1515

16+
/**
17+
* Used to override Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer::getCacheKey which is private
18+
* We need the cache_key in JsonApi and Hal before it is computed in Symfony.
19+
*
20+
* @see https://github.com/symfony/symfony/blob/49b6ab853d81e941736a1af67845efa3401e7278/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php#L723 which isn't protected
21+
*/
1622
trait CacheKeyTrait
1723
{
1824
private function getCacheKey(?string $format, array $context): string|bool
@@ -21,10 +27,14 @@ private function getCacheKey(?string $format, array $context): string|bool
2127
unset($context[$key]);
2228
}
2329
unset($context[self::EXCLUDE_FROM_CACHE_KEY]);
30+
unset($context[self::OBJECT_TO_POPULATE]);
2431
unset($context['cache_key']); // avoid artificially different keys
2532

2633
try {
27-
return md5($format.serialize($context));
34+
return hash('xxh128', $format.serialize([
35+
'context' => $context,
36+
'ignored' => $context[self::IGNORED_ATTRIBUTES] ?? $this->defaultContext[self::IGNORED_ATTRIBUTES],
37+
]));
2838
} catch (\Exception) {
2939
// The context cannot be serialized, skip the cache
3040
return false;

SerializerContextBuilder.php

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use ApiPlatform\Util\RequestAttributesExtractor;
1919
use Symfony\Component\HttpFoundation\Request;
2020
use Symfony\Component\Serializer\Encoder\CsvEncoder;
21+
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
2122
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
2223

2324
/**
@@ -81,6 +82,10 @@ public function createFromRequest(Request $request, bool $normalization, array $
8182
$context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS] = true;
8283
}
8384

85+
// to keep the cache computation smaller, we have "operation_name" and "iri" anyways
86+
$context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'root_operation';
87+
$context[AbstractObjectNormalizer::EXCLUDE_FROM_CACHE_KEY][] = 'operation';
88+
8489
return $context;
8590
}
8691
}

0 commit comments

Comments
 (0)