mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(core): restore IIFE with </script> escaping for composition scripts
The Function constructor (3bb0d1ef) was a security hardening to prevent
</script> injection, but it broke sub-composition DOM proxy scoping.
This restores the inline IIFE (preserving closure scope) while adding
</script> → <\/script> escaping to maintain the injection prevention.
Updates tests to match the new IIFE output shape.
Closes #1074
This commit is contained in:
@@ -572,14 +572,15 @@ window.__afterTimeline = window.__timelines.scene;
|
||||
expect(scoped).toContain('[data-composition-id="chrome-overlay"] .child-element');
|
||||
});
|
||||
|
||||
it("wraps scoped composition script source as a string literal", () => {
|
||||
it("escapes </script> in scoped composition script source to prevent injection", () => {
|
||||
const wrapped = wrapScopedCompositionScript(
|
||||
'window.payload = "</script><script>window.pwned = true;</script>";',
|
||||
"scene",
|
||||
);
|
||||
|
||||
expect(wrapped).toContain('Function("document", "gsap", "window", "__hyperframes", ');
|
||||
expect(wrapped).toContain('\\"</script><script>window.pwned = true;</script>\\"');
|
||||
expect(wrapped).toContain("(function(document, gsap, window, __hyperframes)");
|
||||
expect(wrapped).not.toContain("</script><script>");
|
||||
expect(wrapped).toContain("<\\/script>");
|
||||
});
|
||||
|
||||
it("wraps unscoped composition script source as a string literal", () => {
|
||||
|
||||
@@ -486,7 +486,7 @@ export function wrapScopedCompositionScript(
|
||||
var __hfRun = function() {
|
||||
try {
|
||||
(function(document, gsap, window, __hyperframes) {
|
||||
${source}
|
||||
${source.replace(/<\/(script)/gi, "<\\/$1")}
|
||||
}).call(window, __hfScopedDocument, __hfScopedGsap, __hfScopedWindow, __hfScopedHyperframes);
|
||||
} catch (_err) {
|
||||
console.error(__hfErrorLabel, __hfCompId, _err);
|
||||
|
||||
@@ -758,8 +758,8 @@ describe("bundleToSingleHtml", () => {
|
||||
expect(bundled).toContain('[data-composition-id="scene"] .title { color: red; }');
|
||||
expect(bundled).toContain("new Proxy(window.document");
|
||||
expect(bundled).toContain("new Proxy(__hfBaseGsap");
|
||||
expect(bundled).toContain('Function("document", "gsap", "window", "__hyperframes",');
|
||||
expect(bundled).toContain("tl.to('.title'");
|
||||
expect(bundled).toContain("(function(document, gsap, window, __hyperframes)");
|
||||
expect(bundled).toContain('tl.to(".title"');
|
||||
});
|
||||
|
||||
it("isolates sibling instances of the same external sub-composition", async () => {
|
||||
|
||||
Reference in New Issue
Block a user