Improve MIME type handling on File Upload and in Message Component (#688)

* move allowed MIME types to own util file

* add check for safe MIME type before choosing how to upload

* check for allowed blob type to decide what component to load

* re-add check for safe mimetype

* fix bracket positioning
This commit is contained in:
James 2022-08-14 12:01:17 +01:00 committed by GitHub
parent af69955801
commit a417980a81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 38 deletions

View file

@ -13,42 +13,7 @@ import DownloadSVG from '../../../../public/res/ic/outlined/download.svg';
import ExternalSVG from '../../../../public/res/ic/outlined/external.svg'; import ExternalSVG from '../../../../public/res/ic/outlined/external.svg';
import PlaySVG from '../../../../public/res/ic/outlined/play.svg'; import PlaySVG from '../../../../public/res/ic/outlined/play.svg';
// https://github.com/matrix-org/matrix-react-sdk/blob/cd15e08fc285da42134817cce50de8011809cd53/src/utils/blobs.ts#L73 import { getBlobSafeMimeType } from '../../../util/mimetypes';
const ALLOWED_BLOB_MIMETYPES = [
'image/jpeg',
'image/gif',
'image/png',
'image/apng',
'image/webp',
'image/avif',
'video/mp4',
'video/webm',
'video/ogg',
'video/quicktime',
'audio/mp4',
'audio/webm',
'audio/aac',
'audio/mpeg',
'audio/ogg',
'audio/wave',
'audio/wav',
'audio/x-wav',
'audio/x-pn-wav',
'audio/flac',
'audio/x-flac',
];
function getBlobSafeMimeType(mimetype) {
if (!ALLOWED_BLOB_MIMETYPES.includes(mimetype)) {
return 'application/octet-stream';
}
// Required for Chromium browsers
if (mimetype === 'video/quicktime') {
return 'video/mp4';
}
return mimetype;
}
async function getDecryptedBlob(response, type, decryptData) { async function getDecryptedBlob(response, type, decryptData) {
const arrayBuffer = await response.arrayBuffer(); const arrayBuffer = await response.arrayBuffer();

View file

@ -37,6 +37,7 @@ import CmdIC from '../../../../public/res/ic/outlined/cmd.svg';
import BinIC from '../../../../public/res/ic/outlined/bin.svg'; import BinIC from '../../../../public/res/ic/outlined/bin.svg';
import { confirmDialog } from '../confirm-dialog/ConfirmDialog'; import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
import { getBlobSafeMimeType } from '../../../util/mimetypes';
function PlaceholderMessage() { function PlaceholderMessage() {
return ( return (
@ -621,7 +622,12 @@ function genMediaContent(mE) {
if (typeof mediaMXC === 'undefined' || mediaMXC === '') return <span style={{ color: 'var(--bg-danger)' }}>Malformed event</span>; if (typeof mediaMXC === 'undefined' || mediaMXC === '') return <span style={{ color: 'var(--bg-danger)' }}>Malformed event</span>;
let msgType = mE.getContent()?.msgtype; let msgType = mE.getContent()?.msgtype;
if (mE.getType() === 'm.sticker') msgType = 'm.sticker'; const safeMimetype = getBlobSafeMimeType(mContent.info?.mimetype);
if (mE.getType() === 'm.sticker') {
msgType = 'm.sticker';
} else if (safeMimetype === 'application/octet-stream') {
msgType = 'm.file';
}
const blurhash = mContent?.info?.['xyz.amorgan.blurhash']; const blurhash = mContent?.info?.['xyz.amorgan.blurhash'];

View file

@ -6,6 +6,7 @@ import { math } from 'micromark-extension-math';
import { encode } from 'blurhash'; import { encode } from 'blurhash';
import { getShortcodeToEmoji } from '../../app/organisms/emoji-board/custom-emoji'; import { getShortcodeToEmoji } from '../../app/organisms/emoji-board/custom-emoji';
import { mathExtensionHtml, spoilerExtension, spoilerExtensionHtml } from '../../util/markdown'; import { mathExtensionHtml, spoilerExtension, spoilerExtensionHtml } from '../../util/markdown';
import { getBlobSafeMimeType } from '../../util/mimetypes';
import { sanitizeText } from '../../util/sanitize'; import { sanitizeText } from '../../util/sanitize';
import cons from './cons'; import cons from './cons';
import settings from './settings'; import settings from './settings';
@ -355,7 +356,7 @@ class RoomsInput extends EventEmitter {
} }
async sendFile(roomId, file) { async sendFile(roomId, file) {
const fileType = file.type.slice(0, file.type.indexOf('/')); const fileType = getBlobSafeMimeType(file.type).slice(0, file.type.indexOf('/'));
const info = { const info = {
mimetype: file.type, mimetype: file.type,
size: file.size, size: file.size,

37
src/util/mimetypes.js Normal file
View file

@ -0,0 +1,37 @@
// https://github.com/matrix-org/matrix-react-sdk/blob/cd15e08fc285da42134817cce50de8011809cd53/src/utils/blobs.ts
export const ALLOWED_BLOB_MIMETYPES = [
'image/jpeg',
'image/gif',
'image/png',
'image/apng',
'image/webp',
'image/avif',
'video/mp4',
'video/webm',
'video/ogg',
'video/quicktime',
'audio/mp4',
'audio/webm',
'audio/aac',
'audio/mpeg',
'audio/ogg',
'audio/wave',
'audio/wav',
'audio/x-wav',
'audio/x-pn-wav',
'audio/flac',
'audio/x-flac',
];
export function getBlobSafeMimeType(mimetype) {
if (!ALLOWED_BLOB_MIMETYPES.includes(mimetype)) {
return 'application/octet-stream';
}
// Required for Chromium browsers
if (mimetype === 'video/quicktime') {
return 'video/mp4';
}
return mimetype;
}