|
|
|
@ -283,16 +283,53 @@ |
|
|
|
|
[output writeRawData:[NSData dataWithBytes:bytes length:sizeof(bytes)]]; |
|
|
|
|
[output flush]; |
|
|
|
|
|
|
|
|
|
NSData* data = |
|
|
|
|
NSData *data = |
|
|
|
|
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
NSError *error = nil; |
|
|
|
|
TestAllTypes* message = [TestAllTypes parseFromCodedInputStream:input |
|
|
|
|
extensionRegistry:nil |
|
|
|
|
error:NULL]; |
|
|
|
|
XCTAssertNotNil(message); |
|
|
|
|
// Make sure we can read string properties twice without crashing. |
|
|
|
|
XCTAssertEqual([message.defaultString length], (NSUInteger)0); |
|
|
|
|
XCTAssertEqualObjects(@"", message.defaultString); |
|
|
|
|
error:&error]; |
|
|
|
|
XCTAssertNotNil(error); |
|
|
|
|
XCTAssertNil(message); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)testBOMWithinStrings { |
|
|
|
|
// We've seen servers that end up with BOMs within strings (not always at the |
|
|
|
|
// start, and sometimes in multiple places), make sure they always parse |
|
|
|
|
// correctly. (Again, this is inpart incase a custom string class is ever |
|
|
|
|
// used again.) |
|
|
|
|
const char* strs[] = { |
|
|
|
|
"\xEF\xBB\xBF String with BOM", |
|
|
|
|
"String with \xEF\xBB\xBF in middle", |
|
|
|
|
"String with end bom \xEF\xBB\xBF", |
|
|
|
|
"\xEF\xBB\xBF\xe2\x99\xa1", // BOM White Heart |
|
|
|
|
"\xEF\xBB\xBF\xEF\xBB\xBF String with Two BOM", |
|
|
|
|
}; |
|
|
|
|
for (size_t i = 0; i < GPBARRAYSIZE(strs); ++i) { |
|
|
|
|
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory]; |
|
|
|
|
GPBCodedOutputStream* output = |
|
|
|
|
[GPBCodedOutputStream streamWithOutputStream:rawOutput]; |
|
|
|
|
|
|
|
|
|
int32_t tag = GPBWireFormatMakeTag(TestAllTypes_FieldNumber_DefaultString, |
|
|
|
|
GPBWireFormatLengthDelimited); |
|
|
|
|
[output writeRawVarint32:tag]; |
|
|
|
|
size_t length = strlen(strs[i]); |
|
|
|
|
[output writeRawVarint32:(int32_t)length]; |
|
|
|
|
[output writeRawData:[NSData dataWithBytes:strs[i] length:length]]; |
|
|
|
|
[output flush]; |
|
|
|
|
|
|
|
|
|
NSData* data = |
|
|
|
|
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
TestAllTypes* message = [TestAllTypes parseFromCodedInputStream:input |
|
|
|
|
extensionRegistry:nil |
|
|
|
|
error:NULL]; |
|
|
|
|
XCTAssertNotNil(message, @"Loop %zd", i); |
|
|
|
|
// Ensure the string is there. NSString can consume the BOM in some |
|
|
|
|
// cases, so don't actually check the string for exact equality. |
|
|
|
|
XCTAssertTrue(message.defaultString.length > 0, @"Loop %zd", i); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@end |
|
|
|
|