Skip to content

Commit c4da152

Browse files
committed
fix: de/serialize ResourceType when caching results
Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
1 parent 150d5ce commit c4da152

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

apps/dav/lib/Paginate/PaginateCache.php

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@
1414
use OCP\ICacheFactory;
1515
use OCP\IDBConnection;
1616
use OCP\Security\ISecureRandom;
17+
use Sabre\DAV\Xml\Property\ResourceType;
1718

1819
class PaginateCache {
1920
public const TTL = 60 * 60;
2021
private const CACHE_COUNT_SUFFIX = 'count';
2122

23+
private const RESOURCE_TYPE_PROPERTY = '{DAV:}resourcetype';
24+
2225
private ICache $cache;
2326

2427
public function __construct(
@@ -40,6 +43,7 @@ public function store(string $uri, \Iterator $items): array {
4043

4144
$count = 0;
4245
foreach ($items as $item) {
46+
$this->serializeResourceType($item);
4347
// Add small margin to avoid fetching valid count and then expired entries
4448
$this->cache->set($cacheKey . $count, $item, self::TTL + 60);
4549
++$count;
@@ -61,7 +65,49 @@ public function get(string $uri, string $token, int $offset, int $count): Genera
6165

6266
$lastItem = min($nbItems, $offset + $count);
6367
for ($i = $offset; $i < $lastItem; ++$i) {
64-
yield $this->cache->get($cacheKey . $i);
68+
$element = $this->cache->get($cacheKey . $i);
69+
$this->deserializeResourceType($element);
70+
yield $element;
71+
}
72+
}
73+
74+
/**
75+
* The ResourceType class is lost when json_encode is used.
76+
* This function serializes it in place so that this does not happen.
77+
*
78+
* @param array $item
79+
* @return void
80+
*/
81+
private function serializeResourceType(array &$item): void {
82+
foreach ($item as &$responseProperties) {
83+
if (!is_array($responseProperties)) {
84+
continue;
85+
}
86+
foreach ($responseProperties as &$propertyValue) {
87+
if ($propertyValue instanceof ResourceType) {
88+
$propertyValue = serialize($propertyValue);
89+
}
90+
}
91+
}
92+
}
93+
94+
/**
95+
* The ResourceType class in the cache is serialized. This function will
96+
* deserialize it in place.
97+
*
98+
* @param array $item
99+
* @return void
100+
*/
101+
private function deserializeResourceType(array &$item): void {
102+
foreach ($item as &$responseProperties) {
103+
foreach ($responseProperties as $propertyName => &$propertyValue) {
104+
if ($propertyName === self::RESOURCE_TYPE_PROPERTY) {
105+
$propertyValue = unserialize(
106+
$propertyValue,
107+
[ 'allowed_classes' => [ResourceType::class]]
108+
);
109+
}
110+
}
65111
}
66112
}
67113

0 commit comments

Comments
 (0)