|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
import copy from "copy-to-clipboard";
|
|
|
|
|
import DOMPurify from "dompurify";
|
|
|
|
|
import hljs from "highlight.js";
|
|
|
|
|
import { CopyIcon } from "lucide-react";
|
|
|
|
|
import { useEffect, useMemo } from "react";
|
|
|
|
@ -22,12 +23,63 @@ const CodeBlock: React.FC<Props> = ({ language, content }: Props) => {
|
|
|
|
|
const formatedLanguage = useMemo(() => (language || "").toLowerCase() || "text", [language]);
|
|
|
|
|
|
|
|
|
|
// Users can set Markdown code blocks as `__html` to render HTML directly.
|
|
|
|
|
// Content is sanitized to prevent XSS attacks while preserving safe HTML.
|
|
|
|
|
if (formatedLanguage === SpecialLanguage.HTML) {
|
|
|
|
|
const sanitizedHTML = DOMPurify.sanitize(content, {
|
|
|
|
|
// Allow common safe HTML tags and attributes
|
|
|
|
|
ALLOWED_TAGS: [
|
|
|
|
|
"div",
|
|
|
|
|
"span",
|
|
|
|
|
"p",
|
|
|
|
|
"br",
|
|
|
|
|
"strong",
|
|
|
|
|
"b",
|
|
|
|
|
"em",
|
|
|
|
|
"i",
|
|
|
|
|
"u",
|
|
|
|
|
"s",
|
|
|
|
|
"strike",
|
|
|
|
|
"h1",
|
|
|
|
|
"h2",
|
|
|
|
|
"h3",
|
|
|
|
|
"h4",
|
|
|
|
|
"h5",
|
|
|
|
|
"h6",
|
|
|
|
|
"blockquote",
|
|
|
|
|
"code",
|
|
|
|
|
"pre",
|
|
|
|
|
"ul",
|
|
|
|
|
"ol",
|
|
|
|
|
"li",
|
|
|
|
|
"dl",
|
|
|
|
|
"dt",
|
|
|
|
|
"dd",
|
|
|
|
|
"table",
|
|
|
|
|
"thead",
|
|
|
|
|
"tbody",
|
|
|
|
|
"tr",
|
|
|
|
|
"th",
|
|
|
|
|
"td",
|
|
|
|
|
"a",
|
|
|
|
|
"img",
|
|
|
|
|
"figure",
|
|
|
|
|
"figcaption",
|
|
|
|
|
"hr",
|
|
|
|
|
"small",
|
|
|
|
|
"sup",
|
|
|
|
|
"sub",
|
|
|
|
|
],
|
|
|
|
|
ALLOWED_ATTR: "href title alt src width height class id style target rel colspan rowspan".split(" "),
|
|
|
|
|
// Forbid dangerous attributes and tags
|
|
|
|
|
FORBID_ATTR: "onerror onload onclick onmouseover onfocus onblur onchange".split(" "),
|
|
|
|
|
FORBID_TAGS: "script iframe object embed form input button".split(" "),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
className="w-full overflow-auto my-2!"
|
|
|
|
|
dangerouslySetInnerHTML={{
|
|
|
|
|
__html: content,
|
|
|
|
|
__html: sanitizedHTML,
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|