From df391968d8d552e1810c2c5eb4e185ead917686f Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Wed, 21 May 2025 17:28:13 +0530 Subject: [PATCH] Fix crash on malformed blurhash (#2331) --- src/app/components/message/content/ImageContent.tsx | 3 ++- src/app/components/message/content/VideoContent.tsx | 3 ++- src/app/utils/blurHash.ts | 12 +++++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/app/components/message/content/ImageContent.tsx b/src/app/components/message/content/ImageContent.tsx index 69c7ade..cc0c0c9 100644 --- a/src/app/components/message/content/ImageContent.tsx +++ b/src/app/components/message/content/ImageContent.tsx @@ -30,6 +30,7 @@ import { stopPropagation } from '../../../utils/keyboard'; import { decryptFile, downloadEncryptedMedia, mxcUrlToHttp } from '../../../utils/matrix'; import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; import { ModalWide } from '../../../styles/Modal.css'; +import { validBlurHash } from '../../../utils/blurHash'; type RenderViewerProps = { src: string; @@ -77,7 +78,7 @@ export const ImageContent = as<'div', ImageContentProps>( ) => { const mx = useMatrixClient(); const useAuthentication = useMediaAuthentication(); - const blurHash = info?.[MATRIX_BLUR_HASH_PROPERTY_NAME]; + const blurHash = validBlurHash(info?.[MATRIX_BLUR_HASH_PROPERTY_NAME]); const [load, setLoad] = useState(false); const [error, setError] = useState(false); diff --git a/src/app/components/message/content/VideoContent.tsx b/src/app/components/message/content/VideoContent.tsx index f6ddbb5..0505f20 100644 --- a/src/app/components/message/content/VideoContent.tsx +++ b/src/app/components/message/content/VideoContent.tsx @@ -31,6 +31,7 @@ import { mxcUrlToHttp, } from '../../../utils/matrix'; import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; +import { validBlurHash } from '../../../utils/blurHash'; type RenderVideoProps = { title: string; @@ -68,7 +69,7 @@ export const VideoContent = as<'div', VideoContentProps>( ) => { const mx = useMatrixClient(); const useAuthentication = useMediaAuthentication(); - const blurHash = info.thumbnail_info?.[MATRIX_BLUR_HASH_PROPERTY_NAME]; + const blurHash = validBlurHash(info.thumbnail_info?.[MATRIX_BLUR_HASH_PROPERTY_NAME]); const [load, setLoad] = useState(false); const [error, setError] = useState(false); diff --git a/src/app/utils/blurHash.ts b/src/app/utils/blurHash.ts index 3fe1ade..566f6d1 100644 --- a/src/app/utils/blurHash.ts +++ b/src/app/utils/blurHash.ts @@ -1,4 +1,4 @@ -import { encode } from 'blurhash'; +import { encode, isBlurhashValid } from 'blurhash'; export const encodeBlurHash = ( img: HTMLImageElement | HTMLVideoElement, @@ -17,3 +17,13 @@ export const encodeBlurHash = ( const data = context.getImageData(0, 0, canvas.width, canvas.height); return encode(data.data, data.width, data.height, 4, 4); }; + +export const validBlurHash = (hash?: string): string | undefined => { + if (typeof hash === 'string') { + const validity = isBlurhashValid(hash); + + return validity.result ? hash : undefined; + } + + return undefined; +};