Skip to content

Commit 53707a0

Browse files
committed
Add disk support to file sanitization and enhance error handling
1 parent 4470b25 commit 53707a0

3 files changed

Lines changed: 49 additions & 19 deletions

File tree

composer.lock

Lines changed: 6 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/FileSanitizerManager.php

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Portavice\LaravelFileSanitizer;
44

55
use Illuminate\Http\UploadedFile;
6+
use Illuminate\Support\Facades\Storage;
7+
use RuntimeException;
68
use SytxLabs\FileSanitizer\FileSanitizer as BaseFileSanitizer;
79

810
class FileSanitizerManager
@@ -16,14 +18,47 @@ public function getSanitizer(): BaseFileSanitizer
1618
return $this->sanitizer;
1719
}
1820

19-
public function process(string $inputPath, ?string $outputPath = null, ?bool $sanitizeAlways = null): array
21+
public function process(string $inputPath, ?string $outputPath = null, ?bool $sanitizeAlways = null, ?string $diskName = null): array
2022
{
21-
return $this->sanitizer->process($inputPath, $outputPath, $sanitizeAlways ?? (bool) ($this->config['sanitize_always'] ?? false));
23+
return $this->run($inputPath, $outputPath, $sanitizeAlways ?? (bool) ($this->config['sanitize_always'] ?? false), $diskName);
2224
}
2325

24-
public function sanitizeAlways(string $inputPath, ?string $outputPath = null): array
26+
public function sanitizeAlways(string $inputPath, ?string $outputPath = null, ?string $diskName = null): array
2527
{
26-
return method_exists($this->sanitizer, 'sanitizeAlways') ? $this->sanitizer->sanitizeAlways($inputPath, $outputPath) : $this->sanitizer->process($inputPath, $outputPath, true);
28+
return $this->run($inputPath, $outputPath, true, $diskName);
29+
}
30+
31+
protected function run(string $inputPath, ?string $outputPath, bool $sanitizeAlways, ?string $diskName): array
32+
{
33+
if ($diskName === null) {
34+
return $sanitizeAlways && method_exists($this->sanitizer, 'sanitizeAlways') ? $this->sanitizer->sanitizeAlways($inputPath, $outputPath) : $this->sanitizer->process($inputPath, $outputPath, $sanitizeAlways);
35+
}
36+
$disk = Storage::disk($diskName);
37+
if (! $disk->exists($inputPath)) {
38+
throw new RuntimeException("Input file [{$inputPath}] was not found on disk [{$diskName}].");
39+
}
40+
$tmpInput = tempnam(sys_get_temp_dir(), 'fs_in_');
41+
$tmpOutput = tempnam(sys_get_temp_dir(), 'fs_out_');
42+
if ($tmpInput === false || $tmpOutput === false) {
43+
if ($tmpInput !== false) {
44+
@unlink($tmpInput);
45+
}
46+
if ($tmpOutput !== false) {
47+
@unlink($tmpOutput);
48+
}
49+
throw new RuntimeException('Unable to create temporary files.');
50+
}
51+
try {
52+
file_put_contents($tmpInput, $disk->get($inputPath));
53+
$result = $sanitizeAlways && method_exists($this->sanitizer, 'sanitizeAlways') ? $this->sanitizer->sanitizeAlways($tmpInput, $tmpOutput) : $this->sanitizer->process($tmpInput, $tmpOutput, $sanitizeAlways);
54+
if ($outputPath !== null && is_file($tmpOutput)) {
55+
$disk->put($outputPath, file_get_contents($tmpOutput));
56+
}
57+
return $result;
58+
} finally {
59+
@unlink($tmpInput);
60+
@unlink($tmpOutput);
61+
}
2762
}
2863

2964
public function processUploadedFile(UploadedFile $file, ?string $outputPath = null, ?bool $sanitizeAlways = null): array

src/FileSanitizerServiceProvider.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@ public function boot(): void
3434
Validator::replacer('safe_file', fn (string $message, string $attribute): string => str_replace(':attribute', $attribute, $message ?: 'The :attribute contains unsafe content.'));
3535

3636
if (method_exists(UploadedFile::class, 'macro')) {
37-
UploadedFile::macro('sanitize', function (?string $targetPath = null, bool $sanitizeAlways = false) {
37+
UploadedFile::macro('sanitize', function (?string $targetPath = null, bool $sanitizeAlways = false, ?string $diskName = null) {
3838
/** @var UploadedFile $this */
3939
$manager = app(FileSanitizerManager::class);
40-
4140
$sourcePath = $this->getRealPath();
4241
if ($sourcePath === false) {
4342
throw new RuntimeException('Uploaded file has no readable temporary path.');
@@ -48,21 +47,18 @@ public function boot(): void
4847
if ($targetPath === false) {
4948
throw new RuntimeException('Unable to create temporary file for sanitized upload.');
5049
}
51-
5250
if ($extension !== '') {
5351
$renamed = $targetPath . '.' . $extension;
54-
if (!@rename($targetPath, $renamed)) {
52+
if (! @rename($targetPath, $renamed)) {
5553
throw new RuntimeException('Unable to prepare sanitized temporary file.');
5654
}
5755
$targetPath = $renamed;
5856
}
5957
}
60-
61-
$result = $manager->process($sourcePath, $targetPath, $sanitizeAlways);
62-
$sanitizedFile = new UploadedFile($targetPath, $this->getClientOriginalName(), $this->getMimeType() ?: $this->getClientMimeType(), null, true);
58+
$result = $manager->process($sourcePath, $targetPath, $sanitizeAlways, $diskName);
6359
return [
6460
'result' => $result,
65-
'file' => $sanitizedFile,
61+
'file' => new UploadedFile($targetPath, $this->getClientOriginalName(), $this->getMimeType() ?: $this->getClientMimeType(), null, true),
6662
'path' => $targetPath,
6763
];
6864
});

0 commit comments

Comments
 (0)