#63302 closed defect (bug) (fixed)
SVG images can't be uploaded anymore due to a resizing issue
Reported by: |
|
Owned by: |
|
---|---|---|---|
Milestone: | 6.8.1 | Priority: | normal |
Severity: | normal | Version: | 6.8 |
Component: | Editor | Keywords: | has-screenshots has-patch needs-testing has-unit-tests commit fixed-major dev-reviewed |
Focuses: | Cc: |
Description
Starting with WP 6.8, SVG images can't be uploaded anymore even when they are allowed using custom code or a plugin.
To reproduce the issue:
- Add support for SVG mime type with a custom filter or install a plugin like Safe SVG
- Try to insert a SVG using the image block
- Confirm that it fails because the server cannot resize the image (see screenshot below)
I don't think it's a Gutenberg issue so I'm opening this ticket here, but maybe it is, so I will report it upstream if needed.
Attachments (2)
Change History (46)
#1
@
4 weeks ago
Note: it works when uploading it directly via the Media Library, but not directly in the editor.
#2
@
4 weeks ago
Note 2: I assigned this ticket to milestone 6.8.1 because it looks like a 6.8 issue, but I'm not 100% sure it is not a third party (plugin) issue for now. Still investigating.
#4
follow-up:
↓ 14
@
4 weeks ago
on an initial test I'm not able to reproduce (i.e., I'm able to upload an SVG directly in the Image block).
WP: 6.8
plugins: Safe SVG (and a bunch of others)
PHP: 8.3.15
PHP extensions: imagick (and a bunch of others)
I'll experiment more tomorrow and report findings.
#7
follow-up:
↓ 16
@
4 weeks ago
Hey @audrasjb,
I've identified an issue with SVG uploads in WordPress 6.8 that was introduced in changeset 60084.
After investigating changeset 60084, I found that two different implementations exist for handling unsupported image formats:|
- Media Library path (wp-admin/includes/media.php):
if ( $prevent_unsupported_uploads ) { // Check if WebP images can be edited. if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { $plupload_init['webp_upload_error'] = true; } // Check if AVIF images can be edited. if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) { $plupload_init['avif_upload_error'] = true; } }
- Block Editor path (wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php):
if ( $prevent_unsupported_uploads && isset( $files['file']['type'] ) && str_starts_with( $files['file']['type'], 'image/' ) ) { // Check if the image editor supports the type. if ( ! wp_image_editor_supports( array( 'mime_type' => $files['file']['type'] ) ) ) { return new WP_Error( 'rest_upload_image_type_not_supported', __( 'The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading.' ), array( 'status' => 400 ) ); } }
Difference between both:
- Media Library checks only WebP and AVIF specifically
- Block Editor checks all image types (anything starting with 'image/')
- Media Library sets a warning flag but allows upload
- Block Editor returns an error and prevents upload entirely
This inconsistency causes SVG files to pass in the Media Library (where they're not specifically checked) but fail in the Block Editor (where all image/* types are checked).
I’d love to hear your thoughts on this and discuss the best approach to resolving the inconsistency.
#8
@
4 weeks ago
- Keywords has-patch added
It seems that wp_get_default_extension_for_mime_type()
ignores the upload_mimes
filter because it uses wp_get_mime_types()
directly, instead of get_allowed_mime_types()
, which would include the values modified by the upload_mimes
filter.
I've fixed it with the attached patch.
#9
@
4 weeks ago
I used the following filter to enable SVG image uploads.
function allow_svg_uploads( $mimes ) { $mimes['svg'] = 'image/svg+xml'; return $mimes; } add_filter( 'upload_mimes', 'allow_svg_uploads' );
#10
@
4 weeks ago
Test Report
Description
This report validates whether the indicated patch works as expected.
Patch tested: https://core.trac.wordpress.org/attachment/ticket/63302/63302.patch
Environment
- WordPress: 6.9-alpha-20250418.114231
- PHP: 8.1.29
- Server: nginx/1.26.1
- Database: mysqli (Server: 8.0.35 / Client: mysqlnd 8.1.29)
- Browser: Firefox 136.0
- OS: macOS
- Theme: Twenty Twenty 2.9
- MU Plugins: None activated
- Plugins:
- Query Monitor 3.17.2
- Safe SVG 2.3.1
- Test Reports 1.2.0
Actual Results
- ✅ Issue resolved with patch applied and using the custom code give above to enable SVG
- ❌ Issues still exists with Safe SVG plugin with patch applied.
#11
@
4 weeks ago
@pratiklondhe Thanks for testing!
You're right, it's not working with the safe-svg plugin because it only allows SVG uploads in specific contexts using these hooks:
add_action( 'load-upload.php', array( $this, 'allow_svg_from_upload' ) ); add_action( 'load-post-new.php', array( $this, 'allow_svg_from_upload' ) ); add_action( 'load-post.php', array( $this, 'allow_svg_from_upload' ) ); add_action( 'load-site-editor.php', array( $this, 'allow_svg_from_upload' ) );
I tried calling allow_svg_from_upload()
directly before these hooks, like this:
$this->allow_svg_from_upload(); add_action( 'load-upload.php', array( $this, 'allow_svg_from_upload' ) ); add_action( 'load-post-new.php', array( $this, 'allow_svg_from_upload' ) ); add_action( 'load-post.php', array( $this, 'allow_svg_from_upload' ) ); add_action( 'load-site-editor.php', array( $this, 'allow_svg_from_upload' ) );
And it worked!
Also found where the plugin uses the upload_mimes filter:
https://plugins.trac.wordpress.org/browser/safe-svg/tags/2.3.1/safe-svg.php#L134
#12
@
4 weeks ago
- Keywords changes-requested added; has-patch removed
@dilipbheda can you add a new patch to solve the issues that @pratiklondhe comment?
#13
follow-up:
↓ 17
@
4 weeks ago
@SirLouen We can't fix this directly in the core because the issue is related to how the Safe SVG plugin handles its hooks. The hooks mentioned above don't work when uploading an image through the media block.
#14
in reply to:
↑ 4
@
4 weeks ago
Replying to pbiron:
I'll experiment more tomorrow and report findings.
OK, I've been able to reproduce the problem now...but only on a linux server, not my local Windows machine. Haven't yet figured out why it doesn't surface in Windows.
#15
@
4 weeks ago
I've now been able to reproduce in Windows.
What I've noticed is that things work (in both Windows & linux) while uploading from within an Image block when clicking on the Media Library
button and then dragging/dropping the image into the media modal, but the error message reported by JB happens when clicking on the Upload
button.
#16
in reply to:
↑ 7
;
follow-up:
↓ 18
@
4 weeks ago
Replying to sainathpoojary:
- Block Editor path (wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php):
if ( $prevent_unsupported_uploads && isset( $files['file']['type'] ) && str_starts_with( $files['file']['type'], 'image/' ) ) { // Check if the image editor supports the type. if ( ! wp_image_editor_supports( array( 'mime_type' => $files['file']['type'] ) ) ) { return new WP_Error( 'rest_upload_image_type_not_supported', __( 'The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading.' ), array( 'status' => 400 ) ); } }
Yup, this looks to be the cause. wp_image_editor_supports()
eventually calls WP_Image_Editor_GD::supports_mime_type()
or WP_Image_Editor_Imagick::supports_mime_type()
, both of which return false
for 'image/svg+xml'.
The problem is that SVG images don't need to have "responsive images generated"...so I'm not sure that calling wp_image_editor_supports()
here is the right thing to do.
Perhaps we could introduce something like a wp_image_editor_needs_to_support()
function (function name not great, suggertions welcome :-)) that applies a filter which tools like Safe SVG
could hook into and return false, and then the change in WP_REST_Attachments_Controller::create_item_permissions_check()
in 6.8 could be changed to something like:
if (
$prevent_unsupported_uploads &&
isset( $files['file']['type'] ) &&
str_starts_with( $files['file']['type'], 'image/' )
) {
// Check if the image editor supports the type.
if (
wp_image_editor_needs_to_support( array( 'mime_type' => $files['file']['type'] ) ) &&
! wp_image_editor_supports( array( 'mime_type' => $files['file']['type'] ) )
) {
return new WP_Error(
'rest_upload_image_type_not_supported',
__( 'The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading.' ),
array( 'status' => 400 )
);
}
}
thoughts?
#17
in reply to:
↑ 13
@
4 weeks ago
- Keywords needs-patch added; changes-requested removed
Replying to dilipbheda:
@SirLouen We can't fix this directly in the core because the issue is related to how the Safe SVG plugin handles its hooks. The hooks mentioned above don't work when uploading an image through the media block.
As @sainathpoojary suggested, it seems a regression in 6.8 because of one of the latest changesets. Safe SVG was working in 6.7.2
#18
in reply to:
↑ 16
@
4 weeks ago
Replying to pbiron:
thoughts?
I'm trying to think of supported image types, and afaik, only svg can't support resizing and are the only ones not being converted, so, since this is an edge case, that could simply be handled by hard-coding it directly in the function you propose (instead of having to add another filter, because ultimately its going to become a 2-filter-sequence to support SVG after this, which is not ideal from my pov.
<?php function wp_image_editor_needs_to_support( $args = array() ) { if ( isset( $args['mime_type'] ) && 'image/svg+xml' === $args['mime_type'] ) { return false; } return true; }
#19
follow-up:
↓ 21
@
4 weeks ago
@SirLouen I tend to agree, I was just trying to add some future proofing, in case some other image format in the future becomes common that doesn't need sub-sizes created.
This ticket was mentioned in PR #8714 on WordPress/wordpress-develop by @SirLouen.
4 weeks ago
#20
- Keywords has-patch added; needs-patch removed
Rethinking on the idea by @pbiron of providing some sort of filtering to provide access to SVG uploads in block editor after
https://core.trac.wordpress.org/changeset/60084
The thing is that I believe that forcing users to add more hooks (over the hooks that have to be already added for SVG compatibility), is something undesirable. Maybe hard-coding image/svg+xml
could be a little hard for future debugging or extensibility, or proofing in general. So the idea here is to provide some sort of descriptive term, that actually describes the faulting scenario: "If non-resizable formats are not considered, they won't be able to be uploaded in the block editor", by using some global constant.
Not gonna lie, I have not figured out where to best put this global const, so I've decided to place it a little at random and leave it to better criterion.
Trac ticket: https://core.trac.wordpress.org/ticket/63302
#21
in reply to:
↑ 19
@
4 weeks ago
- Keywords dev-feedback needs-testing has-testing-info added
Replying to pbiron:
@SirLouen I tend to agree, I was just trying to add some future proofing, in case some other image format in the future becomes common that doesn't need sub-sizes created.
I've come with the idea of adding a global constant for this purpose (future-proofing and providing a more descriptive idea of what's going on). As I've described, I still think that a double-filter to enable SVG is too much (moreover this is nothing helpful for the user, like the first filter, that is actually there for some sort of security purpose, in this case it's just a flaw in code, just because GD technically doesn't support resizing for a type of file that doesn't need resizing by its nature)
#22
@
4 weeks ago
- Keywords needs-unit-tests added
Todo: Adding in the current unit tests (if exist) this edge case is desirable.
#24
follow-ups:
↓ 25
↓ 26
@
4 weeks ago
After investigating changeset 60084, I found that two different implementations exist for handling unsupported image formats:|
Indeed, initially we handled only specific types, eventually we decided to include all supported types with the 'image/' prefix when running the handling check.
Media Library sets a warning flag but allows upload
The flag is later checked in JavaScript and uploading is actually prevented.
The problem is that SVG images don't need to have "responsive images generated".
This seems like the critical point: while having a mime type with an "image" prefix, SVG images are in fact "Scalable Vector Graphics" that can be scaled directly - unlike any other image type as far as I can tell.
For that reason I would prefer hard coding an exception for SVG's from the upload check, along with an inline comment to explain why, as well as a test validating the behavior.
I've come with the idea of adding a global constant for this purpose
This feels like too much, image formats change very rarely and I don't see us adding additional scalable formats in the future (are there any?). SVGs don't need resizing and should be included in this check. Is there a use case for being able to change that behavior?
#25
in reply to:
↑ 24
@
4 weeks ago
I've come with the idea of adding a global constant for this purpose
This feels like too much, image formats change very rarely and I don't see us adding additional scalable formats in the future (are there any?). SVGs don't need resizing and should be included in this check. Is there a use case for being able to change that behavior?
Yes I was exactly thinking this here, but with all the futureproofing thing, I came down to this alternative
The problem is that the check is picking supported formats from GD, and obv, SVG is not included, resulting in a failure. So, anything like "NON_RESIZABLE_FORMATS" (maybe not global, but at least local or at minimum a descriptive array variable, will help debug and come through in the future (agreeing with @pbiron) _just in case_ there is an unlikely new format in the future (instead of just hard-coding the format as I suggested previously)
Simply with this, I think this could be done. Which option do you like the most?
#26
in reply to:
↑ 24
;
follow-up:
↓ 27
@
4 weeks ago
Yes I was exactly thinking this here, but with all the futureproofing thing, I came down to this alternative
A local variable would be fine to help clarify the purpose and might be easier to document.
#27
in reply to:
↑ 26
@
4 weeks ago
Replying to adamsilverstein:
Yes I was exactly thinking this here, but with all the futureproofing thing, I came down to this alternative
A local variable would be fine to help clarify the purpose and might be easier to document.
Ok I updated the patch code with just the local variable
What it surprises me is that SVG supported by WP_Image_Editor_Imagick
https://imagemagick.org/script/formats.php#supported
Not sure why its being ignored in the `wp_image_editor_supports part
#28
@
4 weeks ago
What it surprises me is that SVG supported by WP_Image_Editor_Imagick
Interesting, does it actually resize them?
Not sure why its being ignored in the wp_image_editor_supports part
right, this should return true for your system, might be worth digging in a bit to see whats happening there.
#29
follow-up:
↓ 30
@
4 weeks ago
looks like WP_Image_Editor_Imagick::supports_mime_type()
results in a call to wp_get_default_extension_for_mime_type()
, and asks if Imagick supports the returned extension.
wp_get_default_extension_for_mime_type()
has a fixed assoc array that maps extensions to mime types. Of course, 'svg' => 'image/svg+xml'
is not in that array. However, the mime_type
filter is applied to that assoc array.
Unfortunately, Safe SVG
does not hook into that filter. And so wp_get_default_extension_for_mime_type()
can't find the right file extension to query Imagick for.
Whether Safe SVG
wants to add a callback for the mime_type
filter or not is up to them, but I don't think it really matters for 2 reasons
- SVGs don't need sub-sizes generated
- the upload should be allowed by the REST API even if Imagick isn't installed (i.e., GD is used for editing images)
#30
in reply to:
↑ 29
@
4 weeks ago
Replying to pbiron:
Whether
Safe SVG
wants to add a callback for themime_type
filter or not is up to them, but I don't think it really matters for 2 reasons
- SVGs don't need sub-sizes generated
- the upload should be allowed by the REST API even if Imagick isn't installed (i.e., GD is used for editing images)
Good catch. By adding
'svg' => 'image/svg+xml'
to the wp_get_mime_types
function, problem gets solved with Imagick
But as you said, SVG shouldn't really need resized individual files, nor Imagick should be a requirement for this purpose. Hence, I think that the solution of just using a referenced variable does the trick pretty well without the need of adding more hassle to the users with extra hooks.
Replying to adamsilverstein:
Interesting, does it actually resize them?
You can't resize them in the file editor. Probably for the same reason above. Everything is empty, the image, the sizings, etc...
right, this should return true for your system, might be worth digging in a bit to see whats happening there.
I was testing with the default docker container from wordpress-develop (for imagick support, setting PHP version to 8.2)
This ticket was mentioned in Slack in #core by jorbin. View the logs.
3 weeks ago
This ticket was mentioned in Slack in #core by jorbin. View the logs.
3 weeks ago
#33
@
3 weeks ago
@adamsilverstein Is there any chance you will be able to review the PR in time for this to get committed for 6.8.1 (RC1 next Mon, 2025-04-28, and GR next Wed 2025-04-30)?
@adamsilverstein commented on PR #8714:
3 weeks ago
#36
I added a test in https://github.com/WordPress/wordpress-develop/pull/8714/commits/f2024a05748df58f87987aa47d1d80340a8d3929 - I verified this test fails on trunk while passing on this branch.
#37
@
3 weeks ago
- Keywords has-unit-tests commit added; dev-feedback has-testing-info needs-unit-tests removed
#39
@
3 weeks ago
- Keywords dev-feedback fixed-major added
- Resolution fixed deleted
- Status changed from closed to reopened
Reopening for backport considersation
#40
@
3 weeks ago
- Keywords dev-reviewed added; dev-feedback removed
[60195] Looks good for backport.
Unable to upload any SVG file because of image resizing issue