Skip to content

Commit 84b3107

Browse files
committed
fix: Throw exception when trying to access invalid Node
Instead of just ignoring it and possibly creating subtle bugs. Signed-off-by: Carl Schwan <[email protected]>
1 parent b742250 commit 84b3107

File tree

4 files changed

+79
-25
lines changed

4 files changed

+79
-25
lines changed

apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,12 @@ private function shareAccepted($id, array $notification) {
336336
* @param IShare $share
337337
* @throws ShareNotFound
338338
*/
339-
protected function executeAcceptShare(IShare $share) {
339+
protected function executeAcceptShare(IShare $share): void {
340340
try {
341-
$fileId = $share->getNode()->getId() ?? -1;
341+
$fileId = $share->getNode()->getId();
342+
if ($fileId == null) {
343+
throw new \LogicException('Invalid node for share');
344+
}
342345
[$file, $link] = $this->getFile($this->getCorrectUid($share), $fileId);
343346
} catch (\Exception $e) {
344347
throw new ShareNotFound();

apps/files/lib/Listener/SyncLivePhotosListener.php

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,18 @@ private function handleMove(Node $sourceFile, Node $targetFile, Node $peerFile):
134134
return;
135135
}
136136

137-
$this->pendingRenames[] = $sourceFile->getId() ?? -1;
137+
$sourceFileId = $sourceFile->getId();
138+
if ($sourceFileId === null) {
139+
throw new \LogicException('Invalid source file given with a null id');
140+
}
141+
$this->pendingRenames[] = $sourceFileId;
138142
try {
139143
$peerFile->move($targetParent->getPath() . '/' . $peerTargetName);
140144
} catch (\Throwable $ex) {
141145
throw new AbortedEventException($ex->getMessage());
142146
}
143147

144-
$this->pendingRenames = array_diff($this->pendingRenames, [$sourceFile->getId() ?? -1]);
148+
$this->pendingRenames = array_diff($this->pendingRenames, [$sourceFileId]);
145149
}
146150

147151

@@ -163,15 +167,26 @@ private function handleCopy(File $sourceFile, File $targetFile, File $peerFile):
163167
$targetPeerFile = $peerFile->copy($targetParent->getPath() . '/' . $peerTargetName);
164168
}
165169

170+
$targetFileId = $targetFile->getId();
171+
if ($targetFileId === null) {
172+
throw new \LogicException('Invalid target file given with a null id');
173+
}
174+
175+
$targetPeerFileId = $targetPeerFile->getId();
176+
if ($targetPeerFileId === null) {
177+
throw new \LogicException('Invalid target peer file given with a null id');
178+
}
179+
166180
/** @var FilesMetadata $targetMetadata */
167-
$targetMetadata = $this->filesMetadataManager->getMetadata($targetFile->getId(), true);
181+
$targetMetadata = $this->filesMetadataManager->getMetadata($targetFileId, true);
168182
$targetMetadata->setStorageId($targetFile->getStorage()->getCache()->getNumericStorageId());
169-
$targetMetadata->setString('files-live-photo', (string)$targetPeerFile->getId());
183+
$targetMetadata->setString('files-live-photo', (string)$targetPeerFileId);
170184
$this->filesMetadataManager->saveMetadata($targetMetadata);
185+
171186
/** @var FilesMetadata $peerMetadata */
172-
$peerMetadata = $this->filesMetadataManager->getMetadata($targetPeerFile->getId(), true);
187+
$peerMetadata = $this->filesMetadataManager->getMetadata($targetPeerFileId, true);
173188
$peerMetadata->setStorageId($targetPeerFile->getStorage()->getCache()->getNumericStorageId());
174-
$peerMetadata->setString('files-live-photo', (string)$targetFile->getId());
189+
$peerMetadata->setString('files-live-photo', (string)$targetFileId);
175190
$this->filesMetadataManager->saveMetadata($peerMetadata);
176191
}
177192

