Skip to content

Commit b7ff95d

Browse files
5ZYSZ3Kmeta-codesync[bot]
authored andcommitted
fix: yoga crash with display:none (#1976)
Summary: Pull Request resolved: #1976 It fixes this issue: react/react-native#52349 Basically, in some rare cases, having an element with `display:none` style caused the app to crash. It was caused by a stale `hasNewLayout` flag on the hidden view That flag was always set in `computeFlexBasisForChildren` for elements with `display:none` style, but could be never consumed/reset, because of a cache hit or something. Since such elements contribute nothing to the layout sizes, I made the change to actually touch them only during actual layout passes ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [GENERAL] [FIXED] - Crash: YogaLayoutableShadowNode.cpp: function layout: assertion failed (YGNodeGetOwner(childYogaNode) == &yogaNode_) react/react-native#52349 X-link: react/react-native#57197 Test Plan: I created a reproduction repo: https://github.com/5ZYSZ3K/native-tabs-crash-repro, to see the issue And to see, that my change fixes it, you can switch to `patch-yoga` branch there, and install it again (don't forget to install pods with `RCT_USE_PREBUILT_RNCORE=0 RCT_USE_RN_DEP=0` variables) Reviewed By: christophpurrer Differential Revision: D108796888 Pulled By: javache fbshipit-source-id: 455e3ddbec760dbee875c02f0ed6266b9a417e9a
1 parent f6206ec commit b7ff95d

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

yoga/algorithm/CalculateLayout.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -615,9 +615,18 @@ static float computeFlexBasisForChildren(
615615
for (auto child : children) {
616616
child->processDimensions();
617617
if (child->style().display() == Display::None) {
618-
zeroOutLayoutRecursively(child);
619-
child->setHasNewLayout(true);
620-
child->setDirty(false);
618+
// Only mutate display: none children during layout passes. Zeroing them
619+
// out during measure-only passes contributes nothing to the measurement,
620+
// but sets `hasNewLayout` on nodes the parent's layout pass may never
621+
// visit (e.g. when its layout is restored from cache, skipping
622+
// `cloneChildrenIfNeeded()`). Such a leaked flag survives the commit and
623+
// is copied into lazily-shared clones, later tripping the ownership
624+
// assertion in `YogaLayoutableShadowNode::layout`.
625+
if (performLayout) {
626+
zeroOutLayoutRecursively(child);
627+
child->setHasNewLayout(true);
628+
child->setDirty(false);
629+
}
621630
continue;
622631
}
623632
if (performLayout) {

0 commit comments

Comments
 (0)