| Index: third_party/protobuf/objectivec/GPBCodedInputStream.m
|
| diff --git a/third_party/protobuf/objectivec/GPBCodedInputStream.m b/third_party/protobuf/objectivec/GPBCodedInputStream.m
|
| index 319ec15ba7c81dbb7627b50339ea603619db853e..e8c8989cc79c2bc18a142bea012794f7975e00e4 100644
|
| --- a/third_party/protobuf/objectivec/GPBCodedInputStream.m
|
| +++ b/third_party/protobuf/objectivec/GPBCodedInputStream.m
|
| @@ -36,17 +36,42 @@
|
| #import "GPBUtilities_PackagePrivate.h"
|
| #import "GPBWireFormat.h"
|
|
|
| +NSString *const GPBCodedInputStreamException =
|
| + GPBNSStringifySymbol(GPBCodedInputStreamException);
|
| +
|
| +NSString *const GPBCodedInputStreamUnderlyingErrorKey =
|
| + GPBNSStringifySymbol(GPBCodedInputStreamUnderlyingErrorKey);
|
| +
|
| +NSString *const GPBCodedInputStreamErrorDomain =
|
| + GPBNSStringifySymbol(GPBCodedInputStreamErrorDomain);
|
| +
|
| static const NSUInteger kDefaultRecursionLimit = 64;
|
|
|
| +static void RaiseException(NSInteger code, NSString *reason) {
|
| + NSDictionary *errorInfo = nil;
|
| + if ([reason length]) {
|
| + errorInfo = @{ GPBErrorReasonKey: reason };
|
| + }
|
| + NSError *error = [NSError errorWithDomain:GPBCodedInputStreamErrorDomain
|
| + code:code
|
| + userInfo:errorInfo];
|
| +
|
| + NSDictionary *exceptionInfo =
|
| + @{ GPBCodedInputStreamUnderlyingErrorKey: error };
|
| + [[[NSException alloc] initWithName:GPBCodedInputStreamException
|
| + reason:reason
|
| + userInfo:exceptionInfo] raise];
|
| +}
|
| +
|
| static void CheckSize(GPBCodedInputStreamState *state, size_t size) {
|
| size_t newSize = state->bufferPos + size;
|
| if (newSize > state->bufferSize) {
|
| - [NSException raise:NSParseErrorException format:@""];
|
| + RaiseException(GPBCodedInputStreamErrorInvalidSize, nil);
|
| }
|
| if (newSize > state->currentLimit) {
|
| // Fast forward to end of currentLimit;
|
| state->bufferPos = state->currentLimit;
|
| - [NSException raise:NSParseErrorException format:@""];
|
| + RaiseException(GPBCodedInputStreamErrorSubsectionLimitReached, nil);
|
| }
|
| }
|
|
|
| @@ -95,8 +120,8 @@ static int32_t ReadRawVarint32(GPBCodedInputStreamState *state) {
|
| return result;
|
| }
|
| }
|
| - [NSException raise:NSParseErrorException
|
| - format:@"Unable to read varint32"];
|
| + RaiseException(GPBCodedInputStreamErrorInvalidVarInt,
|
| + @"Invalid VarInt32");
|
| }
|
| }
|
| }
|
| @@ -115,7 +140,7 @@ static int64_t ReadRawVarint64(GPBCodedInputStreamState *state) {
|
| }
|
| shift += 7;
|
| }
|
| - [NSException raise:NSParseErrorException format:@"Unable to read varint64"];
|
| + RaiseException(GPBCodedInputStreamErrorInvalidVarInt, @"Invalid VarInt64");
|
| return 0;
|
| }
|
|
|
| @@ -202,8 +227,13 @@ int32_t GPBCodedInputStreamReadTag(GPBCodedInputStreamState *state) {
|
| state->lastTag = ReadRawVarint32(state);
|
| if (state->lastTag == 0) {
|
| // If we actually read zero, that's not a valid tag.
|
| - [NSException raise:NSParseErrorException
|
| - format:@"Invalid last tag %d", state->lastTag];
|
| + RaiseException(GPBCodedInputStreamErrorInvalidTag,
|
| + @"A zero tag on the wire is invalid.");
|
| + }
|
| + // Tags have to include a valid wireformat, check that also.
|
| + if (!GPBWireFormatIsValidTag(state->lastTag)) {
|
| + RaiseException(GPBCodedInputStreamErrorInvalidTag,
|
| + @"Invalid wireformat in tag.");
|
| }
|
| return state->lastTag;
|
| }
|
| @@ -226,8 +256,7 @@ NSString *GPBCodedInputStreamReadRetainedString(
|
| NSLog(@"UTF-8 failure, is some field type 'string' when it should be "
|
| @"'bytes'?");
|
| #endif
|
| - [NSException raise:NSParseErrorException
|
| - format:@"Invalid UTF-8 for a 'string'"];
|
| + RaiseException(GPBCodedInputStreamErrorInvalidUTF8, nil);
|
| }
|
| }
|
| return result;
|
| @@ -262,8 +291,7 @@ size_t GPBCodedInputStreamPushLimit(GPBCodedInputStreamState *state,
|
| byteLimit += state->bufferPos;
|
| size_t oldLimit = state->currentLimit;
|
| if (byteLimit > oldLimit) {
|
| - [NSException raise:NSInvalidArgumentException
|
| - format:@"byteLimit > oldLimit: %tu > %tu", byteLimit, oldLimit];
|
| + RaiseException(GPBCodedInputStreamErrorInvalidSubsectionLimit, nil);
|
| }
|
| state->currentLimit = byteLimit;
|
| return oldLimit;
|
| @@ -286,8 +314,7 @@ BOOL GPBCodedInputStreamIsAtEnd(GPBCodedInputStreamState *state) {
|
| void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
|
| int32_t value) {
|
| if (state->lastTag != value) {
|
| - [NSException raise:NSParseErrorException
|
| - format:@"Last tag: %d should be %d", state->lastTag, value];
|
| + RaiseException(GPBCodedInputStreamErrorInvalidTag, @"Unexpected tag read");
|
| }
|
| }
|
|
|
| @@ -316,6 +343,12 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
|
| [super dealloc];
|
| }
|
|
|
| +// Direct access is use for speed, to avoid even internally declaring things
|
| +// read/write, etc. The warning is enabled in the project to ensure code calling
|
| +// protos can turn on -Wdirect-ivar-access without issues.
|
| +#pragma clang diagnostic push
|
| +#pragma clang diagnostic ignored "-Wdirect-ivar-access"
|
| +
|
| - (int32_t)readTag {
|
| return GPBCodedInputStreamReadTag(&state_);
|
| }
|
| @@ -325,6 +358,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
|
| }
|
|
|
| - (BOOL)skipField:(int32_t)tag {
|
| + NSAssert(GPBWireFormatIsValidTag(tag), @"Invalid tag");
|
| switch (GPBWireFormatGetTagWireType(tag)) {
|
| case GPBWireFormatVarint:
|
| GPBCodedInputStreamReadInt32(&state_);
|
| @@ -347,8 +381,6 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
|
| SkipRawData(&state_, sizeof(int32_t));
|
| return YES;
|
| }
|
| - [NSException raise:NSParseErrorException format:@"Invalid tag %d", tag];
|
| - return NO;
|
| }
|
|
|
| - (void)skipMessage {
|
| @@ -368,6 +400,14 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
|
| return state_.bufferPos;
|
| }
|
|
|
| +- (size_t)pushLimit:(size_t)byteLimit {
|
| + return GPBCodedInputStreamPushLimit(&state_, byteLimit);
|
| +}
|
| +
|
| +- (void)popLimit:(size_t)oldLimit {
|
| + GPBCodedInputStreamPopLimit(&state_, oldLimit);
|
| +}
|
| +
|
| - (double)readDouble {
|
| return GPBCodedInputStreamReadDouble(&state_);
|
| }
|
| @@ -408,9 +448,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
|
| message:(GPBMessage *)message
|
| extensionRegistry:(GPBExtensionRegistry *)extensionRegistry {
|
| if (state_.recursionDepth >= kDefaultRecursionLimit) {
|
| - [NSException raise:NSParseErrorException
|
| - format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
|
| - kDefaultRecursionLimit];
|
| + RaiseException(GPBCodedInputStreamErrorRecursionDepthExceeded, nil);
|
| }
|
| ++state_.recursionDepth;
|
| [message mergeFromCodedInputStream:self extensionRegistry:extensionRegistry];
|
| @@ -422,9 +460,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
|
| - (void)readUnknownGroup:(int32_t)fieldNumber
|
| message:(GPBUnknownFieldSet *)message {
|
| if (state_.recursionDepth >= kDefaultRecursionLimit) {
|
| - [NSException raise:NSParseErrorException
|
| - format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
|
| - kDefaultRecursionLimit];
|
| + RaiseException(GPBCodedInputStreamErrorRecursionDepthExceeded, nil);
|
| }
|
| ++state_.recursionDepth;
|
| [message mergeFromCodedInputStream:self];
|
| @@ -437,9 +473,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
|
| extensionRegistry:(GPBExtensionRegistry *)extensionRegistry {
|
| int32_t length = ReadRawVarint32(&state_);
|
| if (state_.recursionDepth >= kDefaultRecursionLimit) {
|
| - [NSException raise:NSParseErrorException
|
| - format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
|
| - kDefaultRecursionLimit];
|
| + RaiseException(GPBCodedInputStreamErrorRecursionDepthExceeded, nil);
|
| }
|
| size_t oldLimit = GPBCodedInputStreamPushLimit(&state_, length);
|
| ++state_.recursionDepth;
|
| @@ -455,9 +489,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
|
| parentMessage:(GPBMessage *)parentMessage {
|
| int32_t length = ReadRawVarint32(&state_);
|
| if (state_.recursionDepth >= kDefaultRecursionLimit) {
|
| - [NSException raise:NSParseErrorException
|
| - format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
|
| - kDefaultRecursionLimit];
|
| + RaiseException(GPBCodedInputStreamErrorRecursionDepthExceeded, nil);
|
| }
|
| size_t oldLimit = GPBCodedInputStreamPushLimit(&state_, length);
|
| ++state_.recursionDepth;
|
| @@ -496,4 +528,6 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
|
| return GPBCodedInputStreamReadSInt64(&state_);
|
| }
|
|
|
| +#pragma clang diagnostic pop
|
| +
|
| @end
|
|
|