diff --git a/React/Base/RCTTouchHandler.m b/React/Base/RCTTouchHandler.m index 19af0120d..481128efe 100644 --- a/React/Base/RCTTouchHandler.m +++ b/React/Base/RCTTouchHandler.m @@ -156,17 +156,17 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action CGPoint touchViewLocation = [nativeTouch.window convertPoint:windowLocation toView:touchView]; NSMutableDictionary *reactTouch = _reactTouches[touchIndex]; - reactTouch[@"pageX"] = @(rootViewLocation.x); - reactTouch[@"pageY"] = @(rootViewLocation.y); - reactTouch[@"locationX"] = @(touchViewLocation.x); - reactTouch[@"locationY"] = @(touchViewLocation.y); + reactTouch[@"pageX"] = @(RCTSanitizeNaNValue(rootViewLocation.x, @"touchEvent.pageX")); + reactTouch[@"pageY"] = @(RCTSanitizeNaNValue(rootViewLocation.y, @"touchEvent.pageY")); + reactTouch[@"locationX"] = @(RCTSanitizeNaNValue(touchViewLocation.x, @"touchEvent.locationX")); + reactTouch[@"locationY"] = @(RCTSanitizeNaNValue(touchViewLocation.y, @"touchEvent.locationY")); reactTouch[@"timestamp"] = @(nativeTouch.timestamp * 1000); // in ms, for JS // TODO: force for a 'normal' touch is usually 1.0; // should we expose a `normalTouchForce` constant somewhere (which would // have a value of `1.0 / nativeTouch.maximumPossibleForce`)? if (RCTForceTouchAvailable()) { - reactTouch[@"force"] = @(RCTZeroIfNaN(nativeTouch.force / nativeTouch.maximumPossibleForce)); + reactTouch[@"force"] = @(RCTSanitizeNaNValue(nativeTouch.force / nativeTouch.maximumPossibleForce, @"touchEvent.force")); } } diff --git a/React/Base/RCTUtils.h b/React/Base/RCTUtils.h index 8d6470260..d641f74d7 100644 --- a/React/Base/RCTUtils.h +++ b/React/Base/RCTUtils.h @@ -101,6 +101,9 @@ RCT_EXTERN NSError *RCTErrorWithMessage(NSString *message); // Convert NaN or infinite values to zero, as these aren't JSON-safe RCT_EXTERN double RCTZeroIfNaN(double value); +// Returns `0` and log special warning if value is NaN or INF. +RCT_EXTERN double RCTSanitizeNaNValue(double value, NSString *property); + // Convert data to a Base64-encoded data URL RCT_EXTERN NSURL *RCTDataURL(NSString *mimeType, NSData *data); diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m index 4e2ed4623..c00bb283d 100644 --- a/React/Base/RCTUtils.m +++ b/React/Base/RCTUtils.m @@ -513,6 +513,16 @@ double RCTZeroIfNaN(double value) return isnan(value) || isinf(value) ? 0 : value; } +double RCTSanitizeNaNValue(double value, NSString *property) +{ + if (!isnan(value) && !isinf(value)) { + return value; + } + + RCTLogWarn(@"The value `%@` equals NaN or INF and will be replaced by `0`.", property); + return 0; +} + NSURL *RCTDataURL(NSString *mimeType, NSData *data) { return [NSURL URLWithString: