Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import AttachmentAuthorName from './structure/AttachmentAuthorName';
import AttachmentContent from './structure/AttachmentContent';
import AttachmentDetails from './structure/AttachmentDetails';
import AttachmentInner from './structure/AttachmentInner';
import { useMaxMessageParseSize } from '../../hooks/useMaxMessageParseSize';

// TODO: remove this team collaboration
const quoteStyles = css`
Expand All @@ -38,6 +39,7 @@ type QuoteAttachmentProps = {
export const QuoteAttachment = ({ attachment }: QuoteAttachmentProps): ReactElement => {
const formatTime = useTimeAgo();
const displayAvatarPreference = useUserPreference<boolean>('displayAvatars');
const maxMessageParseSize = useMaxMessageParseSize();

return (
<>
Expand Down Expand Up @@ -71,7 +73,11 @@ export const QuoteAttachment = ({ attachment }: QuoteAttachmentProps): ReactElem
<Attachments attachments={attachment.attachments} id={attachment.attachments[0]?.title_link} />
</AttachmentInner>
)}
{attachment.md ? <MessageContentBody md={attachment.md} /> : attachment.text.substring(attachment.text.indexOf('\n') + 1)}
{attachment.text?.length <= maxMessageParseSize && attachment.md ? (
<MessageContentBody md={attachment.md} />
) : (
attachment.text.substring(attachment.text.indexOf('\n') + 1)
)}
</AttachmentDetails>
</AttachmentContent>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useSetting } from '@rocket.chat/ui-contexts';
import { useMemo } from 'react';

import { MESSAGE_PARSE_HARD_LIMIT } from '../../../lib/constants';

/**
* Returns the maximum allowed size for message parsing.
* Uses Math.min to ensure it never exceeds the hard limit to avoid performance issues.
* Always returns a number, never null or undefined.
*/
export const useMaxMessageParseSize = (): number => {
const settingValue = useSetting('Message_MaxAllowedSize', 5000);

return useMemo(() => {
const maxSize = typeof settingValue === 'number' ? settingValue : 5000;
return Math.min(maxSize, MESSAGE_PARSE_HARD_LIMIT);
}, [settingValue]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const normalizeAttachments = (attachments: MessageAttachment[], name?: string, t
});
};

export const useNormalizedMessage = <TMessage extends IMessage>(message: TMessage): MessageWithMdEnforced => {
export const useNormalizedMessage = <TMessage extends IMessage>(message: TMessage, maxMessageParseSize: number): MessageWithMdEnforced => {
const katex = useMessageListKatex();
const katexEnabled = !!katex;
const customDomains = useAutoLinkDomains();
Expand All @@ -77,6 +77,19 @@ export const useNormalizedMessage = <TMessage extends IMessage>(message: TMessag
}),
};

if (message.msg && message.msg.length > maxMessageParseSize) {
return {
...message,
md: [
{
type: 'PARAGRAPH',
value: [{ type: 'PLAIN_TEXT', value: message.msg }],
},
],
attachments: message.attachments,
};
}

const normalizedMessage = parseMessageTextToAstMarkdown(message, parseOptions, autoTranslateOptions);

if (normalizedMessage.attachments) {
Expand All @@ -88,5 +101,14 @@ export const useNormalizedMessage = <TMessage extends IMessage>(message: TMessag
}

return normalizedMessage;
}, [showColors, customDomains, katexEnabled, katex?.dollarSyntaxEnabled, katex?.parenthesisSyntaxEnabled, message, autoTranslateOptions]);
}, [
showColors,
customDomains,
katexEnabled,
katex?.dollarSyntaxEnabled,
katex?.parenthesisSyntaxEnabled,
message,
autoTranslateOptions,
maxMessageParseSize,
]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { useGoToThread } from '../../../views/room/hooks/useGoToThread';
import Emoji from '../../Emoji';
import { useShowTranslated } from '../list/MessageListContext';
import ThreadMessagePreviewBody from './threadPreview/ThreadMessagePreviewBody';
import { useMaxMessageParseSize } from '../hooks/useMaxMessageParseSize';

type ThreadMessagePreviewProps = {
message: IThreadMessage;
Expand All @@ -51,7 +52,9 @@ const ThreadMessagePreview = ({ message, showUserAvatar, sequential, ...props }:
useCountSelected();

const messageType = parentMessage.isSuccess ? MessageTypes.getType(parentMessage.data) : null;
const messageBody = useMessageBody(parentMessage.data);

const maxMessageParseSize = useMaxMessageParseSize();
const messageBody = useMessageBody(parentMessage.data, maxMessageParseSize);

const previewMessage = isParsedMessage(messageBody) ? { md: messageBody } : { msg: messageBody };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import MessageActions from '../../content/MessageActions';
import Reactions from '../../content/Reactions';
import ThreadMetrics from '../../content/ThreadMetrics';
import UrlPreviews from '../../content/UrlPreviews';
import { useMaxMessageParseSize } from '../../hooks/useMaxMessageParseSize';
import { useNormalizedMessage } from '../../hooks/useNormalizedMessage';
import { useOembedLayout } from '../../hooks/useOembedLayout';
import { useSubscriptionFromMessageQuery } from '../../hooks/useSubscriptionFromMessageQuery';
Expand All @@ -42,8 +43,9 @@ const RoomMessageContent = ({ message, unread, all, mention, searchText }: RoomM
const messageUser = { ...message.u, roles: [], ...useUserPresence(message.u._id) };
const chat = useChat();
const { t } = useTranslation();
const maxMessageParseSize = useMaxMessageParseSize();

const normalizedMessage = useNormalizedMessage(message);
const normalizedMessage = useNormalizedMessage(message, maxMessageParseSize);
const isMessageEncrypted = encrypted && normalizedMessage?.e2e === 'pending';

const quotes = normalizedMessage?.attachments?.filter(isQuoteAttachment) || [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Location from '../../content/Location';
import MessageActions from '../../content/MessageActions';
import Reactions from '../../content/Reactions';
import UrlPreviews from '../../content/UrlPreviews';
import { useMaxMessageParseSize } from '../../hooks/useMaxMessageParseSize';
import { useNormalizedMessage } from '../../hooks/useNormalizedMessage';
import { useOembedLayout } from '../../hooks/useOembedLayout';
import { useSubscriptionFromMessageQuery } from '../../hooks/useSubscriptionFromMessageQuery';
Expand All @@ -33,10 +34,11 @@ const ThreadMessageContent = ({ message }: ThreadMessageContentProps): ReactElem
const uid = useUserId();
const { enabled: readReceiptEnabled } = useMessageListReadReceipts();
const messageUser = { ...message.u, roles: [], ...useUserPresence(message.u._id) };
const maxMessageParseSize = useMaxMessageParseSize();

const { t } = useTranslation();

const normalizedMessage = useNormalizedMessage(message);
const normalizedMessage = useNormalizedMessage(message, maxMessageParseSize);

const isMessageEncrypted = encrypted && normalizedMessage?.e2e === 'pending';

Expand Down
1 change: 1 addition & 0 deletions apps/meteor/client/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export const BIO_TEXT_MAX_LENGTH = 260;
export const VIDEOCONF_STACK_MAX_USERS = 6;
export const NAVIGATION_REGION_ID = 'navigation-region';
export const MAX_FILE_SIZE_PREVIEW = 10485760; // 10MB
export const MESSAGE_PARSE_HARD_LIMIT = 10000;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useAutoLinkDomains } from './useAutoLinkDomains';
import { useMessageListAutoTranslate } from '../../../../components/message/list/MessageListContext';
import { parseMessageTextToAstMarkdown } from '../../../../lib/parseMessageTextToAstMarkdown';

export const useMessageBody = (message: IMessage | undefined): string | Root => {
export const useMessageBody = (message: IMessage | undefined, maxMessageParseSize: number): string | Root => {
const autoTranslateOptions = useMessageListAutoTranslate();
const customDomains = useAutoLinkDomains();

Expand All @@ -15,6 +15,10 @@ export const useMessageBody = (message: IMessage | undefined): string | Root =>
return '';
}

if (message.msg && message.msg.length > maxMessageParseSize) {
return message.msg;
}

if (message.md) {
const parseOptions: Options = {
customDomains,
Expand All @@ -39,5 +43,5 @@ export const useMessageBody = (message: IMessage | undefined): string | Root =>
}

return '';
}, [message, customDomains, autoTranslateOptions]);
}, [message, customDomains, autoTranslateOptions, maxMessageParseSize]);
};
Loading