Skip to content

Commit

Permalink
Add maximum depth to serializer to prevent infinite recursion (facile…
Browse files Browse the repository at this point in the history
  • Loading branch information
mhvis committed Jul 19, 2024
1 parent 9ee761a commit dcb7b0b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
17 changes: 11 additions & 6 deletions src/DataCollector/MongoQuerySerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ public static function serialize(Query $query): void
*
* @return mixed[]
*/
private static function prepareUnserializableData($data): array
private static function prepareUnserializableData($data, int $depth = 0): array
{
if ($data instanceof Serializable) {
$data = $data->bsonSerialize();
}

$newData = [];
foreach ($data as $key => $item) {
$newData[$key] = self::prepareItemData($item);
$newData[$key] = self::prepareItemData($item, $depth + 1);
}

return $newData;
Expand All @@ -43,19 +43,24 @@ private static function prepareUnserializableData($data): array
*
* @return mixed
*/
public static function prepareItemData($item)
public static function prepareItemData($item, int $depth = 0)
{
// Prevent infinite recursion
if ($depth > 1_000) {
return null;
}

if (\is_scalar($item)) {
return $item;
}

if (\is_array($item)) {
return self::prepareUnserializableData($item);
return self::prepareUnserializableData($item, $depth);
}

if (\is_object($item)) {
if (method_exists($item, 'getArrayCopy')) {
return self::prepareUnserializableData($item->getArrayCopy());
return self::prepareUnserializableData($item->getArrayCopy(), $depth);
}

if (method_exists($item, 'toDateTime')) {
Expand All @@ -70,7 +75,7 @@ public static function prepareItemData($item)
return $item->bsonSerialize();
}

return self::prepareUnserializableData((array) $item);
return self::prepareUnserializableData((array) $item, $depth);
}

return $item;
Expand Down
23 changes: 23 additions & 0 deletions tests/Unit/DataCollector/MongoQuerySerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,29 @@ public function unserializedDataProvider(): array
];
}

public function test_serializer_terminating(): void
{
// tests that the serializer terminates when serializing an object which references itself
$selfReferencingObject = new class () {
public $self;

public function __construct(
) {
$this->self = $this;
}
};
$data = ['test' => $selfReferencingObject];

$query = new Query();
$query->setFilters($data);
$query->setData($data);
$query->setOptions($data);

MongoQuerySerializer::serialize($query);

$this->expectNotToPerformAssertions();
}

public function test_serializer_regression_with_replaceOne(): void
{
$stdClass = new \stdClass();
Expand Down

0 comments on commit dcb7b0b

Please sign in to comment.