Skip to content

Commit a290116

Browse files
committed
Fix maxBytes check
1 parent 58f1a48 commit a290116

2 files changed

Lines changed: 49 additions & 5 deletions

File tree

src/FileCache.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -565,16 +565,19 @@ protected function cacheFromResource(File $file, $source, $target)
565565

566566
$cachedPath = $this->getCachedPath($file);
567567
$maxBytes = intval($this->config['max_file_size']);
568-
$bytes = stream_copy_to_stream($source, $target, $maxBytes);
569-
570-
if ($bytes === $maxBytes) {
571-
throw new Exception("The file is too large with more than {$maxBytes} bytes.");
572-
}
568+
// Copy one byte more than allowed to detect files that exceed the limit.
569+
// Using $maxBytes directly would reject files of exactly $maxBytes bytes.
570+
$copyLimit = $maxBytes >= 0 ? $maxBytes + 1 : -1;
571+
$bytes = stream_copy_to_stream($source, $target, $copyLimit);
573572

574573
if ($bytes === false) {
575574
throw new Exception('The source resource is invalid.');
576575
}
577576

577+
if ($maxBytes >= 0 && $bytes > $maxBytes) {
578+
throw new Exception("The file is too large with more than {$maxBytes} bytes.");
579+
}
580+
578581
$metadata = stream_get_meta_data($source);
579582

580583
if (array_key_exists('timed_out', $metadata) && $metadata['timed_out']) {

tests/FileCacheTest.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,22 @@ public function testGetRemoteTooLarge()
9595
$this->assertFalse(is_resource($cache->stream));
9696
}
9797

98+
public function testGetRemoteExactlyMaxSize()
99+
{
100+
$file = new GenericFile('https://files/image.jpg');
101+
$cache = new FileCacheStub([
102+
'path' => $this->cachePath,
103+
'max_file_size' => 3,
104+
]);
105+
106+
$stream = fopen('php://temp', 'r+');
107+
fwrite($stream, 'abc');
108+
rewind($stream);
109+
$cache->stream = $stream;
110+
$path = $cache->get($file, $this->noop);
111+
$this->assertEquals(3, filesize($path));
112+
}
113+
98114
public function testGetDiskDoesNotExist()
99115
{
100116
$file = new GenericFile('abc://files/image.jpg');
@@ -180,6 +196,31 @@ public function testGetDiskCloudTooLarge()
180196
$this->assertFalse(is_resource($stream));
181197
}
182198

199+
public function testGetDiskCloudExactlyMaxSize()
200+
{
201+
config(['filesystems.disks.s3' => ['driver' => 's3']]);
202+
$file = new GenericFile('s3://files/image.txt');
203+
$hash = hash('sha256', 's3://files/image.txt');
204+
205+
$stream = fopen('php://temp', 'r+');
206+
fwrite($stream, 'abc');
207+
rewind($stream);
208+
209+
$mock = Mockery::mock();
210+
$mock->shouldReceive('disk')->once()->with('s3')->andReturn($mock);
211+
$mock->shouldReceive('readStream')->once()->andReturn($stream);
212+
$this->app['filesystem'] = $mock;
213+
214+
$cache = new FileCache([
215+
'path' => $this->cachePath,
216+
'max_file_size' => 3,
217+
]);
218+
219+
$path = $cache->get($file, $this->noop);
220+
$this->assertEquals(3, filesize($path));
221+
$this->assertFalse(is_resource($stream));
222+
}
223+
183224
public function testGetThrowOnLock()
184225
{
185226
$cache = new FileCache(['path' => $this->cachePath]);

0 commit comments

Comments
 (0)