You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Fabric differ (Differentiator.cpp) makes incorrect mutations for one tree shape. It creates a view that is already mounted. Or it deletes a view that only moves.
The tree has three nested views: Q > U > F. Q and F have opacity. F has three children. The second child (K) has zIndex: -1.
When the opacity moves from F to U in one commit, U unflattens and F flattens. The children of F move to U. The opposite change also causes the bug.
Result:
iOS Debug: the app crashes on the first change. RCTComponentViewRegistry asserts: "Attempt to dequeue already registered component."
iOS Release: the app crashes with SIGSEGV in -[RCTMountingManager performTransaction:] (I saw this on 0.88.0-rc.2).
Android: the app does not crash. The Android mounting layer ignores a Create for a tag that it already has. The differ output is still incorrect.
If you remove zIndex: -1 from K, the differ output is correct.
Cause (suspected):
This below cause came from AI assisted analysis of the situation
In calculateShadowViewMutationsFlattener, the differ sorts the children by orderIndex. Thus it visits K before F. At that time, nothing has matched K, so K becomes a delete or create candidate. Then the nested (un)flattening of F matches K through a different ShadowViewNodePair. It records K in subVisitedNewMap or subVisitedOldMap. But the last loop over the candidates checks only treeChildPair.inOtherTree(). Thus the differ deletes or creates K.
A related bug is in the same function. In the "flatten parent, unflatten child" branch, auto unvisitedItPair = *unvisitedOtherNodesIt->second; keeps the address of a local copy in unvisitedRecursiveChildPairs. This pointer is not valid after the loop iteration.
We found this bug through crash reports in react-native-reanimated (Layout Animations). The reproducer does not use Reanimated or any other library.
Description
The Fabric differ (
Differentiator.cpp) makes incorrect mutations for one tree shape. It creates a view that is already mounted. Or it deletes a view that only moves.The tree has three nested views: Q > U > F. Q and F have
opacity. F has three children. The second child (K) haszIndex: -1.When the opacity moves from F to U in one commit, U unflattens and F flattens. The children of F move to U. The opposite change also causes the bug.
Result:
RCTComponentViewRegistryasserts: "Attempt to dequeue already registered component."-[RCTMountingManager performTransaction:](I saw this on 0.88.0-rc.2).Createfor a tag that it already has. The differ output is still incorrect.If you remove
zIndex: -1from K, the differ output is correct.Cause (suspected):
This below cause came from AI assisted analysis of the situation
In
calculateShadowViewMutationsFlattener, the differ sorts the children byorderIndex. Thus it visits K before F. At that time, nothing has matched K, so K becomes a delete or create candidate. Then the nested (un)flattening of F matches K through a differentShadowViewNodePair. It records K insubVisitedNewMaporsubVisitedOldMap. But the last loop over the candidates checks onlytreeChildPair.inOtherTree(). Thus the differ deletes or creates K.A related bug is in the same function. In the "flatten parent, unflatten child" branch,
auto unvisitedItPair = *unvisitedOtherNodesIt->second;keeps the address of a local copy inunvisitedRecursiveChildPairs. This pointer is not valid after the loop iteration.We found this bug through crash reports in react-native-reanimated (Layout Animations). The reproducer does not use Reanimated or any other library.
Steps to reproduce
ReproducerAppdirectory.yarn install.cd ios && bundle install && bundle exec pod install && cd ...yarn ios.React Native Version
0.87.1
Affected Platforms
Runtime - iOS
Output of
npx @react-native-community/cli infoStacktrace or Logs
MANDATORY Reproducer
https://github.com/pawicao/rn-differ-zindex-flatten-repro
Screenshots and Videos
rn-differ-crash-ios.mp4