fix(preview): harden sandbox and transformation
This commit is contained in:
+18
-5
@@ -393,7 +393,15 @@ def _critique_shared(markup: str) -> list[str]:
|
||||
issues: list[str] = []
|
||||
lower = markup.lower()
|
||||
|
||||
if re.search(r"""(?i)(?:src|href)\s*=\s*['"]https?://""", markup):
|
||||
external_attr = re.search(
|
||||
r"""(?i)\b(?:src|srcset|href|xlink:href|poster|action|formaction|data)\b\s*=\s*(?:['"]\s*)?https?://""",
|
||||
markup,
|
||||
)
|
||||
external_css = re.search(
|
||||
r"""(?i)(?:url\s*\(\s*['"]?\s*https?://|@import\s+(?:url\s*\(\s*)?['"]?\s*https?://)""",
|
||||
markup,
|
||||
)
|
||||
if external_attr or external_css:
|
||||
issues.append(
|
||||
"Remove external http(s) URLs — the sandboxed preview blocks them. "
|
||||
"Inline CSS/JS; use data: URIs for images/fonts."
|
||||
@@ -1014,14 +1022,15 @@ STANDING_TOOLS = frozenset({"render_preview"})
|
||||
# User-message cues that justify running the (slow, non-stream) tool loop with
|
||||
# render_preview. Kept narrow so ordinary chat isn't blocked behind a tool turn.
|
||||
_RENDER_HINTS = (
|
||||
"visual", "visualize", "visualization", "chart", "graph", "diagram",
|
||||
"canvas", "plot", "interactive", "animation", "render_preview",
|
||||
"visual", "visuals", "visualize", "visualization", "chart", "charts",
|
||||
"graph", "graphs", "diagram", "diagrams", "canvas", "plot", "plots",
|
||||
"interactive", "animation", "animations", "render_preview",
|
||||
"render preview", "svg", "draw me", "live preview",
|
||||
"demonstrate", "demo", "html demo", "html snippet", "html file",
|
||||
# Ways of asking for something that reacts to the pointer. "interactive"
|
||||
# alone missed "mouse-over sensitive", and with it the whole feature.
|
||||
"hover", "mouse", "drag", "click on", "real-time", "realtime",
|
||||
"simulation", "simulate", "particle", "animate",
|
||||
"simulation", "simulations", "simulate", "particle", "particles", "animate",
|
||||
# Every language the render window can display. Naming one is asking for a
|
||||
# preview, and this way a language added to PREVIEW_LANGS starts hinting
|
||||
# for itself instead of being unreachable until someone edits this tuple -
|
||||
@@ -1031,8 +1040,12 @@ _RENDER_HINTS = (
|
||||
|
||||
def wants_render_preview(message: str) -> bool:
|
||||
"""True when this turn should advertise render_preview / enter the tool loop."""
|
||||
import re
|
||||
lower = (message or "").lower()
|
||||
return any(h in lower for h in _RENDER_HINTS)
|
||||
return any(
|
||||
re.search(rf"(?<![A-Za-z0-9_]){re.escape(hint)}(?![A-Za-z0-9_])", lower)
|
||||
for hint in _RENDER_HINTS
|
||||
)
|
||||
|
||||
|
||||
def is_action(name: str) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user