Improve MIME type handling on File Upload and in Message Component (#688)
authorJames <thumbscrw@pm.me>
Sun, 14 Aug 2022 11:01:17 +0000 (12:01 +0100)
committerGitHub <noreply@github.com>
Sun, 14 Aug 2022 11:01:17 +0000 (16:31 +0530)
* 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

src/app/molecules/media/Media.jsx
src/app/molecules/message/Message.jsx
src/client/state/RoomsInput.js
src/util/mimetypes.js [new file with mode: 0644]

index 5ef25ecb5f736e22b76ef2b334d27f4cc406eec9..d7ba3854a8fa0c7aa376c5037bf94ed1cda7f4cd 100644 (file)
@@ -13,42 +13,7 @@ import DownloadSVG from '../../../../public/res/ic/outlined/download.svg';
 import ExternalSVG from '../../../../public/res/ic/outlined/external.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
-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;
-}
+import { getBlobSafeMimeType } from '../../../util/mimetypes';
 
 async function getDecryptedBlob(response, type, decryptData) {
   const arrayBuffer = await response.arrayBuffer();
index e4b68834bae1f766318747ce6091ee4bb94faa86..1e5a006eb9876e663033b8d2ef18b6f625bc1f1e 100644 (file)
@@ -37,6 +37,7 @@ import CmdIC from '../../../../public/res/ic/outlined/cmd.svg';
 import BinIC from '../../../../public/res/ic/outlined/bin.svg';
 
 import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
+import { getBlobSafeMimeType } from '../../../util/mimetypes';
 
 function PlaceholderMessage() {
   return (
@@ -621,7 +622,12 @@ function genMediaContent(mE) {
   if (typeof mediaMXC === 'undefined' || mediaMXC === '') return <span style={{ color: 'var(--bg-danger)' }}>Malformed event</span>;
 
   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'];
 
index e1d3acf9ae29ab9057d4511b8ed68ed3bce3e4e0..9b6628804a693e804293161f4c3cf40edac069fb 100644 (file)
@@ -6,6 +6,7 @@ import { math } from 'micromark-extension-math';
 import { encode } from 'blurhash';
 import { getShortcodeToEmoji } from '../../app/organisms/emoji-board/custom-emoji';
 import { mathExtensionHtml, spoilerExtension, spoilerExtensionHtml } from '../../util/markdown';
+import { getBlobSafeMimeType } from '../../util/mimetypes';
 import { sanitizeText } from '../../util/sanitize';
 import cons from './cons';
 import settings from './settings';
@@ -355,7 +356,7 @@ class RoomsInput extends EventEmitter {
   }
 
   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 = {
       mimetype: file.type,
       size: file.size,
diff --git a/src/util/mimetypes.js b/src/util/mimetypes.js
new file mode 100644 (file)
index 0000000..121ae06
--- /dev/null
@@ -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;
+}