Skip to content

Commit 6ec4597

Browse files
fkgozalimeta-codesync[bot]
authored andcommitted
Fix LayoutAnimation crash from mutation sort ordering (#56629)
Summary: Pull Request resolved: #56629 `LayoutAnimationDriver::animationMutationsForFrame` was sorting animation-frame Update mutations together with structural mutations (Remove/Insert/Delete) from completed animations. Animation-frame Updates reference views by their pre-structural-change parentTag. When `std::stable_sort` reordered these Updates after Remove/Insert pairs that reparented a view, `StubViewTree::mutate` hit a parentTag mismatch assertion (`react_native_assert(oldStubView->parentTag == mutation.parentTag)`) and crashed with SIGABRT. The fix records the boundary between animation-frame Updates and final structural mutations, then only sorts the structural portion. This preserves the invariant that animation-frame Updates execute before any structural changes. Per zeyap's review: simplified to just the LayoutAnimationDriver.cpp change. The earlier MutationComparator (`Update < Insert`) tweak and the `TEST_F` + feature-flag test refactor were dropped — the driver-side fix alone unbreaks the failing test. Changelog: [Internal] Reviewed By: zeyap Differential Revision: D102696875 fbshipit-source-id: abaac2ae6dae44f7df1f4088bb8ec19b055c2b1a
1 parent a3906b6 commit 6ec4597

1 file changed

Lines changed: 8 additions & 3 deletions

File tree

packages/react-native/ReactCommon/react/renderer/animations/LayoutAnimationDriver.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ void LayoutAnimationDriver::animationMutationsForFrame(
7474
}
7575
}
7676

77+
// Record boundary: animation-frame Updates above this point carry
78+
// parentTag from before any structural changes and must execute first.
79+
auto animationUpdatesEnd = mutationsList.size();
80+
7781
// Clear out finished animations
7882
for (auto it = inflightAnimations_.begin();
7983
it != inflightAnimations_.end();) {
@@ -99,10 +103,11 @@ void LayoutAnimationDriver::animationMutationsForFrame(
99103
}
100104
}
101105

102-
// Final step: make sure that all operations execute in the proper order.
103-
// REMOVE operations with highest indices must operate first.
106+
// Sort only the final mutations from completed animations.
107+
// Animation-frame Updates must stay before structural mutations because
108+
// they reference views by their pre-structural-change parentTag.
104109
std::stable_sort(
105-
mutationsList.begin(),
110+
mutationsList.begin() + static_cast<ptrdiff_t>(animationUpdatesEnd),
106111
mutationsList.end(),
107112
&shouldFirstComeBeforeSecondMutation);
108113
}

0 commit comments

Comments
 (0)