From 6e49d2041de4f4c3ed43ff5f5438b2887631a2c5 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Wed, 13 Feb 2019 11:54:59 -0800 Subject: [PATCH] [Fix] ensure nullish values in `oneOf` do not crash Fixes #256. --- __tests__/PropTypesDevelopmentReact15.js | 11 +++++++++++ __tests__/PropTypesDevelopmentStandalone-test.js | 11 +++++++++++ __tests__/PropTypesProductionReact15-test.js | 9 +++++++++ factoryWithTypeCheckers.js | 8 +++++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/__tests__/PropTypesDevelopmentReact15.js b/__tests__/PropTypesDevelopmentReact15.js index 5913f58..8eeff8d 100644 --- a/__tests__/PropTypesDevelopmentReact15.js +++ b/__tests__/PropTypesDevelopmentReact15.js @@ -983,6 +983,17 @@ describe('PropTypesDevelopmentReact15', () => { ); }); + it('does not fail when the valid types contain null or undefined', () => { + typeCheckFail( + PropTypes.oneOf([0, 'false', null, undefined]), + false, + 'Warning: Failed prop type: Invalid prop `testProp` of value `false` supplied to ' + + '`testComponent`, expected one of [0,"false",null,null].', + // TODO: uncomment and fix implementation + // '`testComponent`, expected one of [0,"false",null,undefined].', + ); + }); + it('should not warn for valid values', () => { typeCheckPass(PropTypes.oneOf(['red', 'blue']), 'red'); typeCheckPass(PropTypes.oneOf(['red', 'blue']), 'blue'); diff --git a/__tests__/PropTypesDevelopmentStandalone-test.js b/__tests__/PropTypesDevelopmentStandalone-test.js index 9012971..8e9b2b7 100644 --- a/__tests__/PropTypesDevelopmentStandalone-test.js +++ b/__tests__/PropTypesDevelopmentStandalone-test.js @@ -1057,6 +1057,17 @@ describe('PropTypesDevelopmentStandalone', () => { ); }); + it('does not fail when the valid types contain null or undefined', () => { + typeCheckFail( + PropTypes.oneOf([0, 'false', null, undefined]), + false, + 'Warning: Failed prop type: Invalid prop `testProp` of value `false` supplied to ' + + '`testComponent`, expected one of [0,"false",null,null].', + // TODO: uncomment and fix implementation + // '`testComponent`, expected one of [0,"false",null,undefined].', + ); + }); + it('should not warn for valid values', () => { typeCheckPass(PropTypes.oneOf(['red', 'blue']), 'red'); typeCheckPass(PropTypes.oneOf(['red', 'blue']), 'blue'); diff --git a/__tests__/PropTypesProductionReact15-test.js b/__tests__/PropTypesProductionReact15-test.js index 3dcac99..e3c9543 100644 --- a/__tests__/PropTypesProductionReact15-test.js +++ b/__tests__/PropTypesProductionReact15-test.js @@ -768,6 +768,15 @@ describe('PropTypesProductionReact15', () => { ); }); + it('does not fail when the valid types contain null or undefined', () => { + expectNoop( + PropTypes.oneOf([0, 'false', null, undefined]), + false, + 'Warning: Failed prop type: Invalid prop `testProp` of value `false` supplied to ' + + '`testComponent`, expected one of [0,"false",null,undefined].', + ); + }); + it('should not warn for valid values', () => { expectNoop(PropTypes.oneOf(['red', 'blue']), 'red'); expectNoop(PropTypes.oneOf(['red', 'blue']), 'blue'); diff --git a/factoryWithTypeCheckers.js b/factoryWithTypeCheckers.js index c947083..3711f0b 100644 --- a/factoryWithTypeCheckers.js +++ b/factoryWithTypeCheckers.js @@ -326,7 +326,8 @@ module.exports = function(isValidElement, throwOnDirectAccess) { } var valuesString = JSON.stringify(expectedValues, function replacer(key, value) { - if (getPropType(value) === 'symbol') { + var type = getPreciseType(value); + if (type === 'symbol') { return String(value); } return value; @@ -504,6 +505,11 @@ module.exports = function(isValidElement, throwOnDirectAccess) { return true; } + // falsy value can't be a Symbol + if (!propValue) { + return false; + } + // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' if (propValue['@@toStringTag'] === 'Symbol') { return true;