Problem/Motivation
When template_preprocess_file_link() is called, Drupal\file\IconMimeTypes cannot handle NULL value for mimetype well. Errors out pages with file references to file with NULL as the mimetype.
Steps to reproduce
Attempt to view or edit a page with a file reference to a file with NULL as the mimetype, where a variable icon is expected to display.
Instead you'll get a white error page, with watchdog errors, e.g., TypeError: Drupal\file\IconMimeTypes::getIconClass(): Argument #1 ($mimeType) must be of type string, null given ...
The problem is that the database table file_managed allows NULL for the filemime column, but the internal methods of Drupal\file\IconMimeTypes require strings and can't handle NULL at all.
Proposed resolution
If \Drupal\file\FileInterface::getMimeType() returns NULL then default to \Drupal\Core\File\MimeType\MimeTypeGuesser::DEFAULT_MIME_TYPE with value 'application/octet-stream'.
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #6 | Screenshot 2024-09-03 at 5.37.54 PM.png | 370.05 KB | sahana _n |
| #6 | Screenshot 2024-09-03 at 5.39.41 PM.png | 710.18 KB | sahana _n |
Issue fork drupal-3469280
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:
- 3469280-default-mime-type
changes, plain diff MR !11965
- 3469280-default-mime-type-rebase
changes, plain diff MR !15490
- 3469280-File-mime-type-null
changes, plain diff MR !9407
- 3469280-default-mime-type-main
changes, plain diff MR !16258
- 3469280-drupalfileiconmimetypes-doesnt-handle
changes, plain diff MR !9399
- 11.x
compare
Comments
Comment #2
msypes commentedComment #3
asghar commentedI created the Patch for it.
Comment #6
sahana _n commentedHi,
I can reproduce the issue in Drupal 10.3.x, when I attempt to view the page with a file reference to a file with NULL as the mimetype I got this error TypeError: Drupal\file\IconMimeTypes::getIconClass(): Argument #1 ($mimeType) must be of type string, null given, called in /var/www/html/core/modules/file/file.module on line 774 in Drupal\file\IconMimeTypes::getIconClass() (line 21 of core/modules/file/src/IconMimeTypes.php).
I tested the same scenario by applying the patch provided in comment #3. The patch is applied cleanly and the error was cleared. So, I created MR with the same code changes.
I am attaching before & after screenshots for reference.
This issue is also reproducible in 11.x and was able to fix the issue with the same code changes.
I'll be happy to create MR for 11.x also if required. Please suggest how we can proceed further.
Comment #7
smustgrave commentedFixes should be against 11.x
Also we should probably do some debugging vs putting a null check. Could be masking a larger issue
Comment #9
sahana _n commentedHi,
Created an MR for 11. x.
Comment #10
kim.pepperDespite the db column allowing NULL. our API assumes there will always be a mime type. Why do you have NULL mimetypes?
Comment #11
msypes commented@kim.pepper: Are you asking me why we had NULL mimetypes in the database? I don't know. Could be from a less-than-perfect migration, from when we moved from D7. They were generally pretty old records. Did the the API always assume there was a mimetype? If not, why would the db allow it to be NULL? At any rate, the fact that it does allow NULLs should mean that the system can handle them.
Comment #12
colanOr the DB setting is wrong.
Comment #13
kim.pepper\Drupal\Core\File\MimeType\MimeTypeGuesser::guessMimeType()defaults to'application/octet-stream'if it can't determine a mime type. Would it make sense to default to this rather than empty string?Comment #14
colanWell, it's better than getting an error, right?
Comment #15
didebruThanks for the patch.
In our case it happens if we send a webform graphql mutation with a pdf attached.
Comment #19
kim.pepperAdded a default mime type constant of
\Drupal\Core\File\MimeType\MimeTypeGuesser::DEFAULT_MIME_TYPEwith value'application/octet-stream'and use that instead of empty string.Hiding some older patches and MRs.
Comment #20
kim.pepperUpdated IS to reflect latest proposed resolution.
Comment #21
kim.pepperUpdated title.
Comment #22
smustgrave commentedSeems pretty straight forward, not sure test coverage is needed here.
Comment #23
alexpottWe have other code that assumes getMimeType() returns a string...
Consider
in
This will also cause a deprection.
I think we should change \Drupal\file\Entity\File::getMimeType() to return the default value - or it could even do something like File::preCreate()... and guess the mimetype if we have a URI
We should also update the interface to tell people not to return a NULL
I think this would be a good change because then all code can rely on getMimeType() returning something sensible rather than having to deal with the NULL situation (which must be very rare given the preCreate().
Comment #25
kim.pepperRe: #23 I updated \Drupal\file\Entity\File::getMimeType() to return the default mime type if NULL, and also the docs on \Drupal\file\FileInterface::getMimeType() to match this behaviour.
Comment #26
smustgrave commentedFeedback appears to be addressed.
Comment #27
larowlanOne minor change, fine to self RTBC
Comment #28
ironnuts commentedSelf-RTBTC
Comment #29
larowlanWe can clean up a bit more here
\Drupal\file\Plugin\Field\FieldFormatter\FileMediaFormatterBase::getSourceFileshas code that checks for NULL, which is no longer possible.In searching for callers of this method, the number of places we're treating the return as a string is an excellent case to make this change.
Comment #32
didebruRebased bump.
Comment #36
fathershawnMoved changes to a new branch from main and opened a new MR
Comment #38
kim.pepperMR !16258 looks ready to me.
Comment #39
larowlanI don't think we should be changing the way File::getMimeType works - we should handle it in the theme layer
We also need a test here - thanks!
Comment #41
longwaveReduced the change to the bare minimum and added a test.
Comment #42
kim.pepperThe minimal change in the preprocess hook addresses the earlier concerns. Test coverage looks good too. Back to RTBC
Comment #43
godotislateI think we can consolidate the test into the
Drupal\Tests\file\Kernel\Formatter\FileEntityFormatterTestclass. Maybe even just modifytestFormatterFileLinkWithQueryStringto do the assertions there.Comment #44
kim.pepperConsolidated the test into FileEntityFormatterTest.
Comment #45
smustgrave commentedFeedback appears to be addressed.
Comment #48
godotislateCommitted and pushed 61a6cb2 to main and 4210702 to 11.x. Thanks!
I think this can go to 11.4.x as well, confirming with other committers.
Comment #50
godotislateConfirmed with @longwave for 11.4.x backport.