diff --git a/application/bookmark/BookmarkIO.php b/application/bookmark/BookmarkIO.php index 8439d470..fa5cefb5 100644 --- a/application/bookmark/BookmarkIO.php +++ b/application/bookmark/BookmarkIO.php @@ -9,6 +9,8 @@ use malkusch\lock\mutex\NoMutex; use Shaarli\Bookmark\Exception\DatastoreNotInitializedException; use Shaarli\Bookmark\Exception\EmptyDataStoreException; +use Shaarli\Bookmark\Exception\InvalidWritableDataException; +use Shaarli\Bookmark\Exception\NotEnoughSpaceException; use Shaarli\Bookmark\Exception\NotWritableDataStoreException; use Shaarli\Config\ConfigManager; @@ -107,6 +109,7 @@ public function read() * @param Bookmark[] $links * * @throws NotWritableDataStoreException the datastore is not writable + * @throws InvalidWritableDataException */ public function write($links) { @@ -118,9 +121,19 @@ public function write($links) throw new NotWritableDataStoreException(dirname($this->datastore)); } - $data = self::$phpPrefix . base64_encode(gzdeflate(serialize($links))) . self::$phpSuffix; + $data = base64_encode(gzdeflate(serialize($links))); + + if (empty($data)) { + throw new InvalidWritableDataException(); + } + + $data = self::$phpPrefix . $data . self::$phpSuffix; $this->synchronized(function () use ($data) { + if (!$this->checkDiskSpace($data)) { + throw new NotEnoughSpaceException(); + } + file_put_contents( $this->datastore, $data @@ -144,4 +157,17 @@ protected function synchronized(callable $function): void $function(); } } + + /** + * Make sure that there is enough disk space available to save the current data store. + * We add an arbitrary margin of 500kB. + * + * @param string $data to be saved + * + * @return bool True if data can safely be saved + */ + public function checkDiskSpace(string $data): bool + { + return disk_free_space(dirname($this->datastore)) > (strlen($data) + 1024 * 500); + } } diff --git a/application/bookmark/exception/InvalidWritableDataException.php b/application/bookmark/exception/InvalidWritableDataException.php new file mode 100644 index 00000000..bf3ae167 --- /dev/null +++ b/application/bookmark/exception/InvalidWritableDataException.php @@ -0,0 +1,14 @@ +message = 'Couldn\'t generate bookmark data to store in the datastore. Skipping file writing.'; + } +} diff --git a/application/bookmark/exception/NotEnoughSpaceException.php b/application/bookmark/exception/NotEnoughSpaceException.php new file mode 100644 index 00000000..e55dd22e --- /dev/null +++ b/application/bookmark/exception/NotEnoughSpaceException.php @@ -0,0 +1,14 @@ +message = 'Not enough available disk space to save the datastore.'; + } +}