3

I have enabled SVG uploads using this code:

add_filter('upload_mimes', function($mimes) {
  $mimes['svg'] = 'image/svg+xml';
  return $mimes;
});

However, uploads of SVG files that start with the <svg> tag fail with the usual "Sorry, this file type is not permitted for security reasons." error that WordPress displays when SVG uploads are not supported.

If I add <?xml version="1.0" encoding="UTF-8" standalone="no"?> to the file, just before the opening <svg> tag, the upload succeeds.

Why is the XML tag required? Is this requirement normal in WordPress, or is there something wrong with my setup?

2 Answers 2

5

It seems that in the recent releases of WordPress, changes were made to the mime type handling to make sure that files have the extension they say they do: https://make.wordpress.org/core/2018/12/13/backwards-compatibility-breaks-in-5-0-1/

This poses an issue for SVG files without the tag in them.

SVG is actually an XML, and WordPress is now requiring to have a line such as 

<?xml version="1.0" encoding="utf-8"?>

 in an SVG file.

2
  • 1
    This answer really just repeats the information the asker already knows. They want to know why the XML tag needs to be specified for an SVG file to be recognised as the correct mime type. Jun 15, 2019 at 5:14
  • Accepting this answer because it refers to what is really a bug, that WP team is aware of, as discussed in the linked post and comments. Thanks for the link, it backs me up in my work for a client.
    – Theo d'Or
    Jun 15, 2019 at 5:45
2

To validate uploads WordPress compares the MIME type of the file to the allowed MIME types for that extension. So when the file is uploaded, WordPress checks for the file extension, .svg, and the file's MIME type. It then these against the allowed MIME type for the .svg extension. If the detected MIME type does not match, then the upload is refused. The purpose of this is to prevent dangerous files being uploaded with a misleading file extension.

The actual detection of the MIME type for the file is ultimately handled by PHP, though. So if your SVG file is not being detected as image/svg+xml, then this is because PHP doesn't recognise it as an SVG file. As you've discovered, it appears that PHP does not recognise files without the <?xml ?> tag as an SVG. It's likely that it thinks the file is an HTML file, text/html. This would be because HTML documents can contain <svg> elements, meaning only way to reliably distinguish between an HTML file with SVG and an actual SVG file is the presence of this tag.

So this is why the tag needs to be included. It's what makes it an image/svg+xml file.

3
  • Thanks for the explanation, though I'm not sure just how correct it is. The issue seems to be less clear cut. Until encountering the WP uploading issue, my impression from reading was that an SVG file without the XML prolog is a valid SVG file. At any rate, I've accepted the other answer as it is more WP specific and links to the discussion on the subject.
    – Theo d'Or
    Jun 15, 2019 at 5:49
  • 1
    It might be a valid file, but PHP might not necessarily recognise it as an image/svg+xml, specifically. Regardless of the specifics of SVG files it remains true that the mime type is determined by PHP, not WordPress, so PHP/your web server is what’s at fault here. Jun 15, 2019 at 6:03
  • 1
    This answer in combination with that of @twelvell gives the complete picture. WordPress switched to checking the MIME type of files, which under the hood means it now uses PHP's mime_content_type(), which requires SVG files to have the XML declaration (<?xml ...>).
    – Jacob
    Aug 27, 2021 at 14:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.