diff --git a/ts/components/CompositionInput.tsx b/ts/components/CompositionInput.tsx index ae0a7a5a5f..0e5849d00c 100644 --- a/ts/components/CompositionInput.tsx +++ b/ts/components/CompositionInput.tsx @@ -81,6 +81,7 @@ import { FUN_STATIC_EMOJI_CLASS } from './fun/FunEmoji'; import { useFunEmojiSearch } from './fun/useFunEmojiSearch'; import type { EmojiCompletionOptions } from '../quill/emoji/completion'; import { useFunEmojiLocalizer } from './fun/useFunEmojiLocalizer'; +import { MAX_BODY_ATTACHMENT_BYTE_LENGTH } from '../util/longAttachment'; const log = createLogger('CompositionInput'); @@ -158,7 +159,6 @@ export type Props = Readonly<{ onCloseLinkPreview?(conversationId: string): unknown; }>; -const MAX_LENGTH = 64 * 1024; const BASE_CLASS_NAME = 'module-composition-input'; export function CompositionInput(props: Props): React.ReactElement { @@ -612,7 +612,7 @@ export function CompositionInput(props: Props): React.ReactElement { node.attributes.removeNamedItem('style'); } - if (text.length > MAX_LENGTH) { + if (Buffer.byteLength(text) > MAX_BODY_ATTACHMENT_BYTE_LENGTH) { quill.history.undo(); propsRef.current.onTextTooLong(); return; diff --git a/ts/jobs/helpers/sendNormalMessage.ts b/ts/jobs/helpers/sendNormalMessage.ts index 574980a4fa..ae5f5008e0 100644 --- a/ts/jobs/helpers/sendNormalMessage.ts +++ b/ts/jobs/helpers/sendNormalMessage.ts @@ -55,7 +55,11 @@ import { } from '../../util/editHelpers'; import { getMessageSentTimestamp } from '../../util/getMessageSentTimestamp'; import { isSignalConversation } from '../../util/isSignalConversation'; -import { isBodyTooLong, trimBody } from '../../util/longAttachment'; +import { + isBodyTooLong, + MAX_BODY_ATTACHMENT_BYTE_LENGTH, + trimBody, +} from '../../util/longAttachment'; import { markFailed, saveErrorsOnMessage, @@ -607,6 +611,15 @@ async function getMessageSendData({ targetTimestamp, }); + if ( + maybeLongAttachment && + maybeLongAttachment.size > MAX_BODY_ATTACHMENT_BYTE_LENGTH + ) { + throw new Error( + `Body attachment too long for send: ${maybeLongAttachment.size}` + ); + } + if (body && isBodyTooLong(body)) { body = trimBody(body); } diff --git a/ts/util/longAttachment.ts b/ts/util/longAttachment.ts index 993faef21c..6ecccd60d0 100644 --- a/ts/util/longAttachment.ts +++ b/ts/util/longAttachment.ts @@ -3,16 +3,22 @@ import { unicodeSlice } from './unicodeSlice'; -const LONG_ATTACHMENT_LIMIT = 2048; +const KIBIBYTE = 1024; +const MAX_MESSAGE_BODY_BYTE_LENGTH = 2 * KIBIBYTE; + +export const MAX_BODY_ATTACHMENT_BYTE_LENGTH = 64 * KIBIBYTE; export function isBodyTooLong( body: string, - length = LONG_ATTACHMENT_LIMIT + length = MAX_MESSAGE_BODY_BYTE_LENGTH ): boolean { return Buffer.byteLength(body) > length; } -export function trimBody(body: string, length = LONG_ATTACHMENT_LIMIT): string { +export function trimBody( + body: string, + length = MAX_MESSAGE_BODY_BYTE_LENGTH +): string { const sliced = unicodeSlice(body, 0, length); if (sliced.length > 0) {