Browse Source

Properly error on a tag with field number zero.

Thomas Van Lenten 8 years ago
parent
commit
ecc0f54127

+ 0 - 4
conformance/failure_list_objc.txt

@@ -1,6 +1,2 @@
 # JSON input or output tests are skipped (in conformance_objc.m) as mobile
 # JSON input or output tests are skipped (in conformance_objc.m) as mobile
 # platforms don't support JSON wire format to avoid code bloat.
 # platforms don't support JSON wire format to avoid code bloat.
-Required.ProtobufInput.IllegalZeroFieldNum_Case_0
-Required.ProtobufInput.IllegalZeroFieldNum_Case_1
-Required.ProtobufInput.IllegalZeroFieldNum_Case_2
-Required.ProtobufInput.IllegalZeroFieldNum_Case_3

+ 6 - 6
objectivec/GPBCodedInputStream.m

@@ -230,16 +230,16 @@ int32_t GPBCodedInputStreamReadTag(GPBCodedInputStreamState *state) {
   }
   }
 
 
   state->lastTag = ReadRawVarint32(state);
   state->lastTag = ReadRawVarint32(state);
-  if (state->lastTag == 0) {
-    // If we actually read zero, that's not a valid tag.
-    RaiseException(GPBCodedInputStreamErrorInvalidTag,
-                   @"A zero tag on the wire is invalid.");
-  }
-  // Tags have to include a valid wireformat, check that also.
+  // Tags have to include a valid wireformat.
   if (!GPBWireFormatIsValidTag(state->lastTag)) {
   if (!GPBWireFormatIsValidTag(state->lastTag)) {
     RaiseException(GPBCodedInputStreamErrorInvalidTag,
     RaiseException(GPBCodedInputStreamErrorInvalidTag,
                    @"Invalid wireformat in tag.");
                    @"Invalid wireformat in tag.");
   }
   }
+  // Zero is not a valid field number.
+  if (GPBWireFormatGetTagFieldNumber(state->lastTag) == 0) {
+    RaiseException(GPBCodedInputStreamErrorInvalidTag,
+                   @"A zero field number on the wire is invalid.");
+  }
   return state->lastTag;
   return state->lastTag;
 }
 }
 
 

+ 35 - 0
objectivec/Tests/GPBMessageTests+Serialization.m

@@ -946,6 +946,41 @@ static NSData *DataFromCStr(const char *str) {
   XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag);
   XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag);
 }
 }
 
 
+- (void)testZeroFieldNum {
+  // These are ConformanceTestSuite::TestIllegalTags.
+
+  const char *tests[] = {
+    "\1DEADBEEF",
+    "\2\1\1",
+    "\3\4",
+    "\5DEAD"
+  };
+
+  for (size_t i = 0; i < GPBARRAYSIZE(tests); ++i) {
+    NSData *data = DataFromCStr(tests[i]);
+
+    {
+      // Message from proto2 syntax file
+      NSError *error = nil;
+      Message2 *msg = [Message2 parseFromData:data error:&error];
+      XCTAssertNil(msg, @"i = %zd", i);
+      XCTAssertNotNil(error, @"i = %zd", i);
+      XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain, @"i = %zd", i);
+      XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag, @"i = %zd", i);
+    }
+
+    {
+      // Message from proto3 syntax file
+      NSError *error = nil;
+      Message3 *msg = [Message3 parseFromData:data error:&error];
+      XCTAssertNil(msg, @"i = %zd", i);
+      XCTAssertNotNil(error, @"i = %zd", i);
+      XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain, @"i = %zd", i);
+      XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag, @"i = %zd", i);
+    }
+  }
+}
+
 - (void)testErrorRecursionDepthReached {
 - (void)testErrorRecursionDepthReached {
   NSData *data = DataFromCStr(
   NSData *data = DataFromCStr(
       "\x0A\xF2\x01\x0A\xEF\x01\x0A\xEC\x01\x0A\xE9\x01\x0A\xE6\x01"
       "\x0A\xF2\x01\x0A\xEF\x01\x0A\xEC\x01\x0A\xE9\x01\x0A\xE6\x01"