From a61a5bd12a9d93e6481114c5163eb110f96f2187 Mon Sep 17 00:00:00 2001 From: Pavel Yakimenko Date: Wed, 2 Mar 2022 19:17:26 +0000 Subject: [PATCH] Check class on property value validation --- Realm/RLMObjectBase.mm | 6 ++++-- Realm/Tests/ObjectCreationTests.mm | 8 ++++++++ RealmSwift/Tests/ObjectCreationTests.swift | 9 +++++++++ RealmSwift/Tests/SwiftTestObjects.swift | 9 +++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Realm/RLMObjectBase.mm b/Realm/RLMObjectBase.mm index 773c8887f0..362afd4efd 100644 --- a/Realm/RLMObjectBase.mm +++ b/Realm/RLMObjectBase.mm @@ -93,8 +93,7 @@ - (void)dealloc { } static id coerceToObjectType(id obj, Class cls, RLMSchema *schema) { - if (([obj isKindOfClass:cls] && ![(id)cls isEmbedded]) || - ([(id)cls isEmbedded] && [obj respondsToSelector:@selector(realm)] && ![obj realm])) { + if ([obj isKindOfClass:cls] && (![(id)cls isEmbedded] || ![obj realm])) { return obj; } obj = RLMBridgeSwiftValue(obj) ?: obj; @@ -533,6 +532,9 @@ id RLMObjectThaw(RLMObjectBase *obj) { } id RLMValidatedValueForProperty(id object, NSString *key, NSString *className) { + if (![[[object objectSchema] className] isEqualToString:className]) { + @throw RLMException(@"Invalid value: cannot initialize '%@' with value '%@'", className, object); + } @try { return [object valueForKey:key]; } diff --git a/Realm/Tests/ObjectCreationTests.mm b/Realm/Tests/ObjectCreationTests.mm index 6e8c166aae..20bfaf637b 100644 --- a/Realm/Tests/ObjectCreationTests.mm +++ b/Realm/Tests/ObjectCreationTests.mm @@ -529,6 +529,14 @@ - (void)testInitValidatesNumberTypes { XCTAssertNoThrow(([[NumberObject alloc] initWithValue:@{@"doubleObj": @DBL_MAX}])); } +- (void)testInitEmbeddedProperty { + NSArray *failVal = @[@{}, @{}, @{}, @{@"one": [[IntObject alloc] init]}]; + XCTAssertThrows([[DictionaryPropertyObject alloc] initWithValue:failVal]); + + NSArray *passVal = @[@{}, @{}, @{}, @{@"one": [[EmbeddedIntObject alloc] init]}]; + XCTAssertNoThrow([[DictionaryPropertyObject alloc] initWithValue:passVal]); +} + #pragma mark - Create - (void)testCreateWithArray { diff --git a/RealmSwift/Tests/ObjectCreationTests.swift b/RealmSwift/Tests/ObjectCreationTests.swift index 29b6e0bca3..3440efc66e 100644 --- a/RealmSwift/Tests/ObjectCreationTests.swift +++ b/RealmSwift/Tests/ObjectCreationTests.swift @@ -906,6 +906,7 @@ class ObjectCreationTests: TestCase { ]) // Do not copy unmanaged object let copyD = EmbeddedParentObject(value: parentUnmanaged) + XCTAssertTrue(copyD.object === parentUnmanaged.object) realm.add(copyD) assertThrows(realm.add(parentUnmanaged), "Cannot set a link to an existing managed embedded object") @@ -937,6 +938,14 @@ class ObjectCreationTests: TestCase { realmB.cancelWrite() } + func testInitEmbeddedProperty() { + let failVal: [Any] = [[], ["one": SwiftIntObject()]] + assertThrows(SwiftDictionaryObject(value: failVal)) + + let passVal: [Any] = [[], ["one": EmbeddedSwiftIntObject()]] + XCTAssertNoThrow(SwiftDictionaryObject(value: passVal)) + } + // test null object // test null list diff --git a/RealmSwift/Tests/SwiftTestObjects.swift b/RealmSwift/Tests/SwiftTestObjects.swift index a98d1fff4f..de7e192f6a 100644 --- a/RealmSwift/Tests/SwiftTestObjects.swift +++ b/RealmSwift/Tests/SwiftTestObjects.swift @@ -852,3 +852,12 @@ class EmbeddedTreeObject3: EmbeddedObject, EmbeddedTreeObject { let parent3 = LinkingObjects(fromType: EmbeddedTreeObject2.self, property: "child") let parent4 = LinkingObjects(fromType: EmbeddedTreeObject2.self, property: "children") } + +class EmbeddedSwiftIntObject: EmbeddedObject { + @objc dynamic var intCol = 0 +} + +class SwiftDictionaryObject: Object { + let intDict = Map() + let embedIntDict = Map() +}