In several places, Mime Mail needs to determine if a URL or a file attachment is an image. Currently, a regular expression is used to do this. This is a problem for several reasons:

  • Regular expressions are hard to maintain because they are prone to being inaccurate, especially in the absence of good testing (and these aren't tested at all in the current version of Mime Mail ...)
  • The regular expression currently only recognizes four image file extensions: .png, .gif, .jpg, and .jpeg, so it is incomplete. It is in practice impossible to keep this list up-to-date and complete, so we will always be behind the curve if we continue to use this.

Drupal 8 has a perfectly good service 'file.mime_type.guesser' which is an implementation of the Symfony MimeTypeGuesserInterface. This service provides a way to determine the MIME type of a file that is way more capable than our simple regular expression, and since it is core Drupal / Symfony it is being used and updated and supported by way more people. (Mime Mail's regular expression hasn't changed in 10 years).

A future problem is that Mime Mail is currently trying to determine the MIME type in four distinct places - we should eventually refactor this code so that doesn't have to happen, but the first step is to do the type determination the same way in all four places so that at least we always get the same answer.

Issue fork mimemail-3155325

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

TR created an issue. See original summary.

tr’s picture

Status: Active » Needs review
StatusFileSize
new3.62 KB

Status: Needs review » Needs work

The last submitted patch, 2: 3155325-2-type-guesser.patch, failed testing. View results

tr’s picture

The test correctly fails because the mime type guesser only accepts paths, not URLs with query strings on the end. This points out a problem with URL handling in Mime Mail, because we freely intermix relative paths, absolute paths, stream wrapper paths, URLs, URIs, etc. and perform our own custom parsing on all of these.

We need to make this uniform and use core Drupal classes to handle parsing of the URL parts. But that's another issue. Here, we just need to make sure we pass a valid value to the type guesser so that it can do its job.

tr’s picture

Status: Needs work » Needs review
StatusFileSize
new3.61 KB

Here's a re-roll of the patch in #2 against the current HEAD. I expect the tests will still fail for the reasons I described in #4, because nothing has been done to fix that.

Status: Needs review » Needs work

The last submitted patch, 5: 3155325-5-type-guesser.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

tr’s picture

StatusFileSize
new4.49 KB
new1015 bytes

Corrected two @var declarations to use the current version of Symfony.

tr’s picture

StatusFileSize
new4.99 KB
new1.7 KB

Have to also update guess() to be guessMimeType() for D10. Because guess() was deprecated in D9.1 this change will also work with our current minimum core version of 9.3.

Note the fact that the D9 tests did not catch this is a direct result of our lack of testing for certain key methods. In this case, guess() is used in MimeMailFormatHelper::mimeMailFile and MimeMailFormatHelper::mimeMailMultipartBody, but neither of those are tested. See:
#3145400: Add test cases for MimeMailFormatHelper::mimeMailFile()
#3145401: Add test cases for MimeMailFormatHelper::mimeMailMultipartBody()

tr’s picture

OK, #8 fixed the new errors related to guess(), so we're back to needing to fix the one test failure described in #4.

tr’s picture

Status: Needs work » Needs review
StatusFileSize
new1.5 KB
new5.3 KB

Re-rolled against HEAD and included a fix for #4.

This issue is blocking a D10 release because MimeTypeGuesserInterface::guess() has been removed in D10. This patch replaces that usage.

Status: Needs review » Needs work

The last submitted patch, 10: 3155325-10-type-guesser.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

tr’s picture

Well that did fix the issue from #4 but it caused another issue, which I will now have to look into.

tr’s picture

Version: 8.x-1.x-dev » 2.0.x-dev

scott_earnest made their first commit to this issue’s fork.

scott_earnest’s picture

Updates rolled into issue fork.

Unfortunately, PHPUnit is throwing an error, need to look into this:
https://git.drupalcode.org/issue/mimemail-3155325/-/jobs/2799865
---- Drupal\Tests\mimemail\Functional\MimeMailWebTest ----

Otherwise this works for me in Drupal 10 and Drupal 11.

scott_earnest’s picture

jfurnas’s picture

Even with this patch in place, I am still getting the same error message related to using 'guess' as the method name.

luke.leber’s picture

So to summarize the immediate problem to move this forward, when trying to determine if something is an image, there's a string input that's basically in a random format. It might be a scheme://path.extesion?query#fragment with any part present, not present, or even malformed. Anticipate that the string might even be something like a string of random emojis and some unprintable / null control characters, or even characters that aren't allowed in a URL at all that may or may not be encoded - Some of these methods seem to be general utility methods which may be called outside of Mime Mail given that the utility class is not marked @internal!.

This string has to be either:

  1. Massaged into something that the mime type guesser won't choke on
  2. Assumed to probably not be an image if things are too messed up to pass to the guesser

Even given Drupal's URL utilities, that's likely extremely tricky as this issue stands. IMO it might be worth checking the various call sites and seeing if there's an opportunity to normalize things. That would of course likely need a B/C break in the utility class, but I do fear that tackling the problem naively may be a very disturbing game of whack-a-mole in the wild. Passing a nullable \Drupal\Core\Url object into the various utility methods would make this a trivial problem to solve.

drupgirl’s picture

This issue could reduce its scope by remove the work that has been accomplished in https://www.drupal.org/project/mimemail/issues/3155325.

andras_szilagyi made their first commit to this issue’s fork.

andras_szilagyi’s picture

I've added more test coverage for us to see the way mimeMailUrl behaves with the scenarios mentioned in #19, after I refactored the image detection using a centralized method that uses more core API

andras_szilagyi’s picture

Status: Needs work » Needs review

ready for review

saidatom’s picture

Status: Needs review » Reviewed & tested by the community

Great! Looks good, moving to RTBC.

mark_fullmer’s picture

Assigned: Unassigned » mark_fullmer

Assigning to myself for a second review...

mark_fullmer’s picture

Status: Reviewed & tested by the community » Fixed

Thanks, all! I functionally tested these improvements, and the new test coverage looks comprehensive. This is merge and will be included in the next release.

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.