Fix handling of maximum response size in ImageProxyAction
authorTim Düsterhus <duesterhus@woltlab.com>
Fri, 5 Mar 2021 12:41:00 +0000 (13:41 +0100)
committerTim Düsterhus <duesterhus@woltlab.com>
Fri, 5 Mar 2021 12:44:13 +0000 (13:44 +0100)
The previous implementation might have resulted in a truncated / broken image
which is undesirable.

wcfsetup/install/files/lib/action/ImageProxyAction.class.php

index a86b4fa88bc25507c5e2059c09e3443f7b13b306..cf00837f7b1b72d2dc32747ac8941e2bf3280f29 100644 (file)
@@ -19,8 +19,8 @@ use wcf\util\StringUtil;
 /**
  * Proxies requests for embedded images.
  *
- * @author  Matthias Schmidt
- * @copyright   2001-2019 WoltLab GmbH
+ * @author  Tim Duesterhus, Matthias Schmidt
+ * @copyright   2001-2021 WoltLab GmbH
  * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package WoltLabSuite\Core\Action
  * @since   3.0
@@ -104,6 +104,8 @@ class ImageProxyAction extends AbstractAction
                     }
 
                     // download image
+                    $file = null;
+                    $response = null;
                     try {
                         $client = HttpFactory::makeClient([
                             RequestOptions::TIMEOUT => 10,
@@ -112,7 +114,6 @@ class ImageProxyAction extends AbstractAction
                         $request = new Request('GET', $url, [
                             'via' => '1.1 wsc',
                             'accept' => 'image/*',
-                            'range' => 'bytes=0-' . (self::MAX_SIZE - 1),
                         ]);
                         $response = $client->send($request);
 
@@ -121,14 +122,22 @@ class ImageProxyAction extends AbstractAction
                             $file->write($response->getBody()->read(8192));
 
                             if ($response->getBody()->tell() >= self::MAX_SIZE) {
-                                break;
+                                throw new \DomainException(\sprintf(
+                                    'Response body is larger than the accepted maximum size (%d Bytes).',
+                                    self::MAX_SIZE
+                                ));
                             }
                         }
-                        $response->getBody()->close();
                         $file->flush();
-                        $file->close();
                     } catch (TransferException $e) {
                         throw new \DomainException('Failed to request', 0, $e);
+                    } finally {
+                        if ($response && $response->getBody()) {
+                            $response->getBody()->close();
+                        }
+                        if ($file) {
+                            $file->close();
+                        }
                     }
 
                     // check file type