[Darwin] MTRAttributePath NSSecureCoding fix (#32862)
diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm
index 914917a..cb93d2d 100644
--- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm
+++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm
@@ -2597,6 +2597,7 @@
- (void)encodeWithCoder:(NSCoder *)coder
{
+ [super encodeWithCoder:coder];
[coder encodeObject:_attribute forKey:sAttributeKey];
}
@@ -2663,6 +2664,35 @@
return ConcreteEventPath([self.endpoint unsignedShortValue], static_cast<ClusterId>([self.cluster unsignedLongValue]),
static_cast<EventId>([self.event unsignedLongValue]));
}
+
+static NSString * const sEventKey = @"eventKey";
+
++ (BOOL)supportsSecureCoding
+{
+ return YES;
+}
+
+- (nullable instancetype)initWithCoder:(NSCoder *)decoder
+{
+ self = [super initWithCoder:decoder];
+ if (self == nil) {
+ return nil;
+ }
+
+ _event = [decoder decodeObjectOfClass:[NSNumber class] forKey:sEventKey];
+ if (_event && ![_event isKindOfClass:[NSNumber class]]) {
+ MTR_LOG_ERROR("MTREventPath decoded %@ for event, not NSNumber.", _event);
+ return nil;
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder
+{
+ [super encodeWithCoder:coder];
+ [coder encodeObject:_event forKey:sEventKey];
+}
@end
@implementation MTREventPath (Deprecated)
@@ -2718,6 +2748,35 @@
{
return [MTRCommandPath commandPathWithEndpointID:self.endpoint clusterID:self.cluster commandID:_command];
}
+
+static NSString * const sCommandKey = @"commandKey";
+
++ (BOOL)supportsSecureCoding
+{
+ return YES;
+}
+
+- (nullable instancetype)initWithCoder:(NSCoder *)decoder
+{
+ self = [super initWithCoder:decoder];
+ if (self == nil) {
+ return nil;
+ }
+
+ _command = [decoder decodeObjectOfClass:[NSNumber class] forKey:sCommandKey];
+ if (_command && ![_command isKindOfClass:[NSNumber class]]) {
+ MTR_LOG_ERROR("MTRCommandPath decoded %@ for command, not NSNumber.", _command);
+ return nil;
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder
+{
+ [super encodeWithCoder:coder];
+ [coder encodeObject:_command forKey:sCommandKey];
+}
@end
@implementation MTRCommandPath (Deprecated)
diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
index 1d71c7b..34d3928 100644
--- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
+++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m
@@ -2914,6 +2914,50 @@
}
#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED
+- (void)test032_MTRPathClassesEncoding
+{
+ NSError * encodeError;
+ NSData * encodedData;
+ NSError * decodeError;
+ id decodedValue;
+
+ // Test attribute path encode / decode
+ MTRAttributePath * originalAttributePath = [MTRAttributePath attributePathWithEndpointID:@(101) clusterID:@(102) attributeID:@(103)];
+ encodedData = [NSKeyedArchiver archivedDataWithRootObject:originalAttributePath requiringSecureCoding:YES error:&encodeError];
+ XCTAssertNil(encodeError);
+
+ decodedValue = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithObject:[MTRAttributePath class]] fromData:encodedData error:&decodeError];
+ XCTAssertNil(decodeError);
+ XCTAssertTrue([decodedValue isKindOfClass:[MTRAttributePath class]]);
+
+ MTRAttributePath * decodedAttributePath = decodedValue;
+ XCTAssertEqualObjects(originalAttributePath, decodedAttributePath);
+
+ // Test event path encode / decode
+ MTREventPath * originalEventPath = [MTREventPath eventPathWithEndpointID:@(201) clusterID:@(202) eventID:@(203)];
+ encodedData = [NSKeyedArchiver archivedDataWithRootObject:originalEventPath requiringSecureCoding:YES error:&encodeError];
+ XCTAssertNil(encodeError);
+
+ decodedValue = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithObject:[MTREventPath class]] fromData:encodedData error:&decodeError];
+ XCTAssertNil(decodeError);
+ XCTAssertTrue([decodedValue isKindOfClass:[MTREventPath class]]);
+
+ MTREventPath * decodedEventPath = decodedValue;
+ XCTAssertEqualObjects(originalEventPath, decodedEventPath);
+
+ // Test command path encode / decode
+ MTRCommandPath * originalCommandPath = [MTRCommandPath commandPathWithEndpointID:@(301) clusterID:@(302) commandID:@(303)];
+ encodedData = [NSKeyedArchiver archivedDataWithRootObject:originalCommandPath requiringSecureCoding:YES error:&encodeError];
+ XCTAssertNil(encodeError);
+
+ decodedValue = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithObject:[MTRCommandPath class]] fromData:encodedData error:&decodeError];
+ XCTAssertNil(decodeError);
+ XCTAssertTrue([decodedValue isKindOfClass:[MTRCommandPath class]]);
+
+ MTRCommandPath * decodedCommandPath = decodedValue;
+ XCTAssertEqualObjects(originalCommandPath, decodedCommandPath);
+}
+
@end
@interface MTRDeviceEncoderTests : XCTestCase