Skip to content

refactor(ios): Migrate from PrivateSentrySDKOnly to SentrySDK.internal#6380

Open
alwx wants to merge 13 commits into
mainfrom
alwx/refactor/migrate-private-sentry-sdk-only
Open

refactor(ios): Migrate from PrivateSentrySDKOnly to SentrySDK.internal#6380
alwx wants to merge 13 commits into
mainfrom
alwx/refactor/migrate-private-sentry-sdk-only

docs: Move iOS use_modular_headers note to Changes; reorder Unreleased

23f1729
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden completed Jul 7, 2026 in 0s

4 issues

Low

setCurrentScreen silently no-ops on visionOS, dropping current-screen breadcrumb enrichment - `packages/core/ios/RNSentryInternal.swift:110-125`

The #if os(iOS) || os(tvOS) guard in RNSentryInternal.swift makes setCurrentScreen an empty stub on visionOS, but RNSentry.mm calls [RNSentryInternal setCurrentScreen:screen] under #if SENTRY_HAS_UIKIT — which also resolves true on visionOS. As a result, breadcrumb current-screen enrichment is silently dropped on visionOS with no caller-visible indication, whereas the previous PrivateSentrySDKOnly.setCurrentScreen worked under SENTRY_UIKIT_AVAILABLE (including visionOS). The code comment explicitly acknowledges this as an accepted tradeoff aligned with sentry-cocoa's new hybrid API, so this is a documented, intentional regression worth confirming rather than a defect.

No test coverage for profiling bridge methods (`startProfiler`, `collectProfile`, `discardProfiler`) - `packages/core/ios/RNSentryInternal.swift:214-237`

Have you considered adding smoke tests for the three new profiling bridge methods in RNSentryInternalTests.swift? The swizzle bridge has testSwizzleRNSScreenViewDidAppearNoOpWhenClassMissing, but the profiling path — which is called from production code in RNSentry.mm — has no corresponding coverage.

Also found at:

  • packages/core/ios/RNSentryInternal.swift:131-133
TOCTOU: currentScreenFrames read twice — returns @0 instead of nil on race - `packages/core/RNSentryCocoaTester/RNSentryCocoaTester.xcodeproj/project.pbxproj:22`

In SentryScreenFramesWrapper.m, totalFrames/frozenFrames/slowFrames each call canTrackFrames (which reads RNSentryInternal.currentScreenFrames) and then read currentScreenFrames a second time. If the frames tracker stops between these two accesses, the nil ObjC property read returns 0, so the caller in RNSentry.mm resolves with @{"totalFrames": @0, ...} instead of nil, reporting incorrect zeroed frame data to JavaScript.

UnsafeRawPointer from withUnsafePointer escapes closure as swizzle dedup key in swizzleRNSScreenViewDidAppear - `packages/core/RNSentryCocoaTester/RNSentryCocoaTester.xcodeproj/project.pbxproj:22`

In RNSentryInternal.swift, swizzleRNSScreenViewDidAppear obtains keyPtr via withUnsafePointer(to: &rnsScreenViewDidAppearKey) and passes UnsafeRawPointer(keyPtr) as the key: argument to SentrySDK.internal.swizzle.instanceMethod(_:in:mode:key:factory:). For .oncePerClass deduplication, sentry-cocoa retains that key pointer beyond the closure. Swift's withUnsafePointer(to:) only guarantees the pointer is valid within the closure body, so retaining it afterward is formally undefined behavior. In practice rnsScreenViewDidAppearKey is a static var with stable global storage, so no crash occurs today and the dedup key remains stable across calls; this is a low-severity correctness/idiom concern rather than an exploitable bug.

4 skills analyzed
Skill Findings Duration Cost
security-review 0 18.6s $0.42
code-review 2 5m 52s $1.94
find-bugs 2 16m 46s $5.61
gha-security-review 0 12m 10s $0.32

⏱ 35m 7s · 3.8M in / 227.2k out · $8.29