Skip to content

Commit c46340e

Browse files
committed
[ObjC] Support errors when merging unknown fields to a message.
PiperOrigin-RevId: 658782615
1 parent c5c9c89 commit c46340e

File tree

7 files changed

+71
-27
lines changed

7 files changed

+71
-27
lines changed

objectivec/GPBMessage.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,25 @@ CF_EXTERN_C_END
507507
* Merges in the data from an `GPBUnknownFields`, meaning the data from the unknown fields gets
508508
* re-parsed so any known fields will be propertly set.
509509
*
510-
* If the intent is to replace the message's unknown fields, call `-clearUnknownFields` first.
510+
* If the intent is to *replace* the message's unknown fields, call `-clearUnknownFields` first.
511+
*
512+
* Since the data from the GPBUnknownFields will always be well formed, this call will almost never
513+
* fail. What could cause it to fail is if the GPBUnknownFields contains a field values it is
514+
* and error for the message's schema - i.e.: if it contains a length delimited field where the
515+
* field number for the message is defined to be a _string_ field, however the length delimited
516+
* data provide is not a valid UTF8 string.
511517
*
512518
* @param unknownFields The unknown fields to merge the data from.
513519
* @param extensionRegistry The extension registry to use to look up extensions, can be `nil`.
520+
* @param errorPtr An optional error pointer to fill in with a failure
521+
* reason if the data can not be parsed. Will only be
522+
* filled in if the data failed to be parsed.
523+
*
524+
* @return Boolean indicating success. errorPtr will only be fill in on failure.
514525
**/
515-
- (void)mergeUnknownFields:(GPBUnknownFields *)unknownFields
516-
extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry;
526+
- (BOOL)mergeUnknownFields:(GPBUnknownFields *)unknownFields
527+
extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry
528+
error:(NSError **)errorPtr;
517529

518530
@end
519531

objectivec/GPBMessage.m

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,14 +1484,12 @@ - (void)clearUnknownFields {
14841484
self.unknownFields = nil;
14851485
}
14861486