@@ -185,14 +200,22 @@ private function handleCopy(File $sourceFile, File $targetFile, File $peerFile):
185200
private function handleDeletion(BeforeNodeDeletedEvent $event, Node $peerFile): void {
186201
$deletedFile = $event->getNode();
187202
if ($deletedFile->getMimetype() === 'video/quicktime') {
188-
if (isset($this->pendingDeletion[$peerFile->getId() ?? -1])) {
189-
unset($this->pendingDeletion[$peerFile->getId() ?? -1]);
203+
$peerFileId = $peerFile->getId();
204+
if ($peerFileId === null) {
205+
throw new \LogicException('Invalid peer file given with a null id');
206+
}
207+
if (isset($this->pendingDeletion[$peerFileId])) {
208+
unset($this->pendingDeletion[$peerFileId]);
190209
return;
191210
} else {
192211
throw new AbortedEventException('Cannot delete the video part of a live photo');
193212
}
194213
} else {
195-
$this->pendingDeletion[$deletedFile->getId() ?? -1] = true;
214+
$deletedFileId = $peerFile->getId();
215+
if ($deletedFileId === null) {
216+
throw new \LogicException('Invalid deleted file given with a null id');
217+
}
218+
$this->pendingDeletion[$deletedFileId] = true;
196219
try {
197220
$peerFile->delete();
198221
} catch (\Throwable $ex) {
@@ -243,7 +266,7 @@ private function handleCopyRecursive(Event $event, Node $sourceNode, Node $targe
243266
$this->pendingCopies[] = $peerFileId;
244267
if ($event instanceof BeforeNodeCopiedEvent) {
245268
$this->runMoveOrCopyChecks($sourceNode, $targetNode, $peerFile);
246-
} elseif ($event instanceof NodeCopiedEvent) {
269+
} elseif ($event instanceof NodeCopiedEvent && $peerFile instanceof File) {
247270
$this->handleCopy($sourceNode, $targetNode, $peerFile);
248271
}
249272
$this->pendingCopies = array_diff($this->pendingCopies, [$peerFileId]);

apps/files_trashbin/lib/Listeners/SyncLivePhotosListener.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,13 @@ private function handleRestore(BeforeNodeRestoredEvent $event, Node $peerFile):
7272
$sourceFile = $event->getSource();
7373

7474
if ($sourceFile->getMimetype() === 'video/quicktime') {
75-
if (isset($this->pendingRestores[$peerFile->getId() ?? -1])) {
76-
unset($this->pendingRestores[$peerFile->getId() ?? -1]);
75+
$peerFileId = $peerFile->getId();
76+
if ($peerFileId === null) {
77+
throw new \LogicException('Invalid peer file given with a null id');
78+
}
79+
80+
if (isset($this->pendingRestores[$peerFileId])) {
81+
unset($this->pendingRestores[$peerFileId]);
7782
return;
7883
} else {
7984
$event->abortOperation(new NotPermittedException('Cannot restore the video part of a live photo'));
@@ -97,7 +102,12 @@ private function handleRestore(BeforeNodeRestoredEvent $event, Node $peerFile):
97102
$event->abortOperation(new NotFoundException("Couldn't find peer file in trashbin"));
98103
}
99104

100-
$this->pendingRestores[$sourceFile->getId() ?? -1] = true;
105+
$sourceFileId = $sourceFile->getId();
106+
if ($sourceFileId === null) {
107+
throw new \LogicException('Invalid source file given with a null id');
108+
}
109+
110+
$this->pendingRestores[$sourceFileId] = true;
101111
try {
102112
$this->trashManager->restoreItem($trashItem);
103113
} catch (\Throwable $ex) {

apps/files_versions/lib/Listener/FileEventsListener.php

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
namespace OCA\Files_Versions\Listener;
99

1010
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
11-
use OC\DB\Exceptions\DbalException;
1211
use OC\Files\Filesystem;
1312
use OC\Files\Mount\MoveableMount;
1413
use OC\Files\Node\NonExistingFile;
@@ -122,7 +121,12 @@ public function pre_touch_hook(Node $node): void {
122121
return;
123122
}
124123

125-
$this->nodesTouched[$node->getId() ?? -1] = $node;
124+
$nodeId = $node->getId();
125+
if ($nodeId === null) {
126+
return;
127+
}
128+
129+
$this->nodesTouched[$nodeId] = $node;
126130
}
127131

128132
public function touch_hook(Node $node): void {
@@ -142,13 +146,17 @@ public function touch_hook(Node $node): void {
142146
return;
143147
}
144148

145-
$previousNode = $this->nodesTouched[$node->getId()] ?? null;
149+
$nodeId = $node->getId();
150+
if ($nodeId === null) {
151+
throw new \LogicException('Invalid node given');
152+
}
153+
$previousNode = $this->nodesTouched[$nodeId] ?? null;
146154

147155
if ($previousNode === null) {
148156
return;
149157
}
150158

151-
unset($this->nodesTouched[$node->getId()]);
159+
unset($this->nodesTouched[$nodeId]);
152160

153161
try {
154162
if ($node instanceof File && $this->versionManager instanceof INeedSyncVersionBackend) {
@@ -157,15 +165,15 @@ public function touch_hook(Node $node): void {
157165
// We update the timestamp of the version entity associated with the previousNode.
158166
$this->versionManager->updateVersionEntity($node, $revision, ['timestamp' => $node->getMTime()]);
159167
}
160-
} catch (DbalException $ex) {
168+
} catch (Exception $ex) {
161169
// Ignore UniqueConstraintViolationException, as we are probably in the middle of a rollback
162-
// Where the previous node would temporary have the mtime of the old version, so the rollback touches it to fix it.
163-
if (!($ex->getPrevious() instanceof UniqueConstraintViolationException)) {
170+
// Where the previous node would temporarily have the mtime of the old version, so the rollback touches it to fix it.
171+
if ($ex->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
164172
throw $ex;
165173
}
166174
} catch (DoesNotExistException $ex) {
167175
// Ignore DoesNotExistException, as we are probably in the middle of a rollback
168-
// Where the previous node would temporary have a wrong mtime, so the rollback touches it to fix it.
176+
// Where the previous node would temporarily have a wrong mtime, so the rollback touches it to fix it.
169177
}
170178
}
171179

@@ -208,8 +216,13 @@ public function write_hook(Node $node): void {
208216
$path = $this->getPathForNode($node);
209217
$result = Storage::store($path);
210218

219+
$nodeId = $node->getId();
220+
if ($nodeId === null) {
221+
throw new \LogicException('Invalid node given');
222+
}
223+
211224
// Store the result of the version creation so it can be used in post_write_hook.
212-
$this->writeHookInfo[$node->getId() ?? -1] = [
225+
$this->writeHookInfo[$nodeId] = [
213226
'previousNode' => $node,
214227
'versionCreated' => $result !== false
215228
];
@@ -235,7 +248,12 @@ public function post_write_hook(Node $node): void {
235248
return;
236249
}
237250

238-
$writeHookInfo = $this->writeHookInfo[$node->getId()] ?? null;
251+
$nodeId = $node->getId();
252+
if ($nodeId === null) {
253+
throw new \LogicException('Invalid node given');
254+
}
255+
256+
$writeHookInfo = $this->writeHookInfo[$nodeId] ?? null;
239257

240258
if ($writeHookInfo === null) {
241259
return;

0 commit comments

Comments
 (0)