@@ -742,16 +742,12 @@ static void DecodeSingleValueFromInputStream(GPBExtensionDescriptor *extension,
742742 message: targetMessage
743743 extensionRegistry: extensionRegistry];
744744 } else {
745- // description->dataType == GPBDataTypeMessage
746- if (GPBExtensionIsWireFormat (description)) {
747- // For MessageSet fields the message length will have already been
748- // read.
749- [targetMessage mergeFromCodedInputStream: input
750- extensionRegistry: extensionRegistry
751- endingTag: 0 ];
752- } else {
753- [input readMessage: targetMessage extensionRegistry: extensionRegistry];
754- }
745+ // description->dataType == GPBDataTypeMessage
746+ #if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
747+ NSCAssert (!GPBExtensionIsWireFormat(description),
748+ @"Internal error: got a MessageSet extension when not expected.");
749+ #endif
750+ [input readMessage: targetMessage extensionRegistry: extensionRegistry];
755751 }
756752 // Nothing to add below since the caller provided the message (and added it).
757753 nsValue = nil ;
@@ -2183,81 +2179,85 @@ - (void)parseMessageSet:(GPBCodedInputStream *)input
21832179 extensionRegistry:(id <GPBExtensionRegistry>)extensionRegistry {
21842180 uint32_t typeId = 0 ;
21852181 NSData *rawBytes = nil ;
2186- GPBExtensionDescriptor *extension = nil ;
21872182 GPBCodedInputStreamState *state = &input->state_ ;
2183+ BOOL gotType = NO ;
2184+ BOOL gotBytes = NO ;
21882185 while (true ) {
21892186 uint32_t tag = GPBCodedInputStreamReadTag (state);
2190- if (tag == 0 ) {
2187+ if (tag == GPBWireFormatMessageSetItemEndTag || tag == 0 ) {
21912188 break ;
21922189 }
21932190
21942191 if (tag == GPBWireFormatMessageSetTypeIdTag) {
2195- typeId = GPBCodedInputStreamReadUInt32 (state);
2196- if (typeId != 0 ) {
2197- extension = [extensionRegistry extensionForDescriptor: [self descriptor ] fieldNumber: typeId];
2192+ uint32_t tmp = GPBCodedInputStreamReadUInt32 (state);
2193+ // Spec says only use the first value.
2194+ if (!gotType) {
2195+ gotType = YES ;
2196+ typeId = tmp;
21982197 }
21992198 } else if (tag == GPBWireFormatMessageSetMessageTag) {
2200- rawBytes = [GPBCodedInputStreamReadRetainedBytesNoCopy (state) autorelease ];
2199+ if (gotBytes) {
2200+ // Skip over the payload instead of collecting it.
2201+ [input skipField: tag];
2202+ } else {
2203+ rawBytes = [GPBCodedInputStreamReadRetainedBytesNoCopy (state) autorelease ];
2204+ gotBytes = YES ;
2205+ }
22012206 } else {
2207+ // Don't capture unknowns within the message set impl group.
22022208 if (![input skipField: tag]) {
22032209 break ;
22042210 }
22052211 }
22062212 }
22072213
2208- [input checkLastTagWas: GPBWireFormatMessageSetItemEndTag];
2214+ // If we get here because of end of input (tag zero) or the wrong end tag (within the skipField:),
2215+ // this will error.
2216+ GPBCodedInputStreamCheckLastTagWas (state, GPBWireFormatMessageSetItemEndTag);
22092217
2210- if (rawBytes != nil && typeId != 0 ) {
2211- if (extension != nil ) {
2212- GPBCodedInputStream *newInput = [[GPBCodedInputStream alloc ] initWithData: rawBytes];
2213- @try {
2214- ExtensionMergeFromInputStream (extension, extension.packable , newInput, extensionRegistry,
2215- self);
2216- } @finally {
2217- [newInput release ];
2218- }
2219- } else {
2220- GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields (self);
2221- // rawBytes was created via a NoCopy, so it can be reusing a
2222- // subrange of another NSData that might go out of scope as things
2223- // unwind, so a copy is needed to ensure what is saved in the
2224- // unknown fields stays valid.
2225- NSData *cloned = [NSData dataWithData: rawBytes];
2226- [unknownFields mergeMessageSetMessage: typeId data: cloned];
2227- }
2218+ if (!gotType || !gotBytes) {
2219+ // upb_Decoder_DecodeMessageSetItem does't keep this partial as an unknown field, it just drops
2220+ // it, so do the same thing.
2221+ return ;
22282222 }
2229- }
22302223
2231- - (void )parseUnknownField:(GPBCodedInputStream *)input
2232- extensionRegistry:(id <GPBExtensionRegistry>)extensionRegistry
2233- tag:(uint32_t )tag {
2234- int32_t fieldNumber = GPBWireFormatGetTagFieldNumber (tag);
2235- GPBDescriptor *descriptor = [self descriptor ];
2236- GPBExtensionDescriptor *extension = [extensionRegistry extensionForDescriptor: descriptor
2237- fieldNumber: fieldNumber];
2238- if (extension == nil ) {
2239- if (descriptor.wireFormat && GPBWireFormatMessageSetItemTag == tag) {
2240- [self parseMessageSet: input extensionRegistry: extensionRegistry];
2241- return ;
2224+ GPBExtensionDescriptor *extension = [extensionRegistry extensionForDescriptor: [self descriptor ]
2225+ fieldNumber: typeId];
2226+ if (extension) {
2227+ #if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
2228+ NSAssert (extension.dataType == GPBDataTypeMessage,
2229+ @" Internal Error: MessageSet extension must be a message field." );
2230+ NSAssert (GPBExtensionIsWireFormat(extension->description_),
2231+ @"Internal Error: MessageSet extension must have message_set_wire_format set.");
2232+ NSAssert (!GPBExtensionIsRepeated(extension->description_),
2233+ @"Internal Error: MessageSet extension can't be repeated.");
2234+ #endif
2235+ // Look up the existing one to merge to or create a new one.
2236+ GPBMessage *targetMessage = [self getExistingExtension: extension];
2237+ if (!targetMessage) {
2238+ GPBDescriptor *descriptor = [extension.msgClass descriptor ];
2239+ targetMessage = [[descriptor.messageClass alloc ] init ];
2240+ [self setExtension: extension value: targetMessage];
2241+ [targetMessage release ];
2242+ }
2243+ GPBCodedInputStream *newInput = [[GPBCodedInputStream alloc ] initWithData: rawBytes];
2244+ @try {
2245+ [targetMessage mergeFromCodedInputStream: newInput
2246+ extensionRegistry: extensionRegistry
2247+ endingTag: 0 ];
2248+ } @finally {
2249+ [newInput release ];
22422250 }
22432251 } else {
2244- GPBWireFormat wireType = GPBWireFormatGetTagWireType (tag);
2245- if (extension.wireType == wireType) {
2246- ExtensionMergeFromInputStream (extension, extension.packable , input, extensionRegistry, self);
2247- return ;
2248- }
2249- // Primitive, repeated types can be packed on unpacked on the wire, and are
2250- // parsed either way.
2251- if ([extension isRepeated ] && !GPBDataTypeIsObject (extension->description_ ->dataType ) &&
2252- (extension.alternateWireType == wireType)) {
2253- ExtensionMergeFromInputStream (extension, !extension.packable , input, extensionRegistry, self);
2254- return ;
2255- }
2256- }
2257- GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields (self);
2258- if (![unknownFields mergeFieldFrom: tag input: input]) {
2259- [NSException raise: NSInternalInconsistencyException
2260- format: @" Internal Error: Unable to parse unknown field %u " , tag];
2252+ // The extension isn't in the registry, but it was well formed, so the whole group structure
2253+ // get preserved as an unknown field.
2254+ GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields (self);
2255+ // rawBytes was created via a NoCopy, so it can be reusing a
2256+ // subrange of another NSData that might go out of scope as things
2257+ // unwind, so a copy is needed to ensure what is saved in the
2258+ // unknown fields stays valid.
2259+ NSData *cloned = [NSData dataWithData: rawBytes];
2260+ [unknownFields mergeMessageSetMessage: typeId data: cloned];
22612261 }
22622262}
22632263
@@ -2475,6 +2475,7 @@ - (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input
24752475 uint32_t tag = 0 ;
24762476 NSUInteger startingIndex = 0 ;
24772477 NSArray *fields = descriptor->fields_ ;
2478+ BOOL isMessageSetWireFormat = descriptor.isWireFormat ;
24782479 NSUInteger numFields = fields.count ;
24792480 while (YES ) {
24802481 BOOL merged = NO ;
@@ -2551,7 +2552,40 @@ - (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input
25512552
25522553 if (merged) continue ; // On to the next tag
25532554
2554- [self parseUnknownField: input extensionRegistry: extensionRegistry tag: tag];
2555+ if (isMessageSetWireFormat) {
2556+ if (GPBWireFormatMessageSetItemTag == tag) {
2557+ [self parseMessageSet: input extensionRegistry: extensionRegistry];
2558+ continue ; // On to the next tag
2559+ }
2560+ } else {
2561+ // ObjC Runtime currently doesn't track if a message supported extensions, so the check is
2562+ // always done.
2563+ GPBExtensionDescriptor *extension =
2564+ [extensionRegistry extensionForDescriptor: descriptor
2565+ fieldNumber: GPBWireFormatGetTagFieldNumber (tag)];
2566+ if (extension) {
2567+ GPBWireFormat wireType = GPBWireFormatGetTagWireType (tag);
2568+ if (extension.wireType == wireType) {
2569+ ExtensionMergeFromInputStream (extension, extension.packable , input, extensionRegistry,
2570+ self);
2571+ continue ; // On to the next tag
2572+ }
2573+ // Primitive, repeated types can be packed on unpacked on the wire, and are
2574+ // parsed either way.
2575+ if ([extension isRepeated ] && !GPBDataTypeIsObject (extension->description_ ->dataType ) &&
2576+ (extension.alternateWireType == wireType)) {
2577+ ExtensionMergeFromInputStream (extension, !extension.packable , input, extensionRegistry,
2578+ self);
2579+ continue ; // On to the next tag
2580+ }
2581+ }
2582+ }
2583+
2584+ GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields (self);
2585+ if (![unknownFields mergeFieldFrom: tag input: input]) {
2586+ [NSException raise: NSInternalInconsistencyException
2587+ format: @" Internal Error: Unable to parse unknown field %u " , tag];
2588+ }
25552589 } // while(YES)
25562590}
25572591
0 commit comments