Skip to content

Commit 9f5535d

Browse files
committed
fix: apply quota with writeStream
Signed-off-by: Robin Appelman <robin@icewind.nl>
1 parent f3a5bc8 commit 9f5535d

3 files changed

Lines changed: 57 additions & 0 deletions

File tree

lib/private/Files/Storage/Wrapper/Quota.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use OC\SystemConfig;
1212
use OCP\Files\Cache\ICacheEntry;
1313
use OCP\Files\FileInfo;
14+
use OCP\Files\GenericFileException;
15+
use OCP\Files\NotEnoughSpaceException;
1416
use OCP\Files\Storage\IStorage;
1517

1618
class Quota extends Wrapper {
@@ -214,4 +216,31 @@ public function touch(string $path, ?int $mtime = null): bool {
214216
public function enableQuota(bool $enabled): void {
215217
$this->enabled = $enabled;
216218
}
219+
220+
#[\Override]
221+
public function writeStream(string $path, $stream, ?int $size = null): int {
222+
if (!$this->hasQuota()) {
223+
return parent::writeStream($path, $stream, $size);
224+
}
225+
226+
$free = $this->free_space($path);
227+
if ($this->shouldApplyQuota($path) && $free == 0) {
228+
throw new NotEnoughSpaceException();
229+
}
230+
231+
if ($size !== null) {
232+
if ($size < $free) {
233+
return parent::writeStream($path, $stream, $size);
234+
} else {
235+
throw new NotEnoughSpaceException();
236+
}
237+
} else {
238+
// force fallback through `fopen` to handle the quota
239+
try {
240+
return parent::writeStreamFallback($path, $stream);
241+
} catch (GenericFileException) {
242+
throw new NotEnoughSpaceException();
243+
}
244+
}
245+
}
217246
}

lib/private/Files/Storage/Wrapper/Wrapper.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,13 @@ public function writeStream(string $path, $stream, ?int $size = null): int {
392392
return $storage->writeStream($path, $stream, $size);
393393
}
394394

395+
return $this->writeStreamFallback($path, $stream);
396+
}
397+
398+
/**
399+
* @param resource $stream
400+
*/
401+
protected function writeStreamFallback(string $path, $stream): int {
395402
$target = $this->fopen($path, 'w');
396403
if ($target === false) {
397404
throw new GenericFileException('Failed to open ' . $path);

tests/lib/Files/Storage/Wrapper/QuotaTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,25 @@ public function testNoFopenQuotaZero(): void {
235235
$fh = $instance->fopen('files/test.txt', 'w');
236236
$this->assertFalse($fh);
237237
}
238+
239+
public function testNoWriteStreamQuota(): void {
240+
$instance = $this->getLimitedStorage(5.0);
241+
$stream = fopen('php://temp', 'w+');
242+
fwrite($stream, 'foo');
243+
rewind($stream);
244+
$instance->writeStream('files/test.txt', $stream);
245+
246+
$stream = fopen('php://temp', 'w+');
247+
fwrite($stream, 'foobar');
248+
rewind($stream);
249+
$this->expectException(Files\NotEnoughSpaceException::class);
250+
$instance->writeStream('files/test.txt', $stream);
251+
}
252+
253+
public function testNoWriteStreamQuotaZero(): void {
254+
$instance = $this->getLimitedStorage(0.0);
255+
$stream = fopen('php://temp', 'w+');
256+
$this->expectException(Files\NotEnoughSpaceException::class);
257+
$instance->writeStream('files/test.txt', $stream);
258+
}
238259
}

0 commit comments

Comments
 (0)