diff options
Diffstat (limited to 'objectivec/GPBCodedInputStream.m')
-rw-r--r-- | objectivec/GPBCodedInputStream.m | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/objectivec/GPBCodedInputStream.m b/objectivec/GPBCodedInputStream.m index 319ec15b..acba7156 100644 --- a/objectivec/GPBCodedInputStream.m +++ b/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,7 @@ 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, @"Last tag can't be 0"); } return state->lastTag; } @@ -226,8 +250,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 +285,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 +308,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 +337,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_); } @@ -347,7 +374,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state, SkipRawData(&state_, sizeof(int32_t)); return YES; } - [NSException raise:NSParseErrorException format:@"Invalid tag %d", tag]; + RaiseException(GPBCodedInputStreamErrorInvalidTag, nil); return NO; } @@ -408,9 +435,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 +447,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 +460,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 +476,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 +515,6 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state, return GPBCodedInputStreamReadSInt64(&state_); } +#pragma clang diagnostic pop + @end |