aboutsummaryrefslogtreecommitdiff
path: root/objectivec/GPBCodedInputStream.m
diff options
context:
space:
mode:
authorSergio Campamá <kaipi@google.com>2016-06-02 11:14:26 -0700
committerThomas Van Lenten <thomasvl@google.com>2016-06-02 14:14:26 -0400
commite34c09182ebe0ed2958aefa809159498923743d3 (patch)
tree2eaf97f34c4ece1c6391fb795b20acc2d46fa145 /objectivec/GPBCodedInputStream.m
parent0ab7a7f74458be56bfc65a71a46711637ee5962b (diff)
downloadprotobuf-e34c09182ebe0ed2958aefa809159498923743d3.tar.gz
protobuf-e34c09182ebe0ed2958aefa809159498923743d3.tar.bz2
protobuf-e34c09182ebe0ed2958aefa809159498923743d3.zip
Improving the granularity parsing errors (#1623)
Add more context to GPBCodedInputStream failures. Have GPBMessage parsing apis extract out the GPBCodedInputStream information and expose it. Update HeaderDocs with pointers to all error domains/codes. Expand the unittests to cover the full set of errors reported. Fixes https://github.com/google/protobuf/issues/1618
Diffstat (limited to 'objectivec/GPBCodedInputStream.m')
-rw-r--r--objectivec/GPBCodedInputStream.m65
1 files changed, 39 insertions, 26 deletions
diff --git a/objectivec/GPBCodedInputStream.m b/objectivec/GPBCodedInputStream.m
index 40227178..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");
}
}
@@ -353,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;
}
@@ -414,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];
@@ -428,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];
@@ -443,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;
@@ -461,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;