aboutsummaryrefslogtreecommitdiffhomepage
path: root/objectivec/GPBCodedInputStream.m
diff options
context:
space:
mode:
authorGravatar Thomas Van Lenten <thomasvl@google.com>2016-06-29 09:51:13 -0400
committerGravatar GitHub <noreply@github.com>2016-06-29 09:51:13 -0400
commitc18aa7795a2e02ef700ff8b039d94ecdcc33432f (patch)
tree6a1c28a6dbfd0ef412c23236d1aa8d4f2c76abe5 /objectivec/GPBCodedInputStream.m
parente0016c5b6ae61ad60d260a78c5834cc537b46d10 (diff)
Validate the tag numbers when parsing. (#1725)
There was a twist code path (that some times showed up due to what happened to be in memory in failure cases), that would cast a bogus wire type into the enum, and then fall through switch statements. Resolve this by validating all wire types when parsing tags and throwing the error at that point so it can't enter the system. As added safety, stick in a few asserts for apis that get passed tags to ensure they also are only seeing valid data. Bonus: Tweak the parsing loop to skip some work when we get the end marker (zero tag) instead of still looping through all the fields.
Diffstat (limited to 'objectivec/GPBCodedInputStream.m')
-rw-r--r--objectivec/GPBCodedInputStream.m11
1 files changed, 8 insertions, 3 deletions
diff --git a/objectivec/GPBCodedInputStream.m b/objectivec/GPBCodedInputStream.m
index acba7156..2b578dd5 100644
--- a/objectivec/GPBCodedInputStream.m
+++ b/objectivec/GPBCodedInputStream.m
@@ -227,7 +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.
- RaiseException(GPBCodedInputStreamErrorInvalidTag, @"Last tag can't be 0");
+ 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;
}
@@ -352,6 +358,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
}
- (BOOL)skipField:(int32_t)tag {
+ NSAssert(GPBWireFormatIsValidTag(tag), @"Invalid tag");
switch (GPBWireFormatGetTagWireType(tag)) {
case GPBWireFormatVarint:
GPBCodedInputStreamReadInt32(&state_);
@@ -374,8 +381,6 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
SkipRawData(&state_, sizeof(int32_t));
return YES;
}
- RaiseException(GPBCodedInputStreamErrorInvalidTag, nil);
- return NO;
}
- (void)skipMessage {