Minor code improvements
authorAlexander Ebert <ebert@woltlab.com>
Wed, 8 May 2024 09:10:55 +0000 (11:10 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Sat, 8 Jun 2024 10:19:39 +0000 (12:19 +0200)
wcfsetup/install/files/lib/action/FileDownloadAction.class.php
wcfsetup/install/files/lib/data/attachment/Attachment.class.php
wcfsetup/install/files/lib/data/file/File.class.php
wcfsetup/install/files/lib/data/file/temporary/FileTemporary.class.php
wcfsetup/install/files/lib/system/endpoint/controller/core/files/upload/PostChunk.class.php

index f2d1c7d66348ff7ec062319b5d9121eecbf5f600..efc42466bc25d9510effe0c154f5a54a6178f929 100644 (file)
@@ -8,6 +8,7 @@ use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use Psr\Http\Server\RequestHandlerInterface;
 use wcf\data\file\File;
+use wcf\http\ContentDisposition;
 use wcf\http\Helper;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\PermissionDeniedException;
@@ -54,29 +55,21 @@ final class FileDownloadAction implements RequestHandlerInterface
         );
 
         $mimeType = FileUtil::getMimeType($filename);
-
-        // TODO: This should use `FileReader` instead.
-
-        $inlineMimeTypes = [
+        $contentDisposition = match ($mimeType) {
             'image/gif',
             'image/jpeg',
             'image/png',
             'image/x-png',
             'application/pdf',
             'image/pjpeg',
-            'image/webp',
-        ];
-
-        $dispositionType = \in_array($mimeType, $inlineMimeTypes) ? 'inline' : 'attachment';
+            'image/webp' => ContentDisposition::Inline,
+            default => ContentDisposition::Attachment,
+        };
 
         return $response->withHeader('content-type', $mimeType)
             ->withHeader(
                 'content-disposition',
-                \sprintf(
-                    '%s; filename="%s"',
-                    $dispositionType,
-                    $file->filename,
-                ),
+                $contentDisposition->forFilename($file->filename),
             );
     }
 }
index 0313d1631853312ced0241a906c09dc5af2a36ec..6ede5985002172c851cc2bcc56bfd87a63bfdd33 100644 (file)
@@ -200,7 +200,11 @@ class Attachment extends DatabaseObject implements ILinkableObject, IRouteContro
      */
     public function migrateStorage()
     {
-        foreach ([$this->getLocation(), $this->getThumbnailLocation(), $this->getThumbnailLocation('tiny'),] as $location) {
+        foreach ([
+            $this->getLocation(),
+            $this->getThumbnailLocation(),
+            $this->getThumbnailLocation('tiny'),
+        ] as $location) {
             if (!\str_ends_with($location, '.bin')) {
                 \rename($location, $location . '.bin');
             }
index b2ef0cd1e80b61fce138230dddd7e3639bc1eebc..8dd234f83d0c0eb41843ac769386252788cd9b0a 100644 (file)
@@ -8,6 +8,7 @@ use wcf\data\file\thumbnail\FileThumbnail;
 use wcf\system\file\processor\FileProcessor;
 use wcf\system\file\processor\IFileProcessor;
 use wcf\system\request\LinkHandler;
+use wcf\util\JSON;
 use wcf\util\StringUtil;
 
 /**
@@ -158,8 +159,8 @@ class File extends DatabaseObject
             StringUtil::encodeHTML($this->filename),
             $this->fileSize,
             StringUtil::encodeHTML($this->mimeType),
-            StringUtil::encodeHTML(\json_encode($thumbnails)),
-            StringUtil::encodeHTML(\json_encode($metaData)),
+            StringUtil::encodeHTML(JSON::encode($thumbnails)),
+            StringUtil::encodeHTML(JSON::encode($metaData)),
             StringUtil::encodeHTML($this->getLink()),
         );
     }
@@ -177,11 +178,7 @@ class File extends DatabaseObject
         }
 
         if (\str_contains($filename, '.')) {
-            $fileExtension = \mb_substr(
-                $filename,
-                \mb_strrpos($filename, '.') + 1
-            );
-
+            $fileExtension = \pathinfo($filename, \PATHINFO_EXTENSION);
             if (isset(self::SAFE_FILE_EXTENSIONS[$fileExtension])) {
                 return $fileExtension;
             }
index 5f82295ea8c058d9690bc1bbbcb7fec75fa17947..172e27bfa11cd46ee690d4306e22335df2294fc1 100644 (file)
@@ -40,6 +40,16 @@ class FileTemporary extends DatabaseObject
 
     public function hasChunk(int $sequenceNo): bool
     {
+        if ($sequenceNo > \strlen($this->chunks)) {
+            throw new \OutOfRangeException(
+                \sprintf(
+                    "Cannot access chunk #%d of %d",
+                    $sequenceNo,
+                    \strlen($this->chunks),
+                ),
+            );
+        }
+
         return $this->chunks[$sequenceNo] === '1';
     }
 
index 998783ab5eed9ff3f7760b2fe7ad9aa639755f06..5e8a5ef4db9b6f5d5f3622ab9706d354aa5a5add 100644 (file)
@@ -24,8 +24,9 @@ final class PostChunk implements IController
 
     public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
     {
-        $checksum = \current($request->getHeader('chunk-checksum-sha256'));
-        if ($checksum === false) {
+        $checksum = $request->getHeaderLine('chunk-checksum-sha256');
+        if ($checksum === '' || \str_contains($checksum, ',')) {
+            // Reject a missing header of multiple values provided by the client.
             throw new UserInputException('chunk-checksum-sha256');
         }