[ObjC] Ensure `-[GPBMessage writeToOutputStream:]` still throws exception on flush failure
This restores the behavior of `-[GPBMessage writeToOutputStream:]` throwing an exception if the underlying `GPBCodedOutputStream` failed to flush. `GPBDictionary` and `GPBUnknownFieldSet` could also have theoretically thrown exceptions from just about any method (although not for disk I/O reasons), so this also restores that functionality by explicitly flushing before deallocating the `GPBCodedOutputStream`. PiperOrigin-RevId: 580207004pull/14670/head
parent
9ac3548fa9
commit
1e0338b2ba
|
@ -1044,6 +1044,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream,
|
|||
//% GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data];
|
||||
//% WriteDict##KEY_NAME##Field(outputStream, key->value##KEY_NAME, kMapKeyFieldNumber, keyDataType);
|
||||
//% WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum);
|
||||
//% [outputStream flush];
|
||||
//% [outputStream release];
|
||||
//% return data;
|
||||
//%}
|
||||
|
@ -2788,6 +2789,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream,
|
|||
GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data];
|
||||
WriteDictUInt32Field(outputStream, key->valueUInt32, kMapKeyFieldNumber, keyDataType);
|
||||
WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum);
|
||||
[outputStream flush];
|
||||
[outputStream release];
|
||||
return data;
|
||||
}
|
||||
|
@ -4518,6 +4520,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream,
|
|||
GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data];
|
||||
WriteDictInt32Field(outputStream, key->valueInt32, kMapKeyFieldNumber, keyDataType);
|
||||
WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum);
|
||||
[outputStream flush];
|
||||
[outputStream release];
|
||||
return data;
|
||||
}
|
||||
|
@ -6248,6 +6251,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream,
|
|||
GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data];
|
||||
WriteDictUInt64Field(outputStream, key->valueUInt64, kMapKeyFieldNumber, keyDataType);
|
||||
WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum);
|
||||
[outputStream flush];
|
||||
[outputStream release];
|
||||
return data;
|
||||
}
|
||||
|
@ -7978,6 +7982,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream,
|
|||
GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data];
|
||||
WriteDictInt64Field(outputStream, key->valueInt64, kMapKeyFieldNumber, keyDataType);
|
||||
WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum);
|
||||
[outputStream flush];
|
||||
[outputStream release];
|
||||
return data;
|
||||
}
|
||||
|
@ -9768,6 +9773,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream,
|
|||
GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data];
|
||||
WriteDictStringField(outputStream, key->valueString, kMapKeyFieldNumber, keyDataType);
|
||||
WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum);
|
||||
[outputStream flush];
|
||||
[outputStream release];
|
||||
return data;
|
||||
}
|
||||
|
@ -11741,6 +11747,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream,
|
|||
GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data];
|
||||
WriteDictBoolField(outputStream, key->valueBool, kMapKeyFieldNumber, keyDataType);
|
||||
WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum);
|
||||
[outputStream flush];
|
||||
[outputStream release];
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -1343,6 +1343,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
|
|||
GPBCodedOutputStream *stream = [[GPBCodedOutputStream alloc] initWithData:data];
|
||||
@try {
|
||||
[self writeToCodedOutputStream:stream];
|
||||
[stream flush];
|
||||
} @catch (NSException *exception) {
|
||||
// This really shouldn't happen. Normally, this could mean there was a bug in the library and it
|
||||
// failed to match between computing the size and writing out the bytes. However, the more
|
||||
|
@ -1393,6 +1394,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
|
|||
GPBCodedOutputStream *stream = [[GPBCodedOutputStream alloc] initWithOutputStream:output];
|
||||
@try {
|
||||
[self writeToCodedOutputStream:stream];
|
||||
[stream flush];
|
||||
size_t bytesWritten = [stream bytesWritten];
|
||||
if (bytesWritten > kMaximumMessageSize) {
|
||||
[NSException raise:GPBMessageExceptionMessageTooLarge
|
||||
|
@ -1436,6 +1438,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
|
|||
GPBCodedOutputStream *codedOutput = [[GPBCodedOutputStream alloc] initWithOutputStream:output];
|
||||
@try {
|
||||
[self writeDelimitedToCodedOutputStream:codedOutput];
|
||||
[codedOutput flush];
|
||||
} @finally {
|
||||
[codedOutput release];
|
||||
}
|
||||
|
|
|
@ -207,6 +207,7 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(__unused const void *ke
|
|||
NSMutableData *data = [NSMutableData dataWithLength:self.serializedSize];
|
||||
GPBCodedOutputStream *output = [[GPBCodedOutputStream alloc] initWithData:data];
|
||||
[self writeToCodedOutputStream:output];
|
||||
[output flush];
|
||||
[output release];
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -2225,4 +2225,17 @@
|
|||
XCTAssertNil(shouldGetAPrefixMessage);
|
||||
}
|
||||
|
||||
- (void)testWriteToFullOutputStreamShouldThrow {
|
||||
uint8_t buffer[1] = {0};
|
||||
|
||||
// Output stream which can write precisely 1 byte of data before it's full.
|
||||
NSOutputStream *output = [[[NSOutputStream alloc] initToBuffer:buffer
|
||||
capacity:sizeof(buffer)] autorelease];
|
||||
|
||||
TestAllTypes *message = [TestAllTypes message];
|
||||
[message setOptionalInt32:1];
|
||||
XCTAssertThrowsSpecificNamed([message writeToOutputStream:output], NSException,
|
||||
GPBCodedOutputStreamException_WriteFailed);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue