aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--objectivec/GPBCodedInputStream.m11
-rw-r--r--objectivec/GPBMessage.m5
-rw-r--r--objectivec/GPBUnknownFieldSet.m1
-rw-r--r--objectivec/GPBWireFormat.h1
-rw-r--r--objectivec/GPBWireFormat.m7
5 files changed, 21 insertions, 4 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 {
diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m
index 7ab184c1..b9566bdf 100644
--- a/objectivec/GPBMessage.m
+++ b/objectivec/GPBMessage.m
@@ -2279,6 +2279,9 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
while (YES) {
BOOL merged = NO;
tag = GPBCodedInputStreamReadTag(state);
+ if (tag == 0) {
+ break; // Reached end.
+ }
for (NSUInteger i = 0; i < numFields; ++i) {
if (startingIndex >= numFields) startingIndex = 0;
GPBFieldDescriptor *fieldDescriptor = fields[startingIndex];
@@ -2317,7 +2320,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
}
} // for(i < numFields)
- if (!merged) {
+ if (!merged && (tag != 0)) {
// Primitive, repeated types can be packed on unpacked on the wire, and
// are parsed either way. The above loop covered tag in the preferred
// for, so this need to check the alternate form.
diff --git a/objectivec/GPBUnknownFieldSet.m b/objectivec/GPBUnknownFieldSet.m
index af08556e..9ba1d65c 100644
--- a/objectivec/GPBUnknownFieldSet.m
+++ b/objectivec/GPBUnknownFieldSet.m
@@ -359,6 +359,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
}
- (BOOL)mergeFieldFrom:(int32_t)tag input:(GPBCodedInputStream *)input {
+ NSAssert(GPBWireFormatIsValidTag(tag), @"Got passed an invalid tag");
int32_t number = GPBWireFormatGetTagFieldNumber(tag);
GPBCodedInputStreamState *state = &input->state_;
switch (GPBWireFormatGetTagWireType(tag)) {
diff --git a/objectivec/GPBWireFormat.h b/objectivec/GPBWireFormat.h
index 29cf2f0b..c5941a38 100644
--- a/objectivec/GPBWireFormat.h
+++ b/objectivec/GPBWireFormat.h
@@ -53,6 +53,7 @@ uint32_t GPBWireFormatMakeTag(uint32_t fieldNumber, GPBWireFormat wireType)
__attribute__((const));
GPBWireFormat GPBWireFormatGetTagWireType(uint32_t tag) __attribute__((const));
uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) __attribute__((const));
+BOOL GPBWireFormatIsValidTag(uint32_t tag) __attribute__((const));
GPBWireFormat GPBWireFormatForType(GPBDataType dataType, BOOL isPacked)
__attribute__((const));
diff --git a/objectivec/GPBWireFormat.m b/objectivec/GPBWireFormat.m
index 193235d6..860a339f 100644
--- a/objectivec/GPBWireFormat.m
+++ b/objectivec/GPBWireFormat.m
@@ -49,6 +49,13 @@ uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) {
return GPBLogicalRightShift32(tag, GPBWireFormatTagTypeBits);
}
+BOOL GPBWireFormatIsValidTag(uint32_t tag) {
+ uint32_t formatBits = (tag & GPBWireFormatTagTypeMask);
+ // The valid GPBWireFormat* values are 0-5, anything else is not a valid tag.
+ BOOL result = (formatBits <= 5);
+ return result;
+}
+
GPBWireFormat GPBWireFormatForType(GPBDataType type, BOOL isPacked) {
if (isPacked) {
return GPBWireFormatLengthDelimited;