From e2580fd35c1ba1cfa7ca17ce3e3c94919890085a Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 28 Jan 2025 15:48:39 +0100 Subject: [PATCH 1/5] fix: add NSNull handling to sentry_sanitize --- Sentry.xcodeproj/project.pbxproj | 20 ++- Sources/Sentry/SentryNSDictionarySanitize.m | 4 + .../SentryNSDictionarySanitizeTests.swift | 145 ++++++++++++++++++ .../SentryNSDictionarySanitize+Tests.h | 7 + .../SentryNSDictionarySanitize+Tests.m | 7 + .../SentryTests/SentryTests-Bridging-Header.h | 2 + 6 files changed, 179 insertions(+), 6 deletions(-) create mode 100644 Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift create mode 100644 Tests/SentryTests/SentryNSDictionarySanitize+Tests.h create mode 100644 Tests/SentryTests/SentryNSDictionarySanitize+Tests.m diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index cf7deb2989..50045c3e95 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -787,11 +787,13 @@ A8AFFCD42907E0CA00967CD7 /* SentryRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8AFFCD32907E0CA00967CD7 /* SentryRequestTests.swift */; }; A8F17B2E2901765900990B25 /* SentryRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F17B2D2901765900990B25 /* SentryRequest.m */; }; A8F17B342902870300990B25 /* SentryHttpStatusCodeRange.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F17B332902870300990B25 /* SentryHttpStatusCodeRange.m */; }; + D41909972D490BE5002B83D0 /* SentryNSDictionarySanitize+Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = D41909942D490006002B83D0 /* SentryNSDictionarySanitize+Tests.m */; }; + D42E48592D48FC9700D251BC /* SentryNSDictionarySanitizeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D42E48582D48FC8F00D251BC /* SentryNSDictionarySanitizeTests.swift */; }; D48724DB2D352597005DE483 /* SentryTraceOrigin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DA2D352591005DE483 /* SentryTraceOrigin.swift */; }; - D48724E22D354D16005DE483 /* SentryTraceOriginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */; }; - D48E8B8B2D3E79610032E35E /* SentryTraceOrigin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48E8B8A2D3E79610032E35E /* SentryTraceOrigin.swift */; }; D48724DD2D354939005DE483 /* SentrySpanOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DC2D354934005DE483 /* SentrySpanOperation.swift */; }; D48724E02D3549CA005DE483 /* SentrySpanOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */; }; + D48724E22D354D16005DE483 /* SentryTraceOriginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */; }; + D48E8B8B2D3E79610032E35E /* SentryTraceOrigin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48E8B8A2D3E79610032E35E /* SentryTraceOrigin.swift */; }; D48E8B9D2D3E82AC0032E35E /* SentrySpanOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48E8B9C2D3E82AC0032E35E /* SentrySpanOperation.swift */; }; D4AF00212D2E92FD00F5F3D7 /* SentryNSFileManagerSwizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AF00202D2E92FD00F5F3D7 /* SentryNSFileManagerSwizzling.m */; }; D4AF00232D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = D4AF00222D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h */; }; @@ -1891,11 +1893,14 @@ A8AFFCD32907E0CA00967CD7 /* SentryRequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryRequestTests.swift; sourceTree = ""; }; A8F17B2D2901765900990B25 /* SentryRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryRequest.m; sourceTree = ""; }; A8F17B332902870300990B25 /* SentryHttpStatusCodeRange.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryHttpStatusCodeRange.m; sourceTree = ""; }; + D41909922D48FFF6002B83D0 /* SentryNSDictionarySanitize+Tests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryNSDictionarySanitize+Tests.h"; sourceTree = ""; }; + D41909942D490006002B83D0 /* SentryNSDictionarySanitize+Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SentryNSDictionarySanitize+Tests.m"; sourceTree = ""; }; + D42E48582D48FC8F00D251BC /* SentryNSDictionarySanitizeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNSDictionarySanitizeTests.swift; sourceTree = ""; }; D48724DA2D352591005DE483 /* SentryTraceOrigin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOrigin.swift; sourceTree = ""; }; - D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOriginTests.swift; sourceTree = ""; }; - D48E8B8A2D3E79610032E35E /* SentryTraceOrigin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOrigin.swift; sourceTree = ""; }; D48724DC2D354934005DE483 /* SentrySpanOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperation.swift; sourceTree = ""; }; D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperationTests.swift; sourceTree = ""; }; + D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOriginTests.swift; sourceTree = ""; }; + D48E8B8A2D3E79610032E35E /* SentryTraceOrigin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOrigin.swift; sourceTree = ""; }; D48E8B9C2D3E82AC0032E35E /* SentrySpanOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperation.swift; sourceTree = ""; }; D4AF00202D2E92FD00F5F3D7 /* SentryNSFileManagerSwizzling.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryNSFileManagerSwizzling.m; sourceTree = ""; }; D4AF00222D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryNSFileManagerSwizzling.h; path = include/SentryNSFileManagerSwizzling.h; sourceTree = ""; }; @@ -2581,6 +2586,8 @@ 630436151EC0AD3100C4D3FA /* SentryNSDataCompressionTests.m */, 63EED6C22237989300E02400 /* SentryOptionsTest.m */, 7B569DFF2590EEF600B653FC /* SentryScope+Equality.m */, + D41909922D48FFF6002B83D0 /* SentryNSDictionarySanitize+Tests.h */, + D41909942D490006002B83D0 /* SentryNSDictionarySanitize+Tests.m */, 632331F52404FFA8008D91D6 /* SentryScopeTests.m */, 7B0002312477F0520035FEF1 /* SentrySessionTests.m */, 63AA75951EB8AEDB00D153DE /* SentryTests.m */, @@ -2991,6 +2998,7 @@ 7B6438AD26A710E6000D0F65 /* Categories */ = { isa = PBXGroup; children = ( + D42E48582D48FC8F00D251BC /* SentryNSDictionarySanitizeTests.swift */, 7B6438A626A70DDB000D0F65 /* UIViewControllerSentryTests.swift */, 7B0DC73328869BF40039995F /* NSMutableDictionarySentryTests.swift */, ); @@ -3634,8 +3642,6 @@ 8ECC674325C23A1F000E2BF6 /* SentrySpanContext.m */, 622C08D929E554B9002571D4 /* SentrySpanContext+Private.h */, 8E4E7C7325DAAB49006AB9E2 /* SentrySpanProtocol.h */, - 7B3B83712833832B0001FDEB /* SentrySpanOperations.h */, - 622C08D729E546F4002571D4 /* SentryTraceOrigins.h */, 8E4E7C6C25DAAAFE006AB9E2 /* SentrySpan.h */, 84A789092C0E9F5800FF0803 /* SentrySpan+Private.h */, 8EC3AE7925CA23B600E7591A /* SentrySpan.m */, @@ -5102,6 +5108,7 @@ 7BC6EC10255C3F560059822A /* SentryMechanismTests.swift in Sources */, 63FE721B20DA66EC00CDBAE8 /* Container+DeepSearch_Tests.m in Sources */, 8EA05EED267C2AB200C82B30 /* SentryNetworkTrackerTests.swift in Sources */, + D41909972D490BE5002B83D0 /* SentryNSDictionarySanitize+Tests.m in Sources */, 7BA840A024A1EC6E00B718AA /* SentrySDKTests.swift in Sources */, D8AE48BF2C578D540092A2A6 /* SentryLog.swift in Sources */, D8F6A24E288553A800320515 /* SentryPredicateDescriptorTests.swift in Sources */, @@ -5112,6 +5119,7 @@ 7BC6EC08255C36DE0059822A /* SentryStacktraceTests.swift in Sources */, D88817DD26D72BA500BF2251 /* SentryTraceStateTests.swift in Sources */, 7B26BBFB24C0A66D00A79CCC /* SentrySdkInfoNilTests.m in Sources */, + D42E48592D48FC9700D251BC /* SentryNSDictionarySanitizeTests.swift in Sources */, 7B984A9F28E572AF001F4BEE /* CrashReport.swift in Sources */, D4AF00252D2E93C400F5F3D7 /* SentryNSFileManagerSwizzlingTests.m in Sources */, 7BED3576266F7BFF00EAA70D /* TestSentryCrashWrapper.m in Sources */, diff --git a/Sources/Sentry/SentryNSDictionarySanitize.m b/Sources/Sentry/SentryNSDictionarySanitize.m index 536d161edc..cb45488775 100644 --- a/Sources/Sentry/SentryNSDictionarySanitize.m +++ b/Sources/Sentry/SentryNSDictionarySanitize.m @@ -8,6 +8,10 @@ return nil; } + if ([dictionary isEqual:[NSNull null]]) { + return nil; + } + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; for (id rawKey in dictionary.allKeys) { id rawValue = [dictionary objectForKey:rawKey]; diff --git a/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift b/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift new file mode 100644 index 0000000000..43ce296eeb --- /dev/null +++ b/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift @@ -0,0 +1,145 @@ +@testable import Sentry +import SentryTestUtils +import XCTest + +class SentryNSDictionarySanitizeTests: XCTestCase { + func testSentrySanitize_dictionaryIsNil_shouldReturnNil() { + // Arrange + let dict: [String: Any]? = nil + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertNil(sanitized) + } + + func testSentrySanitize_dictionaryIsNSNull_shouldReturnNil() { + // Act + let sanitized = sentry_sanitize_with_nsnull() + // Assert + XCTAssertNil(sanitized) + } + + func testSentrySanitize_dictionaryIsEmpty_shouldReturnEmptyDictionary() { + // Arrange + let dict = [String: Any]() + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertEqual(sanitized?.count, 0) + } + + func testSentrySanitize_dictionaryKeyIsString_shouldUseKey() { + // Arrange + let dict = ["key": "value"] + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertEqual(sanitized?["key"] as? String, "value") + } + + func testSentrySanitize_dictionaryKeyIsNotString_shouldUseKeyDescriptionAsKey() { + // Arrange + let dict: [AnyHashable: Any] = [ + 1: "number value", + Float(0.123456789): "float value", + Double(9.87654321): "double value", + Date(timeIntervalSince1970: 1_234): "date value" + ] + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertEqual(sanitized?.count, 4) + XCTAssertEqual(sanitized?["1"] as? String, "number value") + XCTAssertEqual(sanitized?["0.1234568"] as? String, "float value") + XCTAssertEqual(sanitized?["9.876543209999999"] as? String, "double value") + XCTAssertEqual(sanitized?["1970-01-01 00:20:34 +0000"] as? String, "date value") + } + + func testSentrySanitize_dictionaryKeyIsBoolean_willCollideWithNumberKey() { + // This test is only added for locking down the expected behaviour. + // The key `true` is bridged to a `_NSCFBoolean` which is a type alias + // for `CFBoolean` which is defined as `1` for `true` and `0` for `false`. + // Therefore any boolean will be casted to a number and treated equally. + + // Arrange + let dict: [AnyHashable: Any] = [ + 1: "number value", + true: "bool value" + ] + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertEqual(sanitized?.count, 1) + // The order is not deterministic, so it can be either one. + let value = sanitized?["1"] as? String + XCTAssertTrue(value == "number value" || value == "bool value") + } + + func testSentrySanitize_keyStartsWithSentryIdentifier_shouldIgnoreValue() { + // Arrange + let dict = ["__sentry_key": "value", "__sentry": "value 2", "key": "value 3"] + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertEqual(sanitized?.count, 1) + XCTAssertEqual(sanitized?["key"] as? String, "value 3") + } + + func testSentrySanitize_dictionaryValueIsString_shouldUseValue() { + // Arrange + let dict = ["key": "value"] + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertEqual(sanitized?["key"] as? String, "value") + } + + func testSentrySanitize_dictionaryValueIsNumber_shouldUseValueDescription() { + // Arrange + let dict = ["key": 123] + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertEqual(sanitized?["key"] as? Int, 123) + } + + func testSentrySanitize_dictionaryValueIsDictionary_shouldSanitizeValue() { + // Arrange + let dict = ["key": ["__sentry": "value 1", "key": "value 2"]] + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertEqual(sanitized?["key"] as? [String: String], ["key": "value 2"]) + } + + func testSentrySanitize_dictionaryValueIsArray_shouldSanitizeEveryElement() { + // Arrange + let dict = ["key": ["value", "value 2"]] + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertEqual(sanitized?["key"] as? [String], ["value", "value 2"]) + } + + func testSentrySanitize_dictionaryValueIsDate_shouldUseISO8601FormatAsValue() { + // Arrange + let date = Date(timeIntervalSince1970: 1_234) + let dict = ["key": date] + // Act + let sanitized = sentry_sanitize(dict) + // Assert + XCTAssertEqual(sanitized?["key"] as? String, "1970-01-01T00:20:34.000Z") + } + + func testSentrySanitize_dictionaryValueIsOtherType_shouldUseObjectDescriptionAsValue() throws { + // Arrange + let dict = ["key": NSObject()] + // Act + let sanitized = sentry_sanitize(dict) + // Assert + let value = try XCTUnwrap(sanitized?["key"] as? String) + let regex = try NSRegularExpression(pattern: "^$") + let result = regex.matches(in: value, range: NSRange(location: 0, length: value.count)) + XCTAssertFalse(result.isEmpty) + } +} diff --git a/Tests/SentryTests/SentryNSDictionarySanitize+Tests.h b/Tests/SentryTests/SentryNSDictionarySanitize+Tests.h new file mode 100644 index 0000000000..5c421cdc49 --- /dev/null +++ b/Tests/SentryTests/SentryNSDictionarySanitize+Tests.h @@ -0,0 +1,7 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +NSDictionary *_Nullable sentry_sanitize_with_nsnull(void); + +NS_ASSUME_NONNULL_END diff --git a/Tests/SentryTests/SentryNSDictionarySanitize+Tests.m b/Tests/SentryTests/SentryNSDictionarySanitize+Tests.m new file mode 100644 index 0000000000..2fd10fd945 --- /dev/null +++ b/Tests/SentryTests/SentryNSDictionarySanitize+Tests.m @@ -0,0 +1,7 @@ +#import "SentryNSDictionarySanitize.h" + +NSDictionary *_Nullable sentry_sanitize_with_nsnull(void) +{ + // Cast [NSNull null] to NSDictionary to avoid compiler warnings/errors + return sentry_sanitize((NSDictionary *)[NSNull null]); +} diff --git a/Tests/SentryTests/SentryTests-Bridging-Header.h b/Tests/SentryTests/SentryTests-Bridging-Header.h index 6664f558ee..e6dd458623 100644 --- a/Tests/SentryTests/SentryTests-Bridging-Header.h +++ b/Tests/SentryTests/SentryTests-Bridging-Header.h @@ -146,6 +146,8 @@ #import "SentryMigrateSessionInit.h" #import "SentryMsgPackSerializer.h" #import "SentryNSDataUtils.h" +#import "SentryNSDictionarySanitize+Tests.h" +#import "SentryNSDictionarySanitize.h" #import "SentryNSError.h" #import "SentryNSNotificationCenterWrapper.h" #import "SentryNSProcessInfoWrapper.h" From 966b70a065effd83cf5e40ca797f83a8ce370dfc Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 28 Jan 2025 15:50:46 +0100 Subject: [PATCH 2/5] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb0ed9b9d3..89161c0493 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Use strlcpy to save session replay info path (#4740) - `sentryReplayUnmask` and `sentryReplayUnmask` preventing interaction (#4749) - Missing `SentryCrashExceptionApplication` implementation for non-macOS target (#4759) +- Add `NSNull` handling to `sentry_sanitize` (#4760) ### Improvements From 7965086af5e5e4597ab6255d77df94ca94c6f22d Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Wed, 29 Jan 2025 11:23:05 +0100 Subject: [PATCH 3/5] add subclass check --- Sentry.xcodeproj/project.pbxproj | 12 ++++++------ Sources/Sentry/SentryNSDictionarySanitize.m | 2 +- .../Categories/SentryNSDictionarySanitizeTests.swift | 7 +++++++ Tests/SentryTests/SentryNSDictionarySanitize+Tests.h | 1 + Tests/SentryTests/SentryNSDictionarySanitize+Tests.m | 6 ++++++ 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 50045c3e95..231d680f9b 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -787,13 +787,11 @@ A8AFFCD42907E0CA00967CD7 /* SentryRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8AFFCD32907E0CA00967CD7 /* SentryRequestTests.swift */; }; A8F17B2E2901765900990B25 /* SentryRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F17B2D2901765900990B25 /* SentryRequest.m */; }; A8F17B342902870300990B25 /* SentryHttpStatusCodeRange.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F17B332902870300990B25 /* SentryHttpStatusCodeRange.m */; }; - D41909972D490BE5002B83D0 /* SentryNSDictionarySanitize+Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = D41909942D490006002B83D0 /* SentryNSDictionarySanitize+Tests.m */; }; - D42E48592D48FC9700D251BC /* SentryNSDictionarySanitizeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D42E48582D48FC8F00D251BC /* SentryNSDictionarySanitizeTests.swift */; }; D48724DB2D352597005DE483 /* SentryTraceOrigin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DA2D352591005DE483 /* SentryTraceOrigin.swift */; }; - D48724DD2D354939005DE483 /* SentrySpanOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DC2D354934005DE483 /* SentrySpanOperation.swift */; }; - D48724E02D3549CA005DE483 /* SentrySpanOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */; }; D48724E22D354D16005DE483 /* SentryTraceOriginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */; }; D48E8B8B2D3E79610032E35E /* SentryTraceOrigin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48E8B8A2D3E79610032E35E /* SentryTraceOrigin.swift */; }; + D48724DD2D354939005DE483 /* SentrySpanOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DC2D354934005DE483 /* SentrySpanOperation.swift */; }; + D48724E02D3549CA005DE483 /* SentrySpanOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */; }; D48E8B9D2D3E82AC0032E35E /* SentrySpanOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48E8B9C2D3E82AC0032E35E /* SentrySpanOperation.swift */; }; D4AF00212D2E92FD00F5F3D7 /* SentryNSFileManagerSwizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AF00202D2E92FD00F5F3D7 /* SentryNSFileManagerSwizzling.m */; }; D4AF00232D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = D4AF00222D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h */; }; @@ -1897,10 +1895,10 @@ D41909942D490006002B83D0 /* SentryNSDictionarySanitize+Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SentryNSDictionarySanitize+Tests.m"; sourceTree = ""; }; D42E48582D48FC8F00D251BC /* SentryNSDictionarySanitizeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNSDictionarySanitizeTests.swift; sourceTree = ""; }; D48724DA2D352591005DE483 /* SentryTraceOrigin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOrigin.swift; sourceTree = ""; }; - D48724DC2D354934005DE483 /* SentrySpanOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperation.swift; sourceTree = ""; }; - D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperationTests.swift; sourceTree = ""; }; D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOriginTests.swift; sourceTree = ""; }; D48E8B8A2D3E79610032E35E /* SentryTraceOrigin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOrigin.swift; sourceTree = ""; }; + D48724DC2D354934005DE483 /* SentrySpanOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperation.swift; sourceTree = ""; }; + D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperationTests.swift; sourceTree = ""; }; D48E8B9C2D3E82AC0032E35E /* SentrySpanOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperation.swift; sourceTree = ""; }; D4AF00202D2E92FD00F5F3D7 /* SentryNSFileManagerSwizzling.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryNSFileManagerSwizzling.m; sourceTree = ""; }; D4AF00222D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryNSFileManagerSwizzling.h; path = include/SentryNSFileManagerSwizzling.h; sourceTree = ""; }; @@ -3642,6 +3640,8 @@ 8ECC674325C23A1F000E2BF6 /* SentrySpanContext.m */, 622C08D929E554B9002571D4 /* SentrySpanContext+Private.h */, 8E4E7C7325DAAB49006AB9E2 /* SentrySpanProtocol.h */, + 7B3B83712833832B0001FDEB /* SentrySpanOperations.h */, + 622C08D729E546F4002571D4 /* SentryTraceOrigins.h */, 8E4E7C6C25DAAAFE006AB9E2 /* SentrySpan.h */, 84A789092C0E9F5800FF0803 /* SentrySpan+Private.h */, 8EC3AE7925CA23B600E7591A /* SentrySpan.m */, diff --git a/Sources/Sentry/SentryNSDictionarySanitize.m b/Sources/Sentry/SentryNSDictionarySanitize.m index cb45488775..faa72c5dfa 100644 --- a/Sources/Sentry/SentryNSDictionarySanitize.m +++ b/Sources/Sentry/SentryNSDictionarySanitize.m @@ -8,7 +8,7 @@ return nil; } - if ([dictionary isEqual:[NSNull null]]) { + if (![[dictionary class] isSubclassOfClass:[NSDictionary class]]) { return nil; } diff --git a/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift b/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift index 43ce296eeb..e3e4059004 100644 --- a/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift +++ b/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift @@ -19,6 +19,13 @@ class SentryNSDictionarySanitizeTests: XCTestCase { XCTAssertNil(sanitized) } + func testSentrySanitize_parameterIsNotNSDictionary_shouldReturnNil() { + // Act + let sanitized = sentry_sanitize_with_non_dictionary() + // Assert + XCTAssertNil(sanitized) + } + func testSentrySanitize_dictionaryIsEmpty_shouldReturnEmptyDictionary() { // Arrange let dict = [String: Any]() diff --git a/Tests/SentryTests/SentryNSDictionarySanitize+Tests.h b/Tests/SentryTests/SentryNSDictionarySanitize+Tests.h index 5c421cdc49..49446d244e 100644 --- a/Tests/SentryTests/SentryNSDictionarySanitize+Tests.h +++ b/Tests/SentryTests/SentryNSDictionarySanitize+Tests.h @@ -3,5 +3,6 @@ NS_ASSUME_NONNULL_BEGIN NSDictionary *_Nullable sentry_sanitize_with_nsnull(void); +NSDictionary *_Nullable sentry_sanitize_with_non_dictionary(void); NS_ASSUME_NONNULL_END diff --git a/Tests/SentryTests/SentryNSDictionarySanitize+Tests.m b/Tests/SentryTests/SentryNSDictionarySanitize+Tests.m index 2fd10fd945..d53a0c0714 100644 --- a/Tests/SentryTests/SentryNSDictionarySanitize+Tests.m +++ b/Tests/SentryTests/SentryNSDictionarySanitize+Tests.m @@ -5,3 +5,9 @@ // Cast [NSNull null] to NSDictionary to avoid compiler warnings/errors return sentry_sanitize((NSDictionary *)[NSNull null]); } + +NSDictionary *_Nullable sentry_sanitize_with_non_dictionary(void) +{ + // Cast @"non-dictionary" to NSDictionary to avoid compiler warnings/errors + return sentry_sanitize((NSDictionary *)@"non-dictionary"); +} From 044c91be5e8f99953c5d94e9aa1510d37bd04bd6 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Wed, 29 Jan 2025 16:52:09 +0100 Subject: [PATCH 4/5] Update Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift Co-authored-by: Philipp Hofmann --- .../Categories/SentryNSDictionarySanitizeTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift b/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift index e3e4059004..a0dc4b2539 100644 --- a/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift +++ b/Tests/SentryTests/Categories/SentryNSDictionarySanitizeTests.swift @@ -101,7 +101,7 @@ class SentryNSDictionarySanitizeTests: XCTestCase { XCTAssertEqual(sanitized?["key"] as? String, "value") } - func testSentrySanitize_dictionaryValueIsNumber_shouldUseValueDescription() { + func testSentrySanitize_dictionaryValueIsNumber_shouldUseValue() { // Arrange let dict = ["key": 123] // Act From 6eb4fe044e65059b63a16a4c8de67a8707173a5c Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Wed, 29 Jan 2025 17:01:27 +0100 Subject: [PATCH 5/5] fix test target --- Sentry.xcodeproj/project.pbxproj | 20 +++++++++---------- .../SentryNSDictionarySanitize+Tests.h | 0 .../SentryNSDictionarySanitize+Tests.m | 0 3 files changed, 10 insertions(+), 10 deletions(-) rename Tests/SentryTests/{ => Categories}/SentryNSDictionarySanitize+Tests.h (100%) rename Tests/SentryTests/{ => Categories}/SentryNSDictionarySanitize+Tests.m (100%) diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 231d680f9b..7ae2669d08 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -788,14 +788,16 @@ A8F17B2E2901765900990B25 /* SentryRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F17B2D2901765900990B25 /* SentryRequest.m */; }; A8F17B342902870300990B25 /* SentryHttpStatusCodeRange.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F17B332902870300990B25 /* SentryHttpStatusCodeRange.m */; }; D48724DB2D352597005DE483 /* SentryTraceOrigin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DA2D352591005DE483 /* SentryTraceOrigin.swift */; }; - D48724E22D354D16005DE483 /* SentryTraceOriginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */; }; - D48E8B8B2D3E79610032E35E /* SentryTraceOrigin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48E8B8A2D3E79610032E35E /* SentryTraceOrigin.swift */; }; D48724DD2D354939005DE483 /* SentrySpanOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DC2D354934005DE483 /* SentrySpanOperation.swift */; }; D48724E02D3549CA005DE483 /* SentrySpanOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */; }; + D48724E22D354D16005DE483 /* SentryTraceOriginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */; }; + D48E8B8B2D3E79610032E35E /* SentryTraceOrigin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48E8B8A2D3E79610032E35E /* SentryTraceOrigin.swift */; }; D48E8B9D2D3E82AC0032E35E /* SentrySpanOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48E8B9C2D3E82AC0032E35E /* SentrySpanOperation.swift */; }; D4AF00212D2E92FD00F5F3D7 /* SentryNSFileManagerSwizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AF00202D2E92FD00F5F3D7 /* SentryNSFileManagerSwizzling.m */; }; D4AF00232D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = D4AF00222D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h */; }; D4AF00252D2E93C400F5F3D7 /* SentryNSFileManagerSwizzlingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AF00242D2E93C400F5F3D7 /* SentryNSFileManagerSwizzlingTests.m */; }; + D4E3F35D2D4A864600F79E2B /* SentryNSDictionarySanitizeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D42E48582D48FC8F00D251BC /* SentryNSDictionarySanitizeTests.swift */; }; + D4E3F35E2D4A877300F79E2B /* SentryNSDictionarySanitize+Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = D41909942D490006002B83D0 /* SentryNSDictionarySanitize+Tests.m */; }; D4F2B5352D0C69D500649E42 /* SentryCrashCTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4F2B5342D0C69D100649E42 /* SentryCrashCTests.swift */; }; D8019910286B089000C277F0 /* SentryCrashReportSinkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D801990F286B089000C277F0 /* SentryCrashReportSinkTests.swift */; }; D802994E2BA836EF000F0081 /* SentryOnDemandReplay.swift in Sources */ = {isa = PBXBuildFile; fileRef = D802994D2BA836EF000F0081 /* SentryOnDemandReplay.swift */; }; @@ -1895,10 +1897,10 @@ D41909942D490006002B83D0 /* SentryNSDictionarySanitize+Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SentryNSDictionarySanitize+Tests.m"; sourceTree = ""; }; D42E48582D48FC8F00D251BC /* SentryNSDictionarySanitizeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNSDictionarySanitizeTests.swift; sourceTree = ""; }; D48724DA2D352591005DE483 /* SentryTraceOrigin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOrigin.swift; sourceTree = ""; }; - D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOriginTests.swift; sourceTree = ""; }; - D48E8B8A2D3E79610032E35E /* SentryTraceOrigin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOrigin.swift; sourceTree = ""; }; D48724DC2D354934005DE483 /* SentrySpanOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperation.swift; sourceTree = ""; }; D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperationTests.swift; sourceTree = ""; }; + D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOriginTests.swift; sourceTree = ""; }; + D48E8B8A2D3E79610032E35E /* SentryTraceOrigin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOrigin.swift; sourceTree = ""; }; D48E8B9C2D3E82AC0032E35E /* SentrySpanOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperation.swift; sourceTree = ""; }; D4AF00202D2E92FD00F5F3D7 /* SentryNSFileManagerSwizzling.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryNSFileManagerSwizzling.m; sourceTree = ""; }; D4AF00222D2E931000F5F3D7 /* SentryNSFileManagerSwizzling.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryNSFileManagerSwizzling.h; path = include/SentryNSFileManagerSwizzling.h; sourceTree = ""; }; @@ -2584,8 +2586,6 @@ 630436151EC0AD3100C4D3FA /* SentryNSDataCompressionTests.m */, 63EED6C22237989300E02400 /* SentryOptionsTest.m */, 7B569DFF2590EEF600B653FC /* SentryScope+Equality.m */, - D41909922D48FFF6002B83D0 /* SentryNSDictionarySanitize+Tests.h */, - D41909942D490006002B83D0 /* SentryNSDictionarySanitize+Tests.m */, 632331F52404FFA8008D91D6 /* SentryScopeTests.m */, 7B0002312477F0520035FEF1 /* SentrySessionTests.m */, 63AA75951EB8AEDB00D153DE /* SentryTests.m */, @@ -2996,6 +2996,8 @@ 7B6438AD26A710E6000D0F65 /* Categories */ = { isa = PBXGroup; children = ( + D41909922D48FFF6002B83D0 /* SentryNSDictionarySanitize+Tests.h */, + D41909942D490006002B83D0 /* SentryNSDictionarySanitize+Tests.m */, D42E48582D48FC8F00D251BC /* SentryNSDictionarySanitizeTests.swift */, 7B6438A626A70DDB000D0F65 /* UIViewControllerSentryTests.swift */, 7B0DC73328869BF40039995F /* NSMutableDictionarySentryTests.swift */, @@ -3640,8 +3642,6 @@ 8ECC674325C23A1F000E2BF6 /* SentrySpanContext.m */, 622C08D929E554B9002571D4 /* SentrySpanContext+Private.h */, 8E4E7C7325DAAB49006AB9E2 /* SentrySpanProtocol.h */, - 7B3B83712833832B0001FDEB /* SentrySpanOperations.h */, - 622C08D729E546F4002571D4 /* SentryTraceOrigins.h */, 8E4E7C6C25DAAAFE006AB9E2 /* SentrySpan.h */, 84A789092C0E9F5800FF0803 /* SentrySpan+Private.h */, 8EC3AE7925CA23B600E7591A /* SentrySpan.m */, @@ -5108,7 +5108,7 @@ 7BC6EC10255C3F560059822A /* SentryMechanismTests.swift in Sources */, 63FE721B20DA66EC00CDBAE8 /* Container+DeepSearch_Tests.m in Sources */, 8EA05EED267C2AB200C82B30 /* SentryNetworkTrackerTests.swift in Sources */, - D41909972D490BE5002B83D0 /* SentryNSDictionarySanitize+Tests.m in Sources */, + D4E3F35E2D4A877300F79E2B /* SentryNSDictionarySanitize+Tests.m in Sources */, 7BA840A024A1EC6E00B718AA /* SentrySDKTests.swift in Sources */, D8AE48BF2C578D540092A2A6 /* SentryLog.swift in Sources */, D8F6A24E288553A800320515 /* SentryPredicateDescriptorTests.swift in Sources */, @@ -5119,7 +5119,7 @@ 7BC6EC08255C36DE0059822A /* SentryStacktraceTests.swift in Sources */, D88817DD26D72BA500BF2251 /* SentryTraceStateTests.swift in Sources */, 7B26BBFB24C0A66D00A79CCC /* SentrySdkInfoNilTests.m in Sources */, - D42E48592D48FC9700D251BC /* SentryNSDictionarySanitizeTests.swift in Sources */, + D4E3F35D2D4A864600F79E2B /* SentryNSDictionarySanitizeTests.swift in Sources */, 7B984A9F28E572AF001F4BEE /* CrashReport.swift in Sources */, D4AF00252D2E93C400F5F3D7 /* SentryNSFileManagerSwizzlingTests.m in Sources */, 7BED3576266F7BFF00EAA70D /* TestSentryCrashWrapper.m in Sources */, diff --git a/Tests/SentryTests/SentryNSDictionarySanitize+Tests.h b/Tests/SentryTests/Categories/SentryNSDictionarySanitize+Tests.h similarity index 100% rename from Tests/SentryTests/SentryNSDictionarySanitize+Tests.h rename to Tests/SentryTests/Categories/SentryNSDictionarySanitize+Tests.h diff --git a/Tests/SentryTests/SentryNSDictionarySanitize+Tests.m b/Tests/SentryTests/Categories/SentryNSDictionarySanitize+Tests.m similarity index 100% rename from Tests/SentryTests/SentryNSDictionarySanitize+Tests.m rename to Tests/SentryTests/Categories/SentryNSDictionarySanitize+Tests.m