1487-
- (void)mergeUnknownFields:(GPBUnknownFields *)unknownFields
1488-
extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry {
1489-
NSData *data = [unknownFields serializeAsData];
1490-
if (![self mergeFromData:data extensionRegistry:extensionRegistry error:NULL]) {
1491-
#if defined(DEBUG) && DEBUG
1492-
NSAssert(0, @"Internal error within the library, failed to parse data from unknown fields.");
1493-
#endif
1494-
};
1487+
- (BOOL)mergeUnknownFields:(GPBUnknownFields *)unknownFields
1488+
extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry
1489+
error:(NSError **)errorPtr {
1490+
return [self mergeFromData:[unknownFields serializeAsData]
1491+
extensionRegistry:extensionRegistry
1492+
error:errorPtr];
14951493
}
14961494

14971495
- (BOOL)isInitialized {

objectivec/GPBUnknownFields.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ __attribute__((objc_subclassing_restricted))
3333
*
3434
* Note: The instance is not linked to the message, any change will not be
3535
* reflected on the message the changes have to be pushed back to the message
36-
* with `-[GPBMessage mergeUnknownFields:error:]`.
36+
* with `-[GPBMessage mergeUnknownFields:extensionRegistry:error:]`.
3737
**/
3838
- (instancetype)initFromMessage:(nonnull GPBMessage *)message;
3939

objectivec/Tests/GPBMessageTests.m

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ - (void)testDescription {
506506
GPBUnknownFields *ufs = [[[GPBUnknownFields alloc] init] autorelease];
507507
[ufs addFieldNumber:1234 fixed32:1234];
508508
[ufs addFieldNumber:2345 varint:54321];
509-
[message mergeUnknownFields:ufs extensionRegistry:nil];
509+
XCTAssertTrue([message mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
510510

511511
NSString *description = [message description];
512512
XCTAssertGreaterThan([description length], 0U);
@@ -997,13 +997,17 @@ - (void)testAutocreatedUnknownFields {
997997
XCTAssertFalse([message hasOptionalNestedMessage]);
998998
GPBUnknownFields *ufs = [[[GPBUnknownFields alloc] init] autorelease];
999999
[ufs addFieldNumber:1 varint:1];
1000-
[message.optionalNestedMessage mergeUnknownFields:ufs extensionRegistry:nil];
1000+
XCTAssertTrue([message.optionalNestedMessage mergeUnknownFields:ufs
1001+
extensionRegistry:nil
1002+
error:NULL]);
10011003
XCTAssertTrue([message hasOptionalNestedMessage]);
10021004

10031005
message.optionalNestedMessage = nil;
10041006
XCTAssertFalse([message hasOptionalNestedMessage]);
10051007
[ufs clear]; // Also make sure merging zero length forces it to become visible.
1006-
[message.optionalNestedMessage mergeUnknownFields:ufs extensionRegistry:nil];
1008+
XCTAssertTrue([message.optionalNestedMessage mergeUnknownFields:ufs
1009+
extensionRegistry:nil
1010+
error:NULL]);
10071011
XCTAssertTrue([message hasOptionalNestedMessage]);
10081012
}
10091013

@@ -1887,7 +1891,7 @@ - (void)testGenerateAndParseUnknownMessage {
18871891
[message setUnknownFields:unknowns];
18881892
GPBUnknownFields *ufs = [[[GPBUnknownFields alloc] init] autorelease];
18891893
[ufs addFieldNumber:1234 varint:5678];
1890-
[message mergeUnknownFields:ufs extensionRegistry:nil];
1894+
XCTAssertTrue([message mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
18911895
NSData *data = [message data];
18921896
GPBMessage *message2 = [GPBMessage parseFromData:data extensionRegistry:nil error:NULL];
18931897
XCTAssertEqualObjects(message, message2);
@@ -1900,7 +1904,7 @@ - (void)testDelimitedWriteAndParseMultipleMessages {
19001904
[message1 setUnknownFields:unknowns1];
19011905
GPBUnknownFields *ufs1 = [[[GPBUnknownFields alloc] init] autorelease];
19021906
[ufs1 addFieldNumber:1234 varint:5678];
1903-
[message1 mergeUnknownFields:ufs1 extensionRegistry:nil];
1907+
XCTAssertTrue([message1 mergeUnknownFields:ufs1 extensionRegistry:nil error:NULL]);
19041908

19051909
GPBUnknownFieldSet *unknowns2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
19061910
[unknowns2 mergeVarintField:789 value:987];
@@ -1910,7 +1914,7 @@ - (void)testDelimitedWriteAndParseMultipleMessages {
19101914
GPBUnknownFields *ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
19111915
[ufs2 addFieldNumber:2345 fixed32:6789];
19121916
[ufs2 addFieldNumber:3456 fixed32:7890];
1913-
[message2 mergeUnknownFields:ufs2 extensionRegistry:nil];
1917+
XCTAssertTrue([message2 mergeUnknownFields:ufs2 extensionRegistry:nil error:NULL]);
19141918

19151919
NSMutableData *delimitedData = [NSMutableData data];
19161920
[delimitedData appendData:[message1 delimitedData]];

objectivec/Tests/GPBUnknownFieldsTest.m

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ - (void)testMessageMergeUnknowns {
811811
[group addFieldNumber:123456 varint:5432];
812812

813813
TestAllTypes* msg = [TestAllTypes message];
814-
[msg mergeUnknownFields:ufs extensionRegistry:nil];
814+
XCTAssertTrue([msg mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
815815
XCTAssertEqual(msg.optionalInt64, 100);
816816
XCTAssertEqual(msg.optionalFixed32, 200);
817817
XCTAssertEqual(msg.optionalFixed64, 300);
@@ -829,7 +829,7 @@ - (void)testMessageMergeUnknowns {
829829
XCTAssertEqual(varint, 5432);
830830

831831
TestEmptyMessage* emptyMessage = [TestEmptyMessage message];
832-
[emptyMessage mergeUnknownFields:ufs extensionRegistry:nil];
832+
XCTAssertTrue([emptyMessage mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
833833
GPBUnknownFields* ufs3 = [[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];
834834
XCTAssertEqualObjects(ufs3, ufs); // Round trip through an empty message got us same fields back.
835835
XCTAssertTrue(ufs3 != ufs); // But they are different objects.
@@ -843,7 +843,7 @@ - (void)testRoundTripLotsOfFields {
843843
TestEmptyMessage* emptyMessage = [TestEmptyMessage parseFromData:allFieldsData error:NULL];
844844
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];
845845
TestAllTypes* allFields2 = [TestAllTypes message];
846-
[allFields2 mergeUnknownFields:ufs extensionRegistry:nil];
846+
XCTAssertTrue([allFields2 mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
847847
XCTAssertEqualObjects(allFields2, allFields);
848848

849849
// Confirm that the they still all end up in unknowns when parsed into a message with extensions
@@ -891,7 +891,7 @@ - (void)testMismatchedFieldTypes {
891891
// unknown fields again.
892892
{
893893
TestAllTypes* msg = [TestAllTypes message];
894-
[msg mergeUnknownFields:ufsWrongTypes extensionRegistry:nil];
894+
XCTAssertTrue([msg mergeUnknownFields:ufsWrongTypes extensionRegistry:nil error:NULL]);
895895
GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msg] autorelease];
896896
XCTAssertFalse(ufs2.empty);
897897
XCTAssertEqualObjects(ufs2, ufsWrongTypes); // All back as unknown fields.
@@ -901,19 +901,46 @@ - (void)testMismatchedFieldTypes {
901901
// into unknown fields.
902902
{
903903
TestAllExtensions* msg = [TestAllExtensions message];
904-
[msg mergeUnknownFields:ufsWrongTypes extensionRegistry:[UnittestRoot extensionRegistry]];
904+
XCTAssertTrue([msg mergeUnknownFields:ufsWrongTypes
905+
extensionRegistry:[UnittestRoot extensionRegistry]
906+
error:NULL]);
905907
GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msg] autorelease];
906908
XCTAssertFalse(ufs2.empty);
907909
XCTAssertEqualObjects(ufs2, ufsWrongTypes); // All back as unknown fields.
908910
}
909911
}
910912

913+
- (void)testMergeFailures {
914+
// Valid data, pushes to the string just fine.
915+
{
916+
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
917+
[ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalString
918+
lengthDelimited:DataFromCStr("abc")];
919+
TestAllTypes* msg = [TestAllTypes message];
920+
NSError* error = nil;
921+
XCTAssertTrue([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
922+
XCTAssertNil(error);
923+
XCTAssertEqualObjects(msg.optionalString, @"abc");
924+
}
925+
926+
// Invalid UTF-8 causes a failure when pushed to the message.
927+
{
928+
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
929+
[ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalString
930+
lengthDelimited:DataFromBytes(0xC2, 0xF2, 0x0, 0x0, 0x0)];
931+
TestAllTypes* msg = [TestAllTypes message];
932+
NSError* error = nil;
933+
XCTAssertFalse([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
934+
XCTAssertNotNil(error);
935+
}
936+
}
937+
911938
- (void)testLargeVarint {
912939
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
913940
[ufs addFieldNumber:1 varint:0x7FFFFFFFFFFFFFFFL];
914941

915942
TestEmptyMessage* emptyMessage = [TestEmptyMessage message];
916-
[emptyMessage mergeUnknownFields:ufs extensionRegistry:nil];
943+
XCTAssertTrue([emptyMessage mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
917944

918945
GPBUnknownFields* ufsParsed =
919946
[[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];

objectivec/Tests/GPBUtilitiesTests.m

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ - (void)testTextFormatUnknownFields {
188188
[group addFieldNumber:3 fixed32:0x3];
189189
[group addFieldNumber:2 fixed64:0x2];
190190
TestEmptyMessage *message = [TestEmptyMessage message];
191-
[message mergeUnknownFields:ufs extensionRegistry:nil];
191+
XCTAssertTrue([message mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
192192

193193
NSString *expected = @"# --- Unknown fields ---\n"
194194
@"10: 1\n"
@@ -255,7 +255,8 @@ - (void)testSetRepeatedFields {
255255
static void AddUnknownFields(GPBMessage *message, int num) {
256256
GPBUnknownFields *ufs = [[GPBUnknownFields alloc] init];
257257
[ufs addFieldNumber:num varint:num];
258-
[message mergeUnknownFields:ufs extensionRegistry:nil];
258+
// Can't fail since it is a varint.
259+
[message mergeUnknownFields:ufs extensionRegistry:nil error:NULL];
259260
[ufs release];
260261
}
261262

objectivec/Tests/GPBWireFormatTests.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ - (void)testSerializeMessageSet {
131131
GPBUnknownFields* group = [ufs addGroupWithFieldNumber:GPBWireFormatMessageSetItem];
132132
[group addFieldNumber:GPBWireFormatMessageSetTypeId varint:kUnknownTypeId2];
133133
[group addFieldNumber:GPBWireFormatMessageSetMessage lengthDelimited:DataFromCStr("baz")];
134-
[message_set mergeUnknownFields:ufs extensionRegistry:[MSetUnittestMsetRoot extensionRegistry]];
134+
XCTAssertTrue([message_set mergeUnknownFields:ufs
135+
extensionRegistry:[MSetUnittestMsetRoot extensionRegistry]
136+
error:NULL]);
135137

136138
NSData* data = [message_set data];
137139

0 commit comments

Comments
 (0)