diff --git a/src/shared/utils/__tests__/traverseAllChildren-test.js b/src/shared/utils/__tests__/traverseAllChildren-test.js index a4c8954db5..d981bb93f0 100644 --- a/src/shared/utils/__tests__/traverseAllChildren-test.js +++ b/src/shared/utils/__tests__/traverseAllChildren-test.js @@ -476,6 +476,39 @@ describe('traverseAllChildren', function() { } }); + it('should allow extension of native prototypes', function() { + /*eslint-disable no-extend-native */ + String.prototype.key = 'react'; + Number.prototype.key = 'rocks'; + /*eslint-enable no-extend-native */ + + var instance = ( +
+ {'a'} + {13} +
+ ); + + var traverseFn = jasmine.createSpy(); + + traverseAllChildren(instance.props.children, traverseFn, null); + expect(traverseFn.calls.length).toBe(2); + + expect(traverseFn).toHaveBeenCalledWith( + null, + 'a', + '.0' + ); + expect(traverseFn).toHaveBeenCalledWith( + null, + 13, + '.1' + ); + + delete String.prototype.key; + delete Number.prototype.key; + }); + it('should throw on object', function() { expect(function() { traverseAllChildren({a: 1, b: 2}, function() {}, null); diff --git a/src/shared/utils/traverseAllChildren.js b/src/shared/utils/traverseAllChildren.js index f7f7e878eb..62146c7431 100644 --- a/src/shared/utils/traverseAllChildren.js +++ b/src/shared/utils/traverseAllChildren.js @@ -47,7 +47,9 @@ function userProvidedKeyEscaper(match) { * @return {string} */ function getComponentKey(component, index) { - if (component && component.key != null) { + // Do some typechecking here since we call this blindly. We want to ensure + // that we don't block potential future ES APIs. + if (component && typeof component === 'object' && component.key != null) { // Explicit key return wrapUserProvidedKey(component.key); }