Skip to content

Commit 029bc93

Browse files
Address review comments around NSNumber
1 parent a3466cc commit 029bc93

File tree

4 files changed

+67
-51
lines changed

4 files changed

+67
-51
lines changed

src/darwin/Framework/CHIP/MTRSetupPayload.h

+19-12
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,26 @@ typedef NS_ENUM(NSUInteger, MTROptionalQRCodeInfoType) {
6161
MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
6262
@interface MTROptionalQRCodeInfo : NSObject /* <NSCopying> (see below) */
6363

64-
- (instancetype)initWithTag:(uint8_t)tag stringValue:(NSString *)value MTR_NEWLY_AVAILABLE;
65-
- (instancetype)initWithTag:(uint8_t)tag int32Value:(int32_t)value MTR_NEWLY_AVAILABLE;
64+
/**
65+
* Initializes the object with a tag and string value.
66+
* The tag must be in the range 0x80 - 0xFF.
67+
*/
68+
- (instancetype)initWithTag:(NSNumber *)tag stringValue:(NSString *)value MTR_NEWLY_AVAILABLE;
69+
70+
/**
71+
* Initializes the object with a tag and int32 value.
72+
* The tag must be in the range 0x80 - 0xFF.
73+
*/
74+
- (instancetype)initWithTag:(NSNumber *)tag int32Value:(int32_t)value MTR_NEWLY_AVAILABLE;
6675

6776
@property (nonatomic, readonly, assign) MTROptionalQRCodeInfoType type MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4));
6877

6978
/**
70-
* The TLV tag number for this information item.
79+
* The vendor-specific TLV tag number for this information item.
7180
*
72-
* Tags in the range 0x00 - 0x7F are reserved for Matter-defined elements.
73-
* Vendor-specific elements must have tags in the range 0x80 - 0xFF.
81+
* Vendor-specific elements have tags in the range 0x80 - 0xFF.
7482
*/
75-
@property (nonatomic, readonly, assign) uint8_t tagNumber MTR_NEWLY_AVAILABLE;
83+
@property (nonatomic, readonly, copy) NSNumber * tag;
7684

7785
/**
7886
* The value held in this extension element,
@@ -160,18 +168,19 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
160168
@property (nonatomic, readonly, copy) NSArray<MTROptionalQRCodeInfo *> * vendorElements MTR_NEWLY_AVAILABLE;
161169

162170
/**
163-
Returns the Manufacturer-specific extension element with the specified tag, if any.
171+
* Returns the Manufacturer-specific extension element with the specified tag, if any.
172+
* The tag must be in the range 0x80 - 0xFF.
164173
*/
165-
- (nullable MTROptionalQRCodeInfo *)vendorElementWithTag:(uint8_t)tag MTR_NEWLY_AVAILABLE;
174+
- (nullable MTROptionalQRCodeInfo *)vendorElementWithTag:(NSNumber *)tag MTR_NEWLY_AVAILABLE;
166175

167176
/**
168177
* Removes the extension element with the specified tag, if any.
178+
* The tag must be in the range 0x80 - 0xFF.
169179
*/
170-
- (void)removeVendorElementWithTag:(uint8_t)tag MTR_NEWLY_AVAILABLE;
180+
- (void)removeVendorElementWithTag:(NSNumber *)tag MTR_NEWLY_AVAILABLE;
171181

172182
/**
173183
* Adds or replaces a Manufacturer-specific extension element.
174-
* The element must have a tag in the vendor-specific range (0x80 - 0xFF).
175184
*/
176185
- (void)addOrReplaceVendorElement:(MTROptionalQRCodeInfo *)element MTR_NEWLY_AVAILABLE;
177186

@@ -230,8 +239,6 @@ MTR_NEWLY_AVAILABLE
230239
@property (nonatomic, copy) NSNumber * infoType
231240
MTR_DEPRECATED("Please use type", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4));
232241

233-
@property (nonatomic, copy) NSNumber * tag MTR_NEWLY_DEPRECATED("Please use tagNumber");
234-
235242
- (void)setType:(MTROptionalQRCodeInfoType)type MTR_NEWLY_DEPRECATED("MTROptionalQRCodeInfo is immutable");
236243
- (void)setTag:(NSNumber *)tag MTR_NEWLY_DEPRECATED("MTROptionalQRCodeInfo is immutable");
237244
- (void)setIntegerValue:(NSNumber *)integerValue MTR_NEWLY_DEPRECATED("MTROptionalQRCodeInfo is immutable");

