public void TestSlowPathAvoidance() { using (var ms = new MemoryStream()) { CodedOutputStream output = CodedOutputStream.CreateInstance(ms); output.WriteField(FieldType.Bytes, 1, "bytes", ByteString.CopyFrom(new byte[100])); output.WriteField(FieldType.Bytes, 2, "bytes", ByteString.CopyFrom(new byte[100])); output.Flush(); ms.Position = 0; CodedInputStream input = CodedInputStream.CreateInstance(ms, new byte[ms.Length / 2]); uint tag; string ignore; ByteString value; Assert.IsTrue(input.ReadTag(out tag, out ignore)); Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag)); value = ByteString.Empty; Assert.IsTrue(input.ReadBytes(ref value) && value.Length == 100); Assert.IsTrue(input.ReadTag(out tag, out ignore)); Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag)); value = ByteString.Empty; Assert.IsTrue(input.ReadBytes(ref value) && value.Length == 100); } }
public void TestNegativeEnumArray() { int arraySize = 1 + 1 + (11 * 5); int msgSize = arraySize; byte[] bytes = new byte[msgSize]; CodedOutputStream output = CodedOutputStream.CreateInstance(bytes); output.WriteInt32Array(8, "", new int[] { 0, -1, -2, -3, -4, -5 }); Assert.AreEqual(0, output.SpaceLeft); CodedInputStream input = CodedInputStream.CreateInstance(bytes); uint tag; string name; Assert.IsTrue(input.ReadTag(out tag, out name)); List <TestNegEnum> values = new List <TestNegEnum>(); ICollection <object> unk; input.ReadEnumArray(tag, name, values, out unk); Assert.AreEqual(2, values.Count); Assert.AreEqual(TestNegEnum.None, values[0]); Assert.AreEqual(TestNegEnum.Value, values[1]); Assert.IsNotNull(unk); Assert.AreEqual(4, unk.Count); }
public void ReadMaliciouslyLargeBlob() { MemoryStream ms = new MemoryStream(); CodedOutputStream output = CodedOutputStream.CreateInstance(ms); uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); output.WriteRawVarint32(tag); output.WriteRawVarint32(0x7FFFFFFF); output.WriteRawBytes(new byte[32]); // Pad with a few random bytes. output.Flush(); ms.Position = 0; CodedInputStream input = CodedInputStream.CreateInstance(ms); uint testtag; string ignore; Assert.IsTrue(input.ReadTag(out testtag, out ignore)); Assert.AreEqual(tag, testtag); try { ByteString bytes = null; input.ReadBytes(ref bytes); Assert.Fail("Should have thrown an exception!"); } catch (InvalidProtocolBufferException) { // success. } }
public void ReadInvalidUtf8() { MemoryStream ms = new MemoryStream(); CodedOutputStream output = CodedOutputStream.CreateInstance(ms); uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); output.WriteRawVarint32(tag); output.WriteRawVarint32(1); output.WriteRawBytes(new byte[] { 0x80 }); output.Flush(); ms.Position = 0; CodedInputStream input = CodedInputStream.CreateInstance(ms); uint testtag; string ignored; Assert.IsTrue(input.ReadTag(out testtag, out ignored)); Assert.AreEqual(tag, testtag); string text = null; input.ReadString(ref text); Assert.AreEqual('\ufffd', text[0]); }
public void SkipWholeMessage() { TestAllTypes message = TestUtil.GetAllSet(); byte[] rawBytes = message.ToByteArray(); // Create two parallel inputs. Parse one as unknown fields while using // skipField() to skip each field on the other. Expect the same tags. CodedInputStream input1 = CodedInputStream.CreateInstance(rawBytes); CodedInputStream input2 = CodedInputStream.CreateInstance(rawBytes); UnknownFieldSet.Builder unknownFields = UnknownFieldSet.CreateBuilder(); uint tag; string name; while (input1.ReadTag(out tag, out name)) { uint tag2; Assert.IsTrue(input2.ReadTag(out tag2, out name)); Assert.AreEqual(tag, tag2); unknownFields.MergeFieldFrom(tag, input1); input2.SkipField(); } }
public IEnumerator <TMessage> GetEnumerator() { using (Stream stream = streamProvider()) { CodedInputStream input = CodedInputStream.CreateInstance(stream); input.SetSizeLimit(sizeLimit); uint tag; string name; while (input.ReadTag(out tag, out name)) { if ((tag == 0 && name == "item") || (tag == ExpectedTag)) { IBuilder builder = defaultMessageInstance.WeakCreateBuilderForType(); input.ReadMessage(builder, extensionRegistry); yield return((TMessage)builder.WeakBuild()); } else { throw InvalidProtocolBufferException.InvalidMessageStreamTag(); } input.ResetSizeCounter(); } } }
public void ReadMaliciouslyLargeBlob() { MemoryStream ms = new MemoryStream(); CodedOutputStream output = CodedOutputStream.CreateInstance(ms); uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); output.WriteRawVarint32(tag); output.WriteRawVarint32(0x7FFFFFFF); output.WriteRawBytes(new byte[32]); // Pad with a few random bytes. output.Flush(); ms.Position = 0; CodedInputStream input = CodedInputStream.CreateInstance(ms); uint testtag; string ignore; Assert.IsTrue(input.ReadTag(out testtag, out ignore)); Assert.AreEqual(tag, testtag); ByteString bytes = null; // TODO(jonskeet): Should this be ArgumentNullException instead? Assert.Throws <InvalidProtocolBufferException>(() => input.ReadBytes(ref bytes)); }
public void TestNegativeEnumArray() { int arraySize = 1 + 1 + (11 * 5); int msgSize = arraySize; byte[] bytes = new byte[msgSize]; CodedOutputStream output = CodedOutputStream.CreateInstance(bytes); output.WriteEnumArray(8, "", new int[] { 0, -1, -2, -3, -4, -5 }); Assert.AreEqual(0, output.SpaceLeft); CodedInputStream input = CodedInputStream.CreateInstance(bytes); uint tag; string name; Assert.IsTrue(input.ReadTag(out tag, out name)); List <int> values = new List <int>(); input.ReadInt32Array(tag, name, values); Assert.AreEqual(6, values.Count); for (int i = 0; i > -6; i--) { Assert.AreEqual(i, values[Math.Abs(i)]); } }
/// <summary> /// Parse an entire message from <paramref name="input"/> and merge /// its fields into this set. /// </summary> public Builder MergeFrom(CodedInputStream input) { while (true) { uint tag = input.ReadTag(); if (tag == 0 || !MergeFieldFrom(tag, input)) { break; } } return(this); }
public IEnumerator <TMessage> GetEnumerator() { using (Stream stream = streamProvider()) { CodedInputStream input = CodedInputStream.CreateInstance(stream); uint tag; while ((tag = input.ReadTag()) != 0) { if (tag != ExpectedTag) { throw InvalidProtocolBufferException.InvalidMessageStreamTag(); } yield return(messageReader(input, extensionRegistry)); } } }
private static void AssertFieldsInOrder(ByteString data) { CodedInputStream input = data.CreateCodedInput(); uint previousTag = 0; uint tag; string name; while (input.ReadTag(out tag, out name)) { Assert.IsTrue(tag > previousTag); previousTag = tag; input.SkipField(); } }
internal void MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder) { while (true) { uint tag = input.ReadTag(); if (tag == 0) { break; } if (!MergeFieldFrom(input, extensionRegistry, builder, tag)) { // end group tag break; } } }
private void AssertFieldsInOrder(ByteString data) { CodedInputStream input = data.CreateCodedInput(); uint previousTag = 0; while (true) { uint tag = input.ReadTag(); if (tag == 0) { break; } Assert.IsTrue(tag > previousTag); previousTag = tag; input.SkipField(tag); } }
/// <summary> /// Called by MergeFieldFrom to parse a MessageSet extension. /// </summary> private void MergeMessageSetExtensionFromCodedStream(CodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder) { MessageDescriptor type = builder.DescriptorForType; // The wire format for MessageSet is: // message MessageSet { // repeated group Item = 1 { // required int32 typeId = 2; // required bytes message = 3; // } // } // "typeId" is the extension's field number. The extension can only be // a message type, where "message" contains the encoded bytes of that // message. // // In practice, we will probably never see a MessageSet item in which // the message appears before the type ID, or where either field does not // appear exactly once. However, in theory such cases are valid, so we // should be prepared to accept them. int typeId = 0; ByteString rawBytes = null; // If we encounter "message" before "typeId" IBuilder subBuilder = null; FieldDescriptor field = null; while (true) { uint tag = input.ReadTag(); if (tag == 0) { break; } if (tag == WireFormat.MessageSetTag.TypeID) { typeId = input.ReadInt32(); // Zero is not a valid type ID. if (typeId != 0) { ExtensionInfo extension = extensionRegistry[type, typeId]; if (extension != null) { field = extension.Descriptor; subBuilder = extension.DefaultInstance.WeakCreateBuilderForType(); IMessage originalMessage = (IMessage)builder[field]; if (originalMessage != null) { subBuilder.WeakMergeFrom(originalMessage); } if (rawBytes != null) { // We already encountered the message. Parse it now. // TODO(jonskeet): Check this is okay. It's subtly different from the Java, as it doesn't create an input stream from rawBytes. // In fact, why don't we just call MergeFrom(rawBytes)? And what about the extension registry? subBuilder.WeakMergeFrom(rawBytes.CreateCodedInput()); rawBytes = null; } } else { // Unknown extension number. If we already saw data, put it // in rawBytes. if (rawBytes != null) { MergeField(typeId, UnknownField.CreateBuilder().AddLengthDelimited(rawBytes).Build()); rawBytes = null; } } } } else if (tag == WireFormat.MessageSetTag.Message) { if (typeId == 0) { // We haven't seen a type ID yet, so we have to store the raw bytes for now. rawBytes = input.ReadBytes(); } else if (subBuilder == null) { // We don't know how to parse this. Ignore it. MergeField(typeId, UnknownField.CreateBuilder().AddLengthDelimited(input.ReadBytes()).Build()); } else { // We already know the type, so we can parse directly from the input // with no copying. Hooray! input.ReadMessage(subBuilder, extensionRegistry); } } else { // Unknown tag. Skip it. if (!input.SkipField(tag)) { break; // end of group } } } input.CheckLastTagWas(WireFormat.MessageSetTag.ItemEnd); if (subBuilder != null) { builder[field] = subBuilder.WeakBuild(); } }
/// <summary> /// Parse an entire message from <paramref name="input"/> and merge /// its fields into this set. /// </summary> public Builder MergeFrom(CodedInputStream input) { while (true) { uint tag = input.ReadTag(); if (tag == 0 || !MergeFieldFrom(tag, input)) { break; } } return this; }
public void TestCodedInputOutputPosition() { byte[] content = new byte[110]; for (int i = 0; i < content.Length; i++) { content[i] = (byte)i; } byte[] child = new byte[120]; { MemoryStream ms = new MemoryStream(child); CodedOutputStream cout = CodedOutputStream.CreateInstance(ms, 20); // Field 11: numeric value: 500 cout.WriteTag(11, WireFormat.WireType.Varint); Assert.AreEqual(1, cout.Position); cout.WriteInt32NoTag(500); Assert.AreEqual(3, cout.Position); //Field 12: length delimited 120 bytes cout.WriteTag(12, WireFormat.WireType.LengthDelimited); Assert.AreEqual(4, cout.Position); cout.WriteBytesNoTag(ByteString.CopyFrom(content)); Assert.AreEqual(115, cout.Position); // Field 13: fixed numeric value: 501 cout.WriteTag(13, WireFormat.WireType.Fixed32); Assert.AreEqual(116, cout.Position); cout.WriteSFixed32NoTag(501); Assert.AreEqual(120, cout.Position); cout.Flush(); } byte[] bytes = new byte[130]; { CodedOutputStream cout = CodedOutputStream.CreateInstance(bytes); // Field 1: numeric value: 500 cout.WriteTag(1, WireFormat.WireType.Varint); Assert.AreEqual(1, cout.Position); cout.WriteInt32NoTag(500); Assert.AreEqual(3, cout.Position); //Field 2: length delimited 120 bytes cout.WriteTag(2, WireFormat.WireType.LengthDelimited); Assert.AreEqual(4, cout.Position); cout.WriteBytesNoTag(ByteString.CopyFrom(child)); Assert.AreEqual(125, cout.Position); // Field 3: fixed numeric value: 500 cout.WriteTag(3, WireFormat.WireType.Fixed32); Assert.AreEqual(126, cout.Position); cout.WriteSFixed32NoTag(501); Assert.AreEqual(130, cout.Position); cout.Flush(); } //Now test Input stream: { CodedInputStream cin = CodedInputStream.CreateInstance(new MemoryStream(bytes), new byte[50]); uint tag; int intValue = 0; string ignore; Assert.AreEqual(0, cin.Position); // Field 1: Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 1); Assert.AreEqual(1, cin.Position); Assert.IsTrue(cin.ReadInt32(ref intValue) && intValue == 500); Assert.AreEqual(3, cin.Position); //Field 2: Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 2); Assert.AreEqual(4, cin.Position); uint childlen = cin.ReadRawVarint32(); Assert.AreEqual(120u, childlen); Assert.AreEqual(5, cin.Position); int oldlimit = cin.PushLimit((int)childlen); Assert.AreEqual(5, cin.Position); // Now we are reading child message { // Field 11: numeric value: 500 Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 11); Assert.AreEqual(6, cin.Position); Assert.IsTrue(cin.ReadInt32(ref intValue) && intValue == 500); Assert.AreEqual(8, cin.Position); //Field 12: length delimited 120 bytes Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 12); Assert.AreEqual(9, cin.Position); ByteString bstr = null; Assert.IsTrue(cin.ReadBytes(ref bstr) && bstr.Length == 110 && bstr.ToByteArray()[109] == 109); Assert.AreEqual(120, cin.Position); // Field 13: fixed numeric value: 501 Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 13); // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit Assert.AreEqual(121, cin.Position); Assert.IsTrue(cin.ReadSFixed32(ref intValue) && intValue == 501); Assert.AreEqual(125, cin.Position); Assert.IsTrue(cin.IsAtEnd); } cin.PopLimit(oldlimit); Assert.AreEqual(125, cin.Position); // Field 3: fixed numeric value: 501 Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 3); Assert.AreEqual(126, cin.Position); Assert.IsTrue(cin.ReadSFixed32(ref intValue) && intValue == 501); Assert.AreEqual(130, cin.Position); Assert.IsTrue(cin.IsAtEnd); } }