From 2aeab2bc10f45e479d7c3c3218b937c1e0a19ca8 Mon Sep 17 00:00:00 2001 From: "Daniel Boelzle [:dbo]" Date: Wed, 18 Jan 2017 14:39:28 +0100 Subject: [PATCH 1/3] Check write-access on prototype. --- client/patch-react.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/client/patch-react.js b/client/patch-react.js index b16b8bb9d8fcc..fc8698a4cb920 100644 --- a/client/patch-react.js +++ b/client/patch-react.js @@ -3,6 +3,15 @@ import React from 'react' +const isWritable = (obj, p) => { + const descr = Object.getOwnPropertyDescriptor(obj, p) + if (descr) { + return descr.writable + } + const proto = Object.getPrototypeOf(obj) + return proto ? isWritable(proto, p) : false +} + let patched = false export default (handleError = () => {}) => { @@ -18,7 +27,9 @@ export default (handleError = () => {}) => { if (typeof Component === 'function') { const { prototype } = Component if (prototype && prototype.render) { - prototype.render = wrapRender(prototype.render) + if (isWritable(prototype, 'render')) { + prototype.render = wrapRender(prototype.render) + } } else { // stateless component Component = wrapRender(Component) From 5bc571d0111f18eafd9447cd359cb039b0500c83 Mon Sep 17 00:00:00 2001 From: "Daniel Boelzle [:dbo]" Date: Wed, 18 Jan 2017 14:53:41 +0100 Subject: [PATCH 2/3] Write on correct prototype. --- client/patch-react.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/client/patch-react.js b/client/patch-react.js index fc8698a4cb920..34b10ba701056 100644 --- a/client/patch-react.js +++ b/client/patch-react.js @@ -3,13 +3,13 @@ import React from 'react' -const isWritable = (obj, p) => { +const getWritableProto = (obj, p) => { const descr = Object.getOwnPropertyDescriptor(obj, p) if (descr) { - return descr.writable + return descr.writable ? obj : null } const proto = Object.getPrototypeOf(obj) - return proto ? isWritable(proto, p) : false + return proto ? getWritableProto(proto, p) : null } let patched = false @@ -25,9 +25,10 @@ export default (handleError = () => {}) => { React.createElement = function (Component, ...rest) { if (typeof Component === 'function') { - const { prototype } = Component + let { prototype } = Component if (prototype && prototype.render) { - if (isWritable(prototype, 'render')) { + prototype = getWritableProto(prototype, 'render') + if (prototype) { prototype.render = wrapRender(prototype.render) } } else { From 996f34250d992a26e7161de25fb50096102a7607 Mon Sep 17 00:00:00 2001 From: "Daniel Boelzle [:dbo]" Date: Sat, 21 Jan 2017 10:14:11 +0100 Subject: [PATCH 3/3] Add comments to prototype lookup. --- client/patch-react.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/patch-react.js b/client/patch-react.js index 34b10ba701056..5e70db0808f7f 100644 --- a/client/patch-react.js +++ b/client/patch-react.js @@ -3,6 +3,10 @@ import React from 'react' +/** + * Traverses the prototype chain, returning the prototype object + * on which the property is defined. + */ const getWritableProto = (obj, p) => { const descr = Object.getOwnPropertyDescriptor(obj, p) if (descr) { @@ -27,6 +31,9 @@ export default (handleError = () => {}) => { if (typeof Component === 'function') { let { prototype } = Component if (prototype && prototype.render) { + /** + * Get the prototype object on which `render` is defined. + */ prototype = getWritableProto(prototype, 'render') if (prototype) { prototype.render = wrapRender(prototype.render)