Potentially fix seg fault when replace YogaLayoutableShadowNodes (#47689)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47689

We were seeing some segfaults from trying to access `display_` in Yoga's `replaceChild` function. Some memory debugging helped identify this was a use-after-free error and NickGerleman suggested we try swapping these lines. Logic being the shared_ptr of YogaLayoutableShadowNode is replaced right before we go and replace its yoga node in the yoga tree. If this is the last shared_ptr holding this node we will delete this object and thus the yoga node with it. We do not need to do this first, so let's swap the lines.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66142356

fbshipit-source-id: 8fd835346edc91e045ed2ee8945a95af21c47556
This commit is contained in:
Joe Vilches 2024-11-19 13:17:35 -08:00 committed by Facebook GitHub Bot
parent fa65b937f5
commit 156454ef39

View File

@ -300,13 +300,13 @@ void YogaLayoutableShadowNode::replaceChild(
// Both children are layoutable, replace the old one with the new one // Both children are layoutable, replace the old one with the new one
react_native_assert(layoutableNewChild->yogaNode_.getOwner() == nullptr); react_native_assert(layoutableNewChild->yogaNode_.getOwner() == nullptr);
layoutableNewChild->yogaNode_.setOwner(&yogaNode_); layoutableNewChild->yogaNode_.setOwner(&yogaNode_);
*oldChildIter = layoutableNewChild;
yogaNode_.replaceChild(&layoutableNewChild->yogaNode_, oldChildIndex); yogaNode_.replaceChild(&layoutableNewChild->yogaNode_, oldChildIndex);
*oldChildIter = layoutableNewChild;
} else { } else {
// Layoutable child replaced with non layoutable child. Remove the previous // Layoutable child replaced with non layoutable child. Remove the previous
// child from the layoutable children list. // child from the layoutable children list.
yogaLayoutableChildren_.erase(oldChildIter);
yogaNode_.removeChild(oldChildIndex); yogaNode_.removeChild(oldChildIndex);
yogaLayoutableChildren_.erase(oldChildIter);
} }
ensureYogaChildrenLookFine(); ensureYogaChildrenLookFine();