What happened?
Steps to reproduce
- Have an image on disk under the local-images adapter root whose filename contains non-ASCII characters, e.g. erik_schön.jpg. (Most easily reproduced by uploading via FTP, or by having such a file from a pre-Joomla-4 migration. Uploading through the media manager
itself won't reproduce because getSafeName() would transliterate the name on the way in.)
- Open the file in the media manager's built-in image editor.
- Make any edit (rotate, crop, …) and click Save.
Version
5.4
Expected result
The edited bytes are written back to the same file on disk.
Actual result
The PUT to index.php?option=com_media&task=api.files&path=:/path/to/.jpg returns HTTP 403 with this JSON:
{
"success": false,
"message": "The file could not be uploaded.",
"messages": { "error": ["The file name must only contain alphanumeric characters and no spaces."] }
}
The file on disk is unchanged.
System Information
No response
Additional Comments
Root cause
LocalAdapter::checkContent() (plugins/filesystem/local/src/Adapter/LocalAdapter.php:860) is called from both createFile() and updateFile(). It invokes MediaHelper::canUpload() with the existing on-disk filename:
$can = $helper->canUpload(['name' => $name, ...], 'com_media');
MediaHelper::canUpload() (libraries/src/Helper/MediaHelper.php:218) then runs:
if ($file['name'] !== File::makeSafe($file['name'])) {
$app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNFILENAME'), 'error');
return false;
}
File::makeSafe() (libraries/src/Filesystem/File.php:99-101) transliterates non-ASCII characters to ASCII via Any-Latin; Latin-ASCII + iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", …), so erik_schön.jpg !== erik_schon.jpg, the guard fires, canUpload returns false, and
checkContent throws a 403 with JLIB_MEDIA_ERROR_UPLOAD_INPUT.
The check is correct for normal uploads (it's why files with non-ASCII names can't be uploaded through the media manager in the first place — that's by design). In-place edits, where the filename is already fixed on disk and not being changed by the operation need to work with the actual filename. The size, MIME and executable-extension checks performed by the same canUpload() call should still run; only the filename equality test is inappropriate here.
What happened?
Steps to reproduce
itself won't reproduce because getSafeName() would transliterate the name on the way in.)
Version
5.4
Expected result
The edited bytes are written back to the same file on disk.
Actual result
The PUT to index.php?option=com_media&task=api.files&path=:/path/to/.jpg returns HTTP 403 with this JSON:
{
"success": false,
"message": "The file could not be uploaded.",
"messages": { "error": ["The file name must only contain alphanumeric characters and no spaces."] }
}
The file on disk is unchanged.
System Information
No response
Additional Comments
Root cause
LocalAdapter::checkContent()(plugins/filesystem/local/src/Adapter/LocalAdapter.php:860) is called from bothcreateFile()andupdateFile(). It invokesMediaHelper::canUpload()with the existing on-disk filename:MediaHelper::canUpload()(libraries/src/Helper/MediaHelper.php:218) then runs:File::makeSafe()(libraries/src/Filesystem/File.php:99-101) transliterates non-ASCII characters to ASCII via Any-Latin; Latin-ASCII + iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", …), soerik_schön.jpg !== erik_schon.jpg, the guard fires,canUploadreturns false, andcheckContent throws a 403 with JLIB_MEDIA_ERROR_UPLOAD_INPUT.
The check is correct for normal uploads (it's why files with non-ASCII names can't be uploaded through the media manager in the first place — that's by design). In-place edits, where the filename is already fixed on disk and not being changed by the operation need to work with the actual filename. The size, MIME and executable-extension checks performed by the same
canUpload()call should still run; only the filename equality test is inappropriate here.