From aef7c4d1a16133f2f6d3ae3bfd18f01f8fc1403b Mon Sep 17 00:00:00 2001 From: Jim Date: Thu, 13 Nov 2014 14:51:57 -0800 Subject: [PATCH] Added checks for incorrect usage of innerHTML. Fixes #1370 --- src/browser/ui/ReactDOMComponent.js | 21 ++++++++++--- .../ui/__tests__/ReactDOMComponent-test.js | 30 +++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/browser/ui/ReactDOMComponent.js b/src/browser/ui/ReactDOMComponent.js index 0a6f60e14ac..3d7031f13bf 100644 --- a/src/browser/ui/ReactDOMComponent.js +++ b/src/browser/ui/ReactDOMComponent.js @@ -27,6 +27,7 @@ var invariant = require('invariant'); var isEventSupported = require('isEventSupported'); var keyOf = require('keyOf'); var monitorCodeUse = require('monitorCodeUse'); +var warning = require('warning'); var deleteListener = ReactBrowserEventEmitter.deleteListener; var listenTo = ReactBrowserEventEmitter.listenTo; @@ -52,11 +53,23 @@ function assertValidProps(props) { return; } // Note the use of `==` which checks for null or undefined. - invariant( - props.children == null || props.dangerouslySetInnerHTML == null, - 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.' - ); + if (props.dangerouslySetInnerHTML != null) { + invariant( + props.children == null, + 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.' + ); + invariant( + props.dangerouslySetInnerHTML.__html != null, + '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.' + ); + } if (__DEV__) { + warning( + props.innerHTML == null, + 'Directly setting property `innerHTML` is not permitted. ' + + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.' + ); if (props.contentEditable && props.children != null) { console.warn( 'A component is `contentEditable` and contains `children` managed by ' + diff --git a/src/browser/ui/__tests__/ReactDOMComponent-test.js b/src/browser/ui/__tests__/ReactDOMComponent-test.js index aa557c662d2..b69773cd241 100644 --- a/src/browser/ui/__tests__/ReactDOMComponent-test.js +++ b/src/browser/ui/__tests__/ReactDOMComponent-test.js @@ -341,6 +341,36 @@ describe('ReactDOMComponent', function() { ); }); + it('should validate against use of innerHTML', function() { + + spyOn(console, 'warn'); + mountComponent({ innerHTML: 'Hi Jim!' }); + expect(console.warn.argsForCall.length).toBe(1); + expect(console.warn.argsForCall[0][0]).toContain( + 'Directly setting property `innerHTML` is not permitted. ' + ); + }); + + it('should validate use of dangerouslySetInnerHTML', function() { + expect(function() { + mountComponent({ dangerouslySetInnerHTML: 'Hi Jim!' }); + }).toThrow( + 'Invariant Violation: ' + + '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.' + ); + }); + + it('should validate use of dangerouslySetInnerHTML', function() { + expect(function() { + mountComponent({ dangerouslySetInnerHTML: {foo: 'bar'} }); + }).toThrow( + 'Invariant Violation: ' + + '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.' + ); + }); + it("should warn about contentEditable and children", function() { spyOn(console, 'warn'); mountComponent({ contentEditable: true, children: '' });