diff --git a/src/app/components/math/KaTeX.tsx b/src/app/components/math/KaTeX.tsx index ebaf17e7d..26d27cd68 100644 --- a/src/app/components/math/KaTeX.tsx +++ b/src/app/components/math/KaTeX.tsx @@ -21,12 +21,31 @@ type KaTeXProps = { * inline (in its error colour) rather than throwing. The HTML returned by * `renderToString` is produced by our own trusted call from a fixed options * object — it is safe to inject via `dangerouslySetInnerHTML`. + * + * `maxSize`/`maxExpand` cap how large a single glyph (`\\rule`, etc.) or macro + * expansion remote LaTeX can request, and `trust: false` disables commands + * that can embed arbitrary HTML/URLs (e.g. `\\includegraphics`, `\\href`) — + * without these a hostile `$$...$$` from a remote message can DoS or (via + * `trust`) inject unsafe links (Gitea #65). `strict: 'ignore'` keeps unknown- + * but-harmless LaTeX from spamming the console as before. Extremely long + * source is rendered as plain text rather than handed to KaTeX at all. */ +const MAX_LATEX_LENGTH = 5000; + export default function KaTeX({ latex, displayMode = false }: KaTeXProps) { + if (latex.length > MAX_LATEX_LENGTH) { + const Plain = displayMode ? 'div' : 'span'; + return {latex}; + } + const html = katex.renderToString(latex, { displayMode, throwOnError: false, output: 'htmlAndMathml', + maxSize: 10, + maxExpand: 100, + trust: false, + strict: 'ignore', }); const Wrapper = displayMode ? 'div' : 'span'; @@ -34,7 +53,7 @@ export default function KaTeX({ latex, displayMode = false }: KaTeXProps) { return ( );