diff --git a/src/Assets/Uploader.php b/src/Assets/Uploader.php index dc4b0d49c6..95acf2e4b9 100644 --- a/src/Assets/Uploader.php +++ b/src/Assets/Uploader.php @@ -58,7 +58,7 @@ private function write($sourcePath, $destinationPath) { $stream = fopen($sourcePath, 'r'); - if (config('statamic.assets.svg_sanitization_on_upload', true) && Str::endsWith($destinationPath, '.svg')) { + if (config('statamic.assets.svg_sanitization_on_upload', true) && Str::of($destinationPath)->lower()->endsWith('.svg')) { $stream = Svg::sanitize(stream_get_contents($stream)); } diff --git a/tests/Assets/AssetTest.php b/tests/Assets/AssetTest.php index 516df9febd..8598e9f10b 100644 --- a/tests/Assets/AssetTest.php +++ b/tests/Assets/AssetTest.php @@ -2089,6 +2089,33 @@ public function it_does_not_sanitizes_svgs_on_upload_when_behaviour_is_disabled( $this->assertStringContainsString('', $asset->contents()); } + #[Test] + public function it_sanitizes_svgs_on_upload_regardless_of_extension_case() + { + Event::fake(); + + // Disable filename lowercasing so the uppercase extension actually + // reaches the disk, otherwise it'd be normalized before we could + // prove the sanitization check itself is case insensitive. + config()->set('statamic.assets.lowercase', false); + + $asset = (new Asset)->container($this->container)->path('path/to/asset.SVG')->syncOriginal(); + + Facades\AssetContainer::shouldReceive('findByHandle')->with('test_container')->andReturn($this->container); + Storage::disk('test')->assertMissing('path/to/asset.SVG'); + + $return = $asset->upload(UploadedFile::fake()->createWithContent('asset.SVG', '')); + + $this->assertEquals($asset, $return); + Storage::disk('test')->assertExists('path/to/asset.SVG'); + $this->assertEquals('path/to/asset.SVG', $asset->path()); + + // Ensure the inline scripts were stripped out. + $this->assertStringNotContainsString('contents()); + $this->assertStringNotContainsString('Bad stuff could go in here.', $asset->contents()); + $this->assertStringNotContainsString('', $asset->contents()); + } + public static function nonGlideableFileExtensionsProvider() { return [ diff --git a/tests/Feature/Fieldtypes/FilesTest.php b/tests/Feature/Fieldtypes/FilesTest.php index 5b23a7069c..1f99a53ed5 100644 --- a/tests/Feature/Fieldtypes/FilesTest.php +++ b/tests/Feature/Fieldtypes/FilesTest.php @@ -125,6 +125,32 @@ public function it_uploads_a_file_to_the_configured_disk_and_path() $localDisk->assertMissing('statamic/file-uploads/1671484636/test.txt'); } + #[Test] + public function it_sanitizes_svgs_on_upload_regardless_of_extension_case() + { + $disk = Storage::fake('local'); + + Date::setTestNow(Date::createFromTimestamp(1671484636, config('app.timezone'))); + + $file = UploadedFile::fake()->createWithContent('test.SVG', ''); + + $this + ->actingAs(tap(User::make()->makeSuper())->save()) + ->post('/cp/fieldtypes/files/upload', ['file' => $file]) + ->assertOk() + ->assertJson([ + 'data' => [ + 'id' => $path = '1671484636/test.SVG', + ], + ]); + + $contents = $disk->get('statamic/file-uploads/'.$path); + + $this->assertStringNotContainsString('assertStringNotContainsString('Bad stuff could go in here.', $contents); + $this->assertStringNotContainsString('', $contents); + } + #[Test] public function it_replaces_dimensions_rule() {