src/darwin/Framework/CHIP/MTRSetupPayload.mm

+25-19
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#import "MTRLogging_Internal.h"
2323
#import "MTRUtilities.h"
2424

25+
#include <lib/support/SafeInt.h>
2526
#include <setup_payload/ManualSetupPayloadGenerator.h>
2627
#include <setup_payload/ManualSetupPayloadParser.h>
2728
#include <setup_payload/QRCodeSetupPayloadGenerator.h>
@@ -34,20 +35,29 @@ @implementation MTROptionalQRCodeInfo {
3435
chip::OptionalQRCodeInfo _info;
3536
}
3637

37-
- (instancetype)initWithTag:(uint8_t)tag int32Value:(int32_t)value
38+
static uint8_t ValidateVendorTag(NSNumber * tag)
39+
{
40+
auto integerValue = tag.integerValue;
41+
auto tagValue = static_cast<uint8_t>(integerValue);
42+
MTRVerifyArgumentOrDie(tag != nil && chip::CanCastTo<uint8_t>(integerValue) && chip::SetupPayload::IsVendorTag(tagValue), @"tag must be a vendor tag (0x80 - 0xFF)");
43+
return tagValue;
44+
}
45+
46+
- (instancetype)initWithTag:(NSNumber *)tag int32Value:(int32_t)value
3847
{
3948
self = [super init];
4049
_info.type = chip::optionalQRCodeInfoTypeInt32;
41-
_info.tag = tag;
50+
_info.tag = ValidateVendorTag(tag);
4251
_info.int32 = value;
4352
return self;
4453
}
4554

46-
- (instancetype)initWithTag:(uint8_t)tag stringValue:(NSString *)value
55+
- (instancetype)initWithTag:(NSNumber *)tag stringValue:(NSString *)value
4756
{
4857
self = [super init];
4958
_info.type = chip::optionalQRCodeInfoTypeString;
50-
_info.tag = tag;
59+
_info.tag = ValidateVendorTag(tag);
60+
MTRVerifyArgumentOrDie(value != nil, @"value");
5161
_info.data = value.UTF8String;
5262
return self;
5363
}
@@ -56,7 +66,8 @@ - (nullable instancetype)initWithQRCodeInfo:(chip::OptionalQRCodeInfo const &)in
5666
{
5767
self = [super init];
5868
_info = info;
59-
// Don't expose objects with an invalid type.
69+
// Don't expose objects with an out-of-range tag or invalid type
70+
VerifyOrReturnValue(chip::SetupPayload::IsVendorTag(_info.tag), nil);
6071
VerifyOrReturnValue(self.type != MTROptionalQRCodeInfoTypeUnknown, nil);
6172
return self;
6273
}
@@ -97,9 +108,9 @@ - (MTROptionalQRCodeInfoType)type
97108
return MTROptionalQRCodeInfoTypeUnknown;
98109
}
99110

100-
- (uint8_t)tagNumber
111+
- (NSNumber *)tag
101112
{
102-
return _info.tag;
113+
return @(_info.tag);
103114
}
104115

105116
- (NSNumber *)integerValue
@@ -142,7 +153,7 @@ - (BOOL)isEqual:(id)object
142153

143154
- (NSString *)description
144155
{
145-
return [NSString stringWithFormat:@"0x%02x=%@", self.tagNumber, self.integerValue ?: self.stringValue];
156+
return [NSString stringWithFormat:@"0x%02x=%@", self.tag.unsignedCharValue, self.integerValue ?: self.stringValue];
146157
}
147158

148159
@end
@@ -431,21 +442,21 @@ - (void)setSerialNumber:(nullable NSString *)serialNumber
431442
return infos;
432443
}
433444

434-
- (MTROptionalQRCodeInfo *)vendorElementWithTag:(uint8_t)tag
445+
- (MTROptionalQRCodeInfo *)vendorElementWithTag:(NSNumber *)tag
435446
{
436447
chip::OptionalQRCodeInfo element;
437-
VerifyOrReturnValue(_payload.getOptionalVendorData(tag, element) == CHIP_NO_ERROR, nil);
448+
VerifyOrReturnValue(_payload.getOptionalVendorData(ValidateVendorTag(tag), element) == CHIP_NO_ERROR, nil);
438449
return [[MTROptionalQRCodeInfo alloc] initWithQRCodeInfo:element];
439450
}
440451

