Skip to content

Commit e5b3f9a

Browse files
committed
Merge pull request #2520 from jsfb/warn-for-dangerouslySetInnerHtml
Added checks for incorrect usage of innerHTML. Fixes #1370
2 parents 158e0dd + aef7c4d commit e5b3f9a

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

src/browser/ui/ReactDOMComponent.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var invariant = require('invariant');
2727
var isEventSupported = require('isEventSupported');
2828
var keyOf = require('keyOf');
2929
var monitorCodeUse = require('monitorCodeUse');
30+
var warning = require('warning');
3031

3132
var deleteListener = ReactBrowserEventEmitter.deleteListener;
3233
var listenTo = ReactBrowserEventEmitter.listenTo;
@@ -52,11 +53,23 @@ function assertValidProps(props) {
5253
return;
5354
}
5455
// Note the use of `==` which checks for null or undefined.
55-
invariant(
56-
props.children == null || props.dangerouslySetInnerHTML == null,
57-
'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
58-
);
56+
if (props.dangerouslySetInnerHTML != null) {
57+
invariant(
58+
props.children == null,
59+
'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
60+
);
61+
invariant(
62+
props.dangerouslySetInnerHTML.__html != null,
63+
'`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
64+
'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
65+
);
66+
}
5967
if (__DEV__) {
68+
warning(
69+
props.innerHTML == null,
70+
'Directly setting property `innerHTML` is not permitted. ' +
71+
'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
72+
);
6073
if (props.contentEditable && props.children != null) {
6174
console.warn(
6275
'A component is `contentEditable` and contains `children` managed by ' +

src/browser/ui/__tests__/ReactDOMComponent-test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,36 @@ describe('ReactDOMComponent', function() {
341341
);
342342
});
343343

344+
it('should validate against use of innerHTML', function() {
345+
346+
spyOn(console, 'warn');
347+
mountComponent({ innerHTML: '<span>Hi Jim!</span>' });
348+
expect(console.warn.argsForCall.length).toBe(1);
349+
expect(console.warn.argsForCall[0][0]).toContain(
350+
'Directly setting property `innerHTML` is not permitted. '
351+
);
352+
});
353+
354+
it('should validate use of dangerouslySetInnerHTML', function() {
355+
expect(function() {
356+
mountComponent({ dangerouslySetInnerHTML: '<span>Hi Jim!</span>' });
357+
}).toThrow(
358+
'Invariant Violation: ' +
359+
'`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
360+
'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
361+
);
362+
});
363+
364+
it('should validate use of dangerouslySetInnerHTML', function() {
365+
expect(function() {
366+
mountComponent({ dangerouslySetInnerHTML: {foo: 'bar'} });
367+
}).toThrow(
368+
'Invariant Violation: ' +
369+
'`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
370+
'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
371+
);
372+
});
373+
344374
it("should warn about contentEditable and children", function() {
345375
spyOn(console, 'warn');
346376
mountComponent({ contentEditable: true, children: '' });

0 commit comments

Comments
 (0)