From 27ba7968527623accab55c3800ead5311a66fbd2 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sun, 28 May 2023 14:45:22 -0500 Subject: [PATCH] Remove greentext support It uses Pleroma FE's vulnerable HTML parser --- app/soapbox/components/status-content.tsx | 12 +-- app/soapbox/utils/greentext.ts | 22 ----- app/soapbox/utils/tiny-post-html-processor.ts | 95 ------------------- 3 files changed, 1 insertion(+), 128 deletions(-) delete mode 100644 app/soapbox/utils/greentext.ts delete mode 100644 app/soapbox/utils/tiny-post-html-processor.ts diff --git a/app/soapbox/components/status-content.tsx b/app/soapbox/components/status-content.tsx index 2dcf673d6..5fc530769 100644 --- a/app/soapbox/components/status-content.tsx +++ b/app/soapbox/components/status-content.tsx @@ -4,8 +4,6 @@ import { FormattedMessage } from 'react-intl'; import { useHistory } from 'react-router-dom'; import Icon from 'soapbox/components/icon'; -import { useSoapboxConfig } from 'soapbox/hooks'; -import { addGreentext } from 'soapbox/utils/greentext'; import { onlyEmoji as isOnlyEmoji } from 'soapbox/utils/rich-content'; import { isRtl } from '../rtl'; @@ -54,8 +52,6 @@ const StatusContent: React.FC = ({ const node = useRef(null); - const { greentext } = useSoapboxConfig(); - const onMentionClick = (mention: Mention, e: MouseEvent) => { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { e.preventDefault(); @@ -134,13 +130,7 @@ const StatusContent: React.FC = ({ }); const parsedHtml = useMemo((): string => { - const html = translatable && status.translation ? status.translation.get('content')! : status.contentHtml; - - if (greentext) { - return addGreentext(html); - } else { - return html; - } + return translatable && status.translation ? status.translation.get('content')! : status.contentHtml; }, [status.contentHtml, status.translation]); if (status.content.length === 0) { diff --git a/app/soapbox/utils/greentext.ts b/app/soapbox/utils/greentext.ts deleted file mode 100644 index 70c5e05d8..000000000 --- a/app/soapbox/utils/greentext.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { processHtml } from './tiny-post-html-processor'; - -export const addGreentext = (html: string): string => { - // Copied from Pleroma FE - // https://git.pleroma.social/pleroma/pleroma-fe/-/blob/19475ba356c3fd6c54ca0306d3ae392358c212d1/src/components/status_content/status_content.js#L132 - return processHtml(html, (string) => { - try { - if (string.includes('>') && - string - .replace(/<[^>]+?>/gi, '') // remove all tags - .replace(/@\w+/gi, '') // remove mentions (even failed ones) - .trim() - .startsWith('>')) { - return `${string}`; - } else { - return string; - } - } catch (e) { - return string; - } - }); -}; diff --git a/app/soapbox/utils/tiny-post-html-processor.ts b/app/soapbox/utils/tiny-post-html-processor.ts deleted file mode 100644 index 5c740ced3..000000000 --- a/app/soapbox/utils/tiny-post-html-processor.ts +++ /dev/null @@ -1,95 +0,0 @@ -// Copied from Pleroma FE -// https://git.pleroma.social/pleroma/pleroma-fe/-/blob/develop/src/services/tiny_post_html_processor/tiny_post_html_processor.service.js - -type Processor = (html: string) => string; - -/** - * This is a tiny purpose-built HTML parser/processor. This basically detects any type of visual newline and - * allows it to be processed, useful for greentexting, mostly. - * - * known issue: doesn't handle CDATA so nested CDATA might not work well. - */ -export const processHtml = (html: string, processor: Processor): string => { - const handledTags = new Set(['p', 'br', 'div']); - const openCloseTags = new Set(['p', 'div']); - - let buffer = ''; // Current output buffer - const level: string[] = []; // How deep we are in tags and which tags were there - let textBuffer = ''; // Current line content - let tagBuffer = null; // Current tag buffer, if null = we are not currently reading a tag - - // Extracts tag name from tag, i.e. => span - const getTagName = (tag: string): string | null => { - const result = /(?:<\/(\w+)>|<(\w+)\s?[^/]*?\/?>)/gi.exec(tag); - return result && (result[1] || result[2]); - }; - - const flush = (): void => { // Processes current line buffer, adds it to output buffer and clears line buffer - if (textBuffer.trim().length > 0) { - buffer += processor(textBuffer); - } else { - buffer += textBuffer; - } - textBuffer = ''; - }; - - const handleBr = (tag: string): void => { // handles single newlines/linebreaks/selfclosing - flush(); - buffer += tag; - }; - - const handleOpen = (tag: string): void => { // handles opening tags - flush(); - buffer += tag; - level.push(tag); - }; - - const handleClose = (tag: string): void => { // handles closing tags - flush(); - buffer += tag; - if (level[level.length - 1] === tag) { - level.pop(); - } - }; - - for (let i = 0; i < html.length; i++) { - const char = html[i]; - if (char === '<' && tagBuffer === null) { - tagBuffer = char; - } else if (char !== '>' && tagBuffer !== null) { - tagBuffer += char; - } else if (char === '>' && tagBuffer !== null) { - tagBuffer += char; - const tagFull = tagBuffer; - tagBuffer = null; - const tagName = getTagName(tagFull); - if (tagName && handledTags.has(tagName)) { - if (tagName === 'br') { - handleBr(tagFull); - } else if (openCloseTags.has(tagName)) { - if (tagFull[1] === '/') { - handleClose(tagFull); - } else if (tagFull[tagFull.length - 2] === '/') { - // self-closing - handleBr(tagFull); - } else { - handleOpen(tagFull); - } - } - } else { - textBuffer += tagFull; - } - } else if (char === '\n') { - handleBr(char); - } else { - textBuffer += char; - } - } - if (tagBuffer) { - textBuffer += tagBuffer; - } - - flush(); - - return buffer; -};