441-
- (void)removeVendorElementWithTag:(uint8_t)tag
452+
- (void)removeVendorElementWithTag:(NSNumber *)tag
442453
{
443-
_payload.removeOptionalVendorData(tag);
454+
_payload.removeOptionalVendorData(ValidateVendorTag(tag));
444455
}
445456

446457
- (void)addOrReplaceVendorElement:(MTROptionalQRCodeInfo *)element
447458
{
448-
MTRVerifyArgumentOrDie(chip::SetupPayload::IsVendorTag(element.tagNumber), @"element.tagNumber");
459+
MTRVerifyArgumentOrDie(element != nil, @"element");
449460
CHIP_ERROR err = [element addAsVendorElementTo:_payload];
450461
VerifyOrDieWithMsg(err == CHIP_NO_ERROR, NotSpecified, "Internal error: %" CHIP_ERROR_FORMAT, err.Format());
451462
}
@@ -615,19 +626,14 @@ @implementation MTROptionalQRCodeInfo (Deprecated)
615626

616627
- (instancetype)init
617628
{
618-
return [self initWithTag:0xff stringValue:@""];
629+
return [self initWithTag:@0xff stringValue:@""];
619630
}
620631

621632
- (void)setType:(MTROptionalQRCodeInfoType)type
622633
{
623634
/* ignored */
624635
}
625636

626-
- (NSNumber *)tag
627-
{
628-
return @(self.tagNumber);
629-
}
630-
631637
- (void)setTag:(NSNumber *)tag
632638
{
633639
/* ignored */

src/darwin/Framework/CHIP/MTRSetupPayload_Internal.h

-5
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,11 @@
1919

2020
#import "MTRDefines_Internal.h"
2121

22-
#ifdef __cplusplus
23-
#import <lib/core/Optional.h>
2422
#import <setup_payload/SetupPayload.h>
25-
#endif
2623

2724
MTR_DIRECT_MEMBERS
2825
@interface MTRSetupPayload ()
2926

30-
#ifdef __cplusplus
3127
- (instancetype)initWithSetupPayload:(chip::SetupPayload)setupPayload;
32-
#endif
3328

3429
@end

src/darwin/Framework/CHIPTests/MTRSetupPayloadTests.m

+23-15
Original file line numberDiff line numberDiff line change
@@ -212,49 +212,49 @@ - (void)testQRCodeParserWithOptionalData
212212
}
213213

214214
// Test access by tag
215-
XCTAssertEqualObjects([payload vendorElementWithTag:130].stringValue, @"myData");
216-
XCTAssertEqualObjects([payload vendorElementWithTag:131].integerValue, @12);
215+
XCTAssertEqualObjects([payload vendorElementWithTag:@130].stringValue, @"myData");
216+
XCTAssertEqualObjects([payload vendorElementWithTag:@131].integerValue, @12);
217217
}
218218

219219
- (void)testAddVendorElement
220220
{
221221
MTRSetupPayload * payload = [[MTRSetupPayload alloc] initWithSetupPasscode:@314159 discriminator:@555];
222222
XCTAssertEqual(payload.vendorElements.count, 0);
223-
[payload addOrReplaceVendorElement:[[MTROptionalQRCodeInfo alloc] initWithTag:0xff int32Value:42]];
223+
[payload addOrReplaceVendorElement:[[MTROptionalQRCodeInfo alloc] initWithTag:@0xff int32Value:42]];
224224
XCTAssertEqual(payload.vendorElements.count, 1);
225225
XCTAssertEqualObjects(payload.vendorElements.firstObject.integerValue, @42);
226-
XCTAssertEqualObjects([payload vendorElementWithTag:0xff].integerValue, @42);
226+
XCTAssertEqualObjects([payload vendorElementWithTag:@0xff].integerValue, @42);
227227
}
228228

229229
- (void)testVendorElementsEncodedToQRCode
230230
{
231231
MTRSetupPayload * payload = [[MTRSetupPayload alloc] initWithSetupPasscode:@314159 discriminator:@555];
232-
[payload addOrReplaceVendorElement:[[MTROptionalQRCodeInfo alloc] initWithTag:0x80 stringValue:@"Hello"]];
232+
[payload addOrReplaceVendorElement:[[MTROptionalQRCodeInfo alloc] initWithTag:@0x80 stringValue:@"Hello"]];
233233
MTRSetupPayload * decoded = [[MTRSetupPayload alloc] initWithPayload:payload.qrCodeString];
234234
XCTAssertNotNil(decoded);
235-
XCTAssertEqualObjects([decoded vendorElementWithTag:0x80].stringValue, @"Hello");
235+
XCTAssertEqualObjects([decoded vendorElementWithTag:@0x80].stringValue, @"Hello");
236236
}
237237

