Skip to content

Commit

Permalink
[Darwin] MTRAttributePath NSSecureCoding fix
Browse files Browse the repository at this point in the history
  • Loading branch information
jtung-apple committed Apr 4, 2024
1 parent cd0e262 commit 9b7ada6
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/darwin/Framework/CHIP/MTRBaseDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2597,6 +2597,7 @@ - (nullable instancetype)initWithCoder:(NSCoder *)decoder

- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder encodeObject:_attribute forKey:sAttributeKey];
}

Expand Down Expand Up @@ -2663,6 +2664,35 @@ - (ConcreteEventPath)_asConcretePath
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)
Expand Down Expand Up @@ -2718,6 +2748,35 @@ - (id)copyWithZone:(NSZone *)zone
{
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)
Expand Down
44 changes: 44 additions & 0 deletions src/darwin/Framework/CHIPTests/MTRDeviceTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -2914,6 +2914,50 @@ - (void)test031_MTRDeviceAttributeCacheLocalTestStorage
}
#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
Expand Down

0 comments on commit 9b7ada6

Please sign in to comment.