From ad35c4c931db37837761038d33ae71fa31ebc9e3 Mon Sep 17 00:00:00 2001
From: Jason Miller
Date: Mon, 12 Sep 2022 10:51:34 -0400
Subject: [PATCH 1/2] Ignore non-VNode objects during rendering
This fixes #245.
---
.changeset/curly-bananas-do.md | 5 +++++
src/index.js | 3 +++
src/pretty.js | 3 +++
test/jsx.test.js | 4 ++++
test/pretty.test.js | 6 ++++++
test/render.test.js | 4 ++++
6 files changed, 25 insertions(+)
create mode 100644 .changeset/curly-bananas-do.md
diff --git a/.changeset/curly-bananas-do.md b/.changeset/curly-bananas-do.md
new file mode 100644
index 00000000..19a81f08
--- /dev/null
+++ b/.changeset/curly-bananas-do.md
@@ -0,0 +1,5 @@
+---
+'preact-render-to-string': patch
+---
+
+Fix object children being rendered as `undefined`
diff --git a/src/index.js b/src/index.js
index 9892d218..206a1d67 100644
--- a/src/index.js
+++ b/src/index.js
@@ -210,6 +210,9 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
return rendered;
}
+ // VNodes have {constructor:undefined} to prevent JSON injection:
+ if (vnode.constructor !== undefined) return '';
+
vnode[PARENT] = parent;
if (options[DIFF]) options[DIFF](vnode);
diff --git a/src/pretty.js b/src/pretty.js
index 4d85cbc7..de7e66d3 100644
--- a/src/pretty.js
+++ b/src/pretty.js
@@ -53,6 +53,9 @@ export function _renderToStringPretty(
return rendered;
}
+ // VNodes have {constructor:undefined} to prevent JSON injection:
+ if (vnode.constructor !== undefined) return '';
+
let nodeName = vnode.type,
props = vnode.props,
isComponent = false;
diff --git a/test/jsx.test.js b/test/jsx.test.js
index 733ebaf4..e2969835 100644
--- a/test/jsx.test.js
+++ b/test/jsx.test.js
@@ -163,4 +163,8 @@ describe('jsx', () => {
`);
});
+
+ it('should prevent JSON injection', () => {
+ expect(renderJsx({{ hello: 'world' }}
)).to.equal('');
+ });
});
diff --git a/test/pretty.test.js b/test/pretty.test.js
index 5c6b4410..9ddfecd1 100644
--- a/test/pretty.test.js
+++ b/test/pretty.test.js
@@ -222,4 +222,10 @@ describe('pretty', () => {
`);
});
+
+ it('should prevent JSON injection', () => {
+ expect(prettyRender({{ hello: 'world' }}
)).to.equal(
+ ''
+ );
+ });
});
diff --git a/test/render.test.js b/test/render.test.js
index 3783569c..0ca58827 100644
--- a/test/render.test.js
+++ b/test/render.test.js
@@ -1260,4 +1260,8 @@ describe('render', () => {
''
);
});
+
+ it('should prevent JSON injection', () => {
+ expect(render({{ hello: 'world' }}
)).to.equal('');
+ });
});
From 203b79a45dfc55f8d0988be4f312f07959c9813c Mon Sep 17 00:00:00 2001
From: Marvin Hagemeister
Date: Tue, 4 Oct 2022 22:43:13 +0200
Subject: [PATCH 2/2] Ignore functions passed as children
---
.changeset/curly-bananas-do.md | 2 +-
src/index.js | 1 +
src/pretty.js | 1 +
test/jsx.test.js | 4 ++++
test/pretty.test.js | 4 ++++
test/render.test.js | 4 ++++
6 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/.changeset/curly-bananas-do.md b/.changeset/curly-bananas-do.md
index 19a81f08..4df000d9 100644
--- a/.changeset/curly-bananas-do.md
+++ b/.changeset/curly-bananas-do.md
@@ -2,4 +2,4 @@
'preact-render-to-string': patch
---
-Fix object children being rendered as `undefined`
+Fix object and function children being rendered as `undefined`
diff --git a/src/index.js b/src/index.js
index 206a1d67..4f5e2831 100644
--- a/src/index.js
+++ b/src/index.js
@@ -195,6 +195,7 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
// Text VNodes: escape as HTML
if (typeof vnode !== 'object') {
+ if (typeof vnode === 'function') return '';
return encodeEntities(vnode);
}
diff --git a/src/pretty.js b/src/pretty.js
index de7e66d3..1c977987 100644
--- a/src/pretty.js
+++ b/src/pretty.js
@@ -29,6 +29,7 @@ export function _renderToStringPretty(
// #text nodes
if (typeof vnode !== 'object') {
+ if (typeof vnode === 'function') return '';
return encodeEntities(vnode);
}
diff --git a/test/jsx.test.js b/test/jsx.test.js
index e2969835..403b888b 100644
--- a/test/jsx.test.js
+++ b/test/jsx.test.js
@@ -167,4 +167,8 @@ describe('jsx', () => {
it('should prevent JSON injection', () => {
expect(renderJsx({{ hello: 'world' }}
)).to.equal('');
});
+
+ it('should not render function children', () => {
+ expect(renderJsx({() => {}}
)).to.equal('');
+ });
});
diff --git a/test/pretty.test.js b/test/pretty.test.js
index 9ddfecd1..4ee901ea 100644
--- a/test/pretty.test.js
+++ b/test/pretty.test.js
@@ -228,4 +228,8 @@ describe('pretty', () => {
''
);
});
+
+ it('should not render function children', () => {
+ expect(prettyRender({() => {}}
)).to.equal('');
+ });
});
diff --git a/test/render.test.js b/test/render.test.js
index 0ca58827..8f234821 100644
--- a/test/render.test.js
+++ b/test/render.test.js
@@ -1264,4 +1264,8 @@ describe('render', () => {
it('should prevent JSON injection', () => {
expect(render({{ hello: 'world' }}
)).to.equal('');
});
+
+ it('should not render function children', () => {
+ expect(render({() => {}}
)).to.equal('');
+ });
});