238238
- (void)testRemoveVendorElements
239239
{
240240
MTRSetupPayload * payload = [[MTRSetupPayload alloc] initWithPayload:@"MT:M5L90MP500K64J0A33P0SET70.QT52B.E23-WZE0WISA0DK5N1K8SQ1RYCU1O0"];
241241
XCTAssertNotNil(payload);
242242
XCTAssertEqual(payload.vendorElements.count, 2);
243-
[payload removeVendorElementWithTag:0]; // no change, no vendor element present with this tag
243+
[payload removeVendorElementWithTag:@128]; // no change, no vendor element present with this tag
244244
XCTAssertEqual(payload.vendorElements.count, 2);
245-
[payload removeVendorElementWithTag:130];
245+
[payload removeVendorElementWithTag:@130];
246246
XCTAssertEqual(payload.vendorElements.count, 1);
247-
[payload removeVendorElementWithTag:131];
247+
[payload removeVendorElementWithTag:@131];
248248
XCTAssertEqual(payload.vendorElements.count, 0);
249249
}
250250

251251
- (void)testQrCodeInfoCopyAndEquality
252252
{
253-
MTROptionalQRCodeInfo * a = [[MTROptionalQRCodeInfo alloc] initWithTag:1 stringValue:@"hello"];
254-
MTROptionalQRCodeInfo * b = [[MTROptionalQRCodeInfo alloc] initWithTag:1 stringValue:@"hello"];
255-
MTROptionalQRCodeInfo * c = [[MTROptionalQRCodeInfo alloc] initWithTag:0xff stringValue:@"hello"];
256-
MTROptionalQRCodeInfo * d = [[MTROptionalQRCodeInfo alloc] initWithTag:1 int32Value:42];
257-
MTROptionalQRCodeInfo * e = [[MTROptionalQRCodeInfo alloc] initWithTag:1 int32Value:0xbad];
253+
MTROptionalQRCodeInfo * a = [[MTROptionalQRCodeInfo alloc] initWithTag:@0x88 stringValue:@"hello"];
254+
MTROptionalQRCodeInfo * b = [[MTROptionalQRCodeInfo alloc] initWithTag:@0x88 stringValue:@"hello"];
255+
MTROptionalQRCodeInfo * c = [[MTROptionalQRCodeInfo alloc] initWithTag:@0xff stringValue:@"hello"];
256+
MTROptionalQRCodeInfo * d = [[MTROptionalQRCodeInfo alloc] initWithTag:@0x88 int32Value:42];
257+
MTROptionalQRCodeInfo * e = [[MTROptionalQRCodeInfo alloc] initWithTag:@0x88 int32Value:0xbad];
258258
XCTAssertTrue([a isEqual:a]);
259259
XCTAssertTrue([a isEqual:[a copy]]);
260260
XCTAssertTrue([a isEqual:b]);
@@ -458,7 +458,7 @@ - (void)testCopyingAndEquality
458458
XCTAssertTrue([copy isEqual:payload]);
459459
XCTAssertEqual(payload.hash, copy.hash);
460460

461-
MTROptionalQRCodeInfo * element = [[MTROptionalQRCodeInfo alloc] initWithTag:0x80 stringValue:@"To infinity and beyond!"];
461+
MTROptionalQRCodeInfo * element = [[MTROptionalQRCodeInfo alloc] initWithTag:@0x80 stringValue:@"To infinity and beyond!"];
462462
[copy addOrReplaceVendorElement:element];
463463
XCTAssertFalse([copy isEqual:payload]);
464464
[payload addOrReplaceVendorElement:element];
@@ -479,4 +479,12 @@ - (void)testCanParseFutureDiscoveryMethod
479479
XCTAssertEqual([[MTRSetupPayload alloc] initWithPayload:@"MT:-24J0Q.C.0KA0648G00"].discoveryCapabilities, 0xfa);
480480
}
481481

482+
- (void)testDescriptionShowsUnknownDiscoveryMethods
483+
{
484+
MTRSetupPayload * a = [[MTRSetupPayload alloc] initWithSetupPasscode:@888 discriminator:@555];
485+
MTRSetupPayload * b = [a copy];
486+
b.discoveryCapabilities |= 0x80;
487+
XCTAssertNotEqualObjects(a.description, b.description);
488+
}
489+
482490
@end

0 commit comments

Comments
 (0)