From dbc7e4e527e4589ea28a7e55d098cd58a7287579 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Fri, 18 Oct 2019 09:25:51 -0700 Subject: [PATCH] Fabric: More type asserts in ConcreteComponentDescriptor Summary: `ConcreteComponentDescriptor` is a major place where dynamic dispatch calls end up. We see some amount of crashes that can be caused by an invalid pointer to a ComponentDescriptor, those checks can help verify this theory. Anyway, it's a good practice to fail earlier. Changelog: [Internal] - Stability improvements (Fabric) Reviewed By: sammy-SC Differential Revision: D17991515 fbshipit-source-id: 1cac372a12b49430a3d1db66c8fc673e6adc32e9 --- .../ConcreteComponentDescriptor.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h b/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h index 61e616eff49..f87bc5051a5 100644 --- a/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h +++ b/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h @@ -77,6 +77,10 @@ class ConcreteComponentDescriptor : public ComponentDescriptor { UnsharedShadowNode cloneShadowNode( const ShadowNode &sourceShadowNode, const ShadowNodeFragment &fragment) const override { + assert( + dynamic_cast(&sourceShadowNode) && + "Provided `sourceShadowNode` has an incompatible type."); + auto shadowNode = std::make_shared(sourceShadowNode, fragment); adopt(shadowNode); @@ -86,6 +90,10 @@ class ConcreteComponentDescriptor : public ComponentDescriptor { void appendChild( const SharedShadowNode &parentShadowNode, const SharedShadowNode &childShadowNode) const override { + assert( + dynamic_cast(parentShadowNode.get()) && + "Provided `parentShadowNode` has an incompatible type."); + auto concreteParentShadowNode = std::static_pointer_cast(parentShadowNode); auto concreteNonConstParentShadowNode = @@ -96,6 +104,11 @@ class ConcreteComponentDescriptor : public ComponentDescriptor { virtual SharedProps cloneProps( const SharedProps &props, const RawProps &rawProps) const override { + assert( + !props || + dynamic_cast(props.get()) && + "Provided `props` has an incompatible type."); + if (rawProps.isEmpty()) { return props ? props : ShadowNodeT::defaultSharedProps(); } @@ -132,6 +145,12 @@ class ConcreteComponentDescriptor : public ComponentDescriptor { return nullptr; } + assert(previousState && "Provided `previousState` is nullptr."); + assert(data && "Provided `data` is nullptr."); + assert( + dynamic_cast(previousState.get()) && + "Provided `previousState` has an incompatible type."); + return std::make_shared( std::move(*std::static_pointer_cast(data)), *std::static_pointer_cast(previousState));