Skip to content

Commit

Permalink
feat: Add experimental flag to disable swizzling of NSData (#4859)
Browse files Browse the repository at this point in the history
  • Loading branch information
philprime authored Feb 21, 2025
1 parent 2181106 commit 25f4e43
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Improvements

- Log message when setting user before starting the SDK (#4882)
- Add experimental flag to disable swizzling of `NSData` individually (#4859)

## 8.45.0

Expand Down
4 changes: 2 additions & 2 deletions Sources/Sentry/SentryFileIOTrackingIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ - (BOOL)installWithOptions:(SentryOptions *)options

- (SentryIntegrationOption)integrationOptions
{
return kIntegrationOptionEnableSwizzling | kIntegrationOptionIsTracingEnabled
| kIntegrationOptionEnableAutoPerformanceTracing | kIntegrationOptionEnableFileIOTracing;
return kIntegrationOptionIsTracingEnabled | kIntegrationOptionEnableAutoPerformanceTracing
| kIntegrationOptionEnableFileIOTracing;
}

- (void)uninstall
Expand Down
11 changes: 11 additions & 0 deletions Sources/Sentry/SentryNSDataSwizzling.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ - (void)startWithOptions:(SentryOptions *)options tracker:(SentryFileIOTracker *
{
self.tracker = tracker;

if (!options.enableSwizzling) {
SENTRY_LOG_DEBUG(@"Auto-tracking of NSData is disabled because enableSwizzling is false");
return;
}

if (!options.experimental.enableDataSwizzling) {
SENTRY_LOG_DEBUG(
@"Auto-tracking of NSData is disabled because enableDataSwizzling is false");
return;
}

[SentryNSDataSwizzling swizzle];
}

Expand Down
9 changes: 8 additions & 1 deletion Sources/Sentry/SentryNSFileManagerSwizzling.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@ - (void)startWithOptions:(SentryOptions *)options tracker:(SentryFileIOTracker *
{
self.tracker = tracker;

if (!options.enableSwizzling) {
SENTRY_LOG_DEBUG(
@"Auto-tracking of NSFileManager is disabled because enableSwizzling is false");
return;
}

if (!options.experimental.enableFileManagerSwizzling) {
SENTRY_LOG_DEBUG(@"Experimental auto-tracking of FileManager is disabled")
SENTRY_LOG_DEBUG(@"Auto-tracking of NSFileManager is disabled because "
@"enableFileManagerSwizzling is false");
return;
}

Expand Down
14 changes: 14 additions & 0 deletions Sources/Swift/SentryExperimentalOptions.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
@objcMembers
public class SentryExperimentalOptions: NSObject {
/**
* Enables swizzling of`NSData` to automatically track file operations.
*
* - Note: Swizzling is enabled by setting ``SentryOptions.enableSwizzling`` to `true`.
* This option allows you to disable swizzling for `NSData` only, while keeping swizzling enabled for other classes.
* This is useful if you want to use manual tracing for file operations.
*/
public var enableDataSwizzling = true

/**
* Enables swizzling of`NSFileManager` to automatically track file operations.
*
* - Note: Swizzling is enabled by setting ``SentryOptions.enableSwizzling`` to `true`.
* This option allows you to disable swizzling for `NSFileManager` only, while keeping swizzling enabled for other classes.
* This is useful if you want to use manual tracing for file operations.
* - Experiment: This is an experimental feature and is therefore disabled by default. We'll enable it by default in a future release.
*/
public var enableFileManagerSwizzling = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ class SentryFileIOTrackingIntegrationTests: XCTestCase {
let fileURL: URL!
let fileDirectory: URL!

func getOptions(enableAutoPerformanceTracing: Bool = true, enableFileIOTracing: Bool = true, enableSwizzling: Bool = true, tracesSampleRate: NSNumber = 1) -> Options {
func getOptions(enableAutoPerformanceTracing: Bool = true, enableFileIOTracing: Bool = true, enableSwizzling: Bool = true, enableDataSwizzling: Bool = true, enableFileManagerSwizzling: Bool = true, tracesSampleRate: NSNumber = 1) -> Options {
let result = Options()
result.enableAutoPerformanceTracing = enableAutoPerformanceTracing
result.enableFileIOTracing = enableFileIOTracing
result.enableSwizzling = enableSwizzling
result.tracesSampleRate = tracesSampleRate
result.experimental.enableDataSwizzling = enableDataSwizzling
result.experimental.enableFileManagerSwizzling = enableFileManagerSwizzling
result.setIntegrations([SentryFileIOTrackingIntegration.self])
return result
}
Expand Down Expand Up @@ -228,7 +230,46 @@ class SentryFileIOTrackingIntegrationTests: XCTestCase {
let readValue = String(data: data, encoding: .utf8)
XCTAssertEqual(randomValue, readValue)
}


func testEnableDataSwizzling_isNotEnabled_shouldNotSwizzleNSDataMethods() {
// -- Arrange --
let options = fixture.getOptions(enableDataSwizzling: false)
SentrySDK.start(options: options)

// -- Act & Assert --
assertWriteWithNoSpans()
}

func testDisableFileManagerSwizzling_isNotEnabledAndDataSwizzlingIsEnabled_shouldTrackWithSpan() throws {
// -- Arrange --
if #available(iOS 18, macOS 15, tvOS 18, *) {
throw XCTSkip("File manager swizzling is not available for this OS version")
}
/// Older OS versions use `NSData` inside `NSFileManager`, therefore we need to test both swizzling options.
let options = fixture.getOptions(enableDataSwizzling: true, enableFileManagerSwizzling: false)
SentrySDK.start(options: options)

// -- Act & Assert --
assertSpans(1, "file.write") {
FileManager.default.createFile(atPath: fixture.filePath, contents: nil)
}
}

func testDisableFileManagerSwizzling_isNotEnabled_shouldNotTrackWithSpan() throws {
// -- Arrange --
if #available(iOS 18, macOS 15, tvOS 18, *) {
throw XCTSkip("File manager swizzling is not available for this OS version")
}
/// Older OS versions use `NSData` inside `NSFileManager`, therefore we need to disable both swizzling options.
let options = fixture.getOptions(enableDataSwizzling: false, enableFileManagerSwizzling: false)
SentrySDK.start(options: options)

// -- Act & Assert --
assertSpans(0, "file.write") {
FileManager.default.createFile(atPath: fixture.filePath, contents: nil)
}
}

private func assertWriteWithNoSpans() {
assertSpans(0, "file.write") {
try? fixture.data.write(to: fixture.fileURL)
Expand Down

0 comments on commit 25f4e43

Please sign in to comment.