diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m index b29540a30f..0bdf4bb8a7 100644 --- a/objectivec/GPBMessage.m +++ b/objectivec/GPBMessage.m @@ -1996,9 +1996,12 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { - (void)mergeFromData:(NSData *)data extensionRegistry:(id)extensionRegistry { GPBCodedInputStream *input = [[GPBCodedInputStream alloc] initWithData:data]; - [self mergeFromCodedInputStream:input extensionRegistry:extensionRegistry]; - [input checkLastTagWas:0]; - [input release]; + @try { + [self mergeFromCodedInputStream:input extensionRegistry:extensionRegistry]; + [input checkLastTagWas:0]; + } @finally { + [input release]; + } } #pragma mark - Parse From Data Support @@ -2204,8 +2207,8 @@ static void MergeSingleFieldFromCodedInputStream(GPBMessage *self, GPBFieldDescr [input readMessage:message extensionRegistry:extensionRegistry]; } else { GPBMessage *message = [[field.msgClass alloc] init]; - [input readMessage:message extensionRegistry:extensionRegistry]; GPBSetRetainedObjectIvarWithFieldPrivate(self, field, message); + [input readMessage:message extensionRegistry:extensionRegistry]; } break; } @@ -2218,8 +2221,8 @@ static void MergeSingleFieldFromCodedInputStream(GPBMessage *self, GPBFieldDescr [input readGroup:GPBFieldNumber(field) message:message extensionRegistry:extensionRegistry]; } else { GPBMessage *message = [[field.msgClass alloc] init]; - [input readGroup:GPBFieldNumber(field) message:message extensionRegistry:extensionRegistry]; GPBSetRetainedObjectIvarWithFieldPrivate(self, field, message); + [input readGroup:GPBFieldNumber(field) message:message extensionRegistry:extensionRegistry]; } break; } @@ -2327,16 +2330,20 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream( #undef CASE_NOT_PACKED_OBJECT case GPBDataTypeMessage: { GPBMessage *message = [[field.msgClass alloc] init]; - [input readMessage:message extensionRegistry:extensionRegistry]; [(NSMutableArray *)genericArray addObject:message]; + // The array will now retain message, so go ahead and release it in case + // -readMessage:extensionRegistry: throws so it won't be leaked. [message release]; + [input readMessage:message extensionRegistry:extensionRegistry]; break; } case GPBDataTypeGroup: { GPBMessage *message = [[field.msgClass alloc] init]; - [input readGroup:GPBFieldNumber(field) message:message extensionRegistry:extensionRegistry]; [(NSMutableArray *)genericArray addObject:message]; + // The array will now retain message, so go ahead and release it in case + // -readGroup:extensionRegistry: throws so it won't be leaked. [message release]; + [input readGroup:GPBFieldNumber(field) message:message extensionRegistry:extensionRegistry]; break; } case GPBDataTypeEnum: { diff --git a/objectivec/GPBUnknownFieldSet.m b/objectivec/GPBUnknownFieldSet.m index 1dce738934..fd36935480 100644 --- a/objectivec/GPBUnknownFieldSet.m +++ b/objectivec/GPBUnknownFieldSet.m @@ -318,10 +318,12 @@ static void GPBUnknownFieldSetMergeUnknownFields(__unused const void *key, const } case GPBWireFormatStartGroup: { GPBUnknownFieldSet *unknownFieldSet = [[GPBUnknownFieldSet alloc] init]; - [input readUnknownGroup:number message:unknownFieldSet]; GPBUnknownField *field = [self mutableFieldForNumber:number create:YES]; [field addGroup:unknownFieldSet]; + // The field will now retain unknownFieldSet, so go ahead and release it in case + // -readUnknownGroup:message: throws so it won't be leaked. [unknownFieldSet release]; + [input readUnknownGroup:number message:unknownFieldSet]; return YES; } case GPBWireFormatEndGroup: