From ea2e2c54cb4d1a99b41aaa98eaf51696d34770dd Mon Sep 17 00:00:00 2001 From: Marc Horowitz Date: Thu, 14 Dec 2017 11:05:35 -0800 Subject: [PATCH] Make the __DEV__ argument check more robust Summary: JSON.stringify will convert a function to null, but folly::dynamic in the native code can't represent a JS function. Props do sometimes have functions, but don't permit them everywhere. Reviewed By: johnislarry Differential Revision: D6541878 fbshipit-source-id: b2a9d3ba7899dfb98a6a2ada3aa91a26549fdd94 --- Libraries/BatchedBridge/MessageQueue.js | 36 +++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/Libraries/BatchedBridge/MessageQueue.js b/Libraries/BatchedBridge/MessageQueue.js index 9d3b8c6d66914a..4309de35519cf6 100644 --- a/Libraries/BatchedBridge/MessageQueue.js +++ b/Libraries/BatchedBridge/MessageQueue.js @@ -215,8 +215,40 @@ class MessageQueue { this._queue[METHOD_IDS].push(methodID); if (__DEV__) { - // Any params sent over the bridge should be encodable as JSON - JSON.stringify(params); + // Validate that parameters passed over the bridge are + // folly-convertible. As a special case, if a prop value is a + // function it is permitted here, and special-cased in the + // conversion. + const isValidArgument = val => { + const t = typeof val; + if ( + t === 'undefined' || + t === 'null' || + t === 'boolean' || + t === 'number' || + t === 'string' + ) { + return true; + } + if (t === 'function' || t !== 'object') { + return false; + } + if (Array.isArray(val)) { + return val.every(isValidArgument); + } + for (const k in val) { + if (typeof val[k] !== 'function' && !isValidArgument(val[k])) { + return false; + } + } + return true; + }; + + invariant( + isValidArgument(params), + '%s is not usable as a native method argument', + params, + ); // The params object should not be mutated after being queued deepFreezeAndThrowOnMutationInDev((params: any));