Skip to content

Commit fae21d3

Browse files
tomekzawclaude
andcommitted
Don't keep paragraph content with attachments across clones
Attachments hold raw pointers to the children the content was built from, and layout() replaces those children with laid-out clones. A clone that kept that content pointed at nodes only the previous revision still owned, and once that revision was released, layout() read freed memory and crashed in ParagraphShadowNode::layout. Only keep content that has no attachments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 70f59c1 commit fae21d3

1 file changed

Lines changed: 8 additions & 2 deletions

File tree

‎packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,17 @@ ParagraphShadowNode::ParagraphShadowNode(
6464
// attributed string and the layouts measured for it instead of rebuilding
6565
// and re-measuring them. `getContent` drops both if the layout context they
6666
// were built for no longer matches.
67+
//
68+
// Content with attachments is not kept: they point at the children the
69+
// content was built from, and `layout` replaces those children with laid-out
70+
// clones, so in a later revision the pointers would outlive the nodes.
6771
if (fragment.props == nullptr && fragment.children == nullptr) {
6872
const auto& source =
6973
static_cast<const ParagraphShadowNode&>(sourceShadowNode);
70-
content_ = source.content_;
71-
measuredLayouts_ = source.measuredLayouts_;
74+
if (source.content_.has_value() && source.content_->attachments.empty()) {
75+
content_ = source.content_;
76+
measuredLayouts_ = source.measuredLayouts_;
77+
}
7278
}
7379
}
7480

0 commit comments

Comments
 (0)