From 97ecb5eb1903eefb1d7bc05361b741bca71df9f6 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Tue, 9 Feb 2021 22:40:17 -0800 Subject: [PATCH] StubViewTree: ensure nodes don't have parents when they're inserted Summary: iOS and Android platform code already explicitly check this invariant: nodes cannot have parents when they're inserted into the View hierarchy. Check this in the core so we get these checks in unit tests, and earlier in the core before platform code runs. Changelog: [Internal] Reviewed By: shergin, mdvacca Differential Revision: D26331842 fbshipit-source-id: c12bc9066d280cb85ccc9e754c9fa475927e6080 --- ReactCommon/react/renderer/mounting/StubView.h | 3 +++ ReactCommon/react/renderer/mounting/StubViewTree.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/ReactCommon/react/renderer/mounting/StubView.h b/ReactCommon/react/renderer/mounting/StubView.h index ca433c953b3..a721c57c74d 100644 --- a/ReactCommon/react/renderer/mounting/StubView.h +++ b/ReactCommon/react/renderer/mounting/StubView.h @@ -18,6 +18,8 @@ namespace facebook { namespace react { +static const int NO_VIEW_TAG = -1; + class StubView final { public: using Shared = std::shared_ptr; @@ -38,6 +40,7 @@ class StubView final { LayoutMetrics layoutMetrics; State::Shared state; std::vector children; + Tag parentTag{NO_VIEW_TAG}; }; bool operator==(StubView const &lhs, StubView const &rhs); diff --git a/ReactCommon/react/renderer/mounting/StubViewTree.cpp b/ReactCommon/react/renderer/mounting/StubViewTree.cpp index bc51d102603..306076bdd73 100644 --- a/ReactCommon/react/renderer/mounting/StubViewTree.cpp +++ b/ReactCommon/react/renderer/mounting/StubViewTree.cpp @@ -90,6 +90,7 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) { auto childTag = mutation.newChildShadowView.tag; STUB_VIEW_ASSERT(registry.find(childTag) != registry.end()); auto childStubView = registry[childTag]; + STUB_VIEW_ASSERT(childStubView->parentTag == NO_VIEW_TAG); childStubView->update(mutation.newChildShadowView); STUB_VIEW_LOG({ LOG(ERROR) << "StubView: Insert: " << childTag << " into " @@ -97,6 +98,7 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) { << parentStubView->children.size() << " children)"; }); STUB_VIEW_ASSERT(parentStubView->children.size() >= mutation.index); + childStubView->parentTag = parentTag; parentStubView->children.insert( parentStubView->children.begin() + mutation.index, childStubView); break; @@ -116,6 +118,7 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) { STUB_VIEW_ASSERT(parentStubView->children.size() > mutation.index); STUB_VIEW_ASSERT(registry.find(childTag) != registry.end()); auto childStubView = registry[childTag]; + STUB_VIEW_ASSERT(childStubView->parentTag == parentTag); bool childIsCorrect = parentStubView->children.size() > mutation.index && parentStubView->children[mutation.index]->tag == childStubView->tag; @@ -133,6 +136,7 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) { << ": " << strChildList; }); STUB_VIEW_ASSERT(childIsCorrect); + childStubView->parentTag = NO_VIEW_TAG; parentStubView->children.erase( parentStubView->children.begin() + mutation.index); break;