MakeTag() public static method

Makes a tag value given a field number and wire type.
public static MakeTag ( int fieldNumber, WireType wireType ) : uint
fieldNumber int
wireType WireType
return uint
        public void SkipGroup_WrongEndGroupTag()
        {
            // Create an output stream with:
            // Field 1: string "field 1"
            // Start group 2
            //   Field 3: fixed int32
            // End group 4 (should give an error)
            var stream = new MemoryStream();
            var output = new CodedOutputStream(stream);

            output.WriteTag(1, WireFormat.WireType.LengthDelimited);
            output.WriteString("field 1");

            // The outer group...
            output.WriteTag(2, WireFormat.WireType.StartGroup);
            output.WriteTag(3, WireFormat.WireType.Fixed32);
            output.WriteFixed32(100);
            output.WriteTag(4, WireFormat.WireType.EndGroup);
            output.Flush();
            stream.Position = 0;

            // Now act like a generated client
            var input = new CodedInputStream(stream);

            Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
            Assert.AreEqual("field 1", input.ReadString());
            Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
            Assert.Throws <InvalidProtocolBufferException>(input.SkipLastField);
        }
        public void ReadStringGreaterThanCurrentLimit()
        {
            MemoryStream      ms     = new MemoryStream();
            CodedOutputStream output = new CodedOutputStream(ms);
            uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);

            output.WriteRawVarint32(tag);
            output.WriteRawVarint32(4);
            output.WriteRawBytes(new byte[4]); // Pad with a few random bytes.
            output.Flush();
            ms.Position = 0;

            CodedInputStream input = new CodedInputStream(ms.ToArray());

            Assert.AreEqual(tag, input.ReadTag());

            // Specify limit smaller than data length
            input.PushLimit(3);
            Assert.Throws <InvalidProtocolBufferException>(() => input.ReadString());

            AssertReadFromParseContext(new ReadOnlySequence <byte>(ms.ToArray()), (ref ParseContext ctx) =>
            {
                Assert.AreEqual(tag, ctx.ReadTag());
                SegmentedBufferHelper.PushLimit(ref ctx.state, 3);
                try
                {
                    ctx.ReadString();
                    Assert.Fail();
                }
                catch (InvalidProtocolBufferException) { }
            }, true);
        }
Beispiel #3
0
        /// <summary>
        /// Parse a single field from <paramref name="input"/> and merge it
        /// into this set.
        /// </summary>
        /// <param name="input">The coded input stream containing the field</param>
        /// <returns>false if the tag is an "end group" tag, true otherwise</returns>
        private bool MergeFieldFrom(CodedInputStream input)
        {
            uint tag    = input.LastTag;
            int  number = WireFormat.GetTagFieldNumber(tag);

            switch (WireFormat.GetTagWireType(tag))
            {
            case WireFormat.WireType.Varint:
            {
                ulong uint64 = input.ReadUInt64();
                GetOrAddField(number).AddVarint(uint64);
                return(true);
            }

            case WireFormat.WireType.Fixed32:
            {
                uint uint32 = input.ReadFixed32();
                GetOrAddField(number).AddFixed32(uint32);
                return(true);
            }

            case WireFormat.WireType.Fixed64:
            {
                ulong uint64 = input.ReadFixed64();
                GetOrAddField(number).AddFixed64(uint64);
                return(true);
            }

            case WireFormat.WireType.LengthDelimited:
            {
                ByteString bytes = input.ReadBytes();
                GetOrAddField(number).AddLengthDelimited(bytes);
                return(true);
            }

            case WireFormat.WireType.StartGroup:
            {
                uint            endTag = WireFormat.MakeTag(number, WireFormat.WireType.EndGroup);
                UnknownFieldSet set    = new UnknownFieldSet();
                while (input.ReadTag() != endTag)
                {
                    set.MergeFieldFrom(input);
                }
                GetOrAddField(number).AddGroup(set);
                return(true);
            }

            case WireFormat.WireType.EndGroup:
            {
                return(false);
            }

            default:
                throw InvalidProtocolBufferException.InvalidWireType();
            }
        }
        public static void ReadGroup(ref ParseContext ctx, int fieldNumber, UnknownFieldSet set)
        {
            if (ctx.state.recursionDepth >= ctx.state.recursionLimit)
            {
                throw InvalidProtocolBufferException.RecursionLimitExceeded();
            }
            ++ctx.state.recursionDepth;

            set.MergeGroupFrom(ref ctx);
            CheckLastTagWas(ref ctx.state, WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));

            --ctx.state.recursionDepth;
        }
        public void ReadGroup_UnknownFields_WrongEndGroupTag()
        {
            MemoryStream      ms     = new MemoryStream();
            CodedOutputStream output = new CodedOutputStream(ms);

            output.WriteTag(WireFormat.MakeTag(14, WireFormat.WireType.StartGroup));
            // end group with different field number
            output.WriteTag(WireFormat.MakeTag(15, WireFormat.WireType.EndGroup));
            output.Flush();
            var payload = ms.ToArray();

            Assert.Throws <InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(payload));
        }
        public static void ReadGroup(ref ParseContext ctx, IMessage message)
        {
            if (ctx.state.recursionDepth >= ctx.state.recursionLimit)
            {
                throw InvalidProtocolBufferException.RecursionLimitExceeded();
            }
            ++ctx.state.recursionDepth;

            uint tag         = ctx.state.lastTag;
            int  fieldNumber = WireFormat.GetTagFieldNumber(tag);

            ReadRawMessage(ref ctx, message);
            CheckLastTagWas(ref ctx.state, WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));

            --ctx.state.recursionDepth;
        }
        public void SkipGroup()
        {
            // Create an output stream with a group in:
            // Field 1: string "field 1"
            // Field 2: group containing:
            //   Field 1: fixed int32 value 100
            //   Field 2: string "ignore me"
            //   Field 3: nested group containing
            //      Field 1: fixed int64 value 1000
            // Field 3: string "field 3"
            var stream = new MemoryStream();
            var output = new CodedOutputStream(stream);

            output.WriteTag(1, WireFormat.WireType.LengthDelimited);
            output.WriteString("field 1");

            // The outer group...
            output.WriteTag(2, WireFormat.WireType.StartGroup);
            output.WriteTag(1, WireFormat.WireType.Fixed32);
            output.WriteFixed32(100);
            output.WriteTag(2, WireFormat.WireType.LengthDelimited);
            output.WriteString("ignore me");
            // The nested group...
            output.WriteTag(3, WireFormat.WireType.StartGroup);
            output.WriteTag(1, WireFormat.WireType.Fixed64);
            output.WriteFixed64(1000);
            // Note: Not sure the field number is relevant for end group...
            output.WriteTag(3, WireFormat.WireType.EndGroup);

            // End the outer group
            output.WriteTag(2, WireFormat.WireType.EndGroup);

            output.WriteTag(3, WireFormat.WireType.LengthDelimited);
            output.WriteString("field 3");
            output.Flush();
            stream.Position = 0;

            // Now act like a generated client
            var input = new CodedInputStream(stream);

            Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
            Assert.AreEqual("field 1", input.ReadString());
            Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
            input.SkipLastField(); // Should consume the whole group, including the nested one.
            Assert.AreEqual(WireFormat.MakeTag(3, WireFormat.WireType.LengthDelimited), input.ReadTag());
            Assert.AreEqual("field 3", input.ReadString());
        }
        public void ReadNegativeSizedBytesThrowsInvalidProtocolBufferException()
        {
            MemoryStream      ms     = new MemoryStream();
            CodedOutputStream output = new CodedOutputStream(ms);

            uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);

            output.WriteRawVarint32(tag);
            output.WriteLength(-1);
            output.Flush();
            ms.Position = 0;

            CodedInputStream input = new CodedInputStream(ms);

            Assert.AreEqual(tag, input.ReadTag());
            Assert.Throws <InvalidProtocolBufferException>(() => input.ReadBytes());
        }
        public void RogueEndGroupTag()
        {
            // If we have an end-group tag without a leading start-group tag, generated
            // code will just call SkipLastField... so that should fail.

            var stream = new MemoryStream();
            var output = new CodedOutputStream(stream);

            output.WriteTag(1, WireFormat.WireType.EndGroup);
            output.Flush();
            stream.Position = 0;

            var input = new CodedInputStream(stream);

            Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.EndGroup), input.ReadTag());
            Assert.Throws <InvalidProtocolBufferException>(input.SkipLastField);
        }
        private static byte[] MakeMaliciousRecursionUnknownFieldsPayload(int recursionDepth)
        {
            // generate recursively nested groups that will be parsed as unknown fields
            int               unknownFieldNumber = 14; // an unused field number
            MemoryStream      ms     = new MemoryStream();
            CodedOutputStream output = new CodedOutputStream(ms);

            for (int i = 0; i < recursionDepth; i++)
            {
                output.WriteTag(WireFormat.MakeTag(unknownFieldNumber, WireFormat.WireType.StartGroup));
            }
            for (int i = 0; i < recursionDepth; i++)
            {
                output.WriteTag(WireFormat.MakeTag(unknownFieldNumber, WireFormat.WireType.EndGroup));
            }
            output.Flush();
            return(ms.ToArray());
        }
Beispiel #11
0
        public void MaximumFieldNumber()
        {
            MemoryStream      ms     = new MemoryStream();
            CodedOutputStream output = new CodedOutputStream(ms);

            int  fieldNumber = 0x1FFFFFFF;
            uint tag         = WireFormat.MakeTag(fieldNumber, WireFormat.WireType.LengthDelimited);

            output.WriteRawVarint32(tag);
            output.WriteString("field 1");
            output.Flush();
            ms.Position = 0;

            CodedInputStream input = new CodedInputStream(ms);

            Assert.AreEqual(tag, input.ReadTag());
            Assert.AreEqual(fieldNumber, WireFormat.GetTagFieldNumber(tag));
        }
        public void TestReadInvalidWireTypeThrowsInvalidProtocolBufferException()
        {
            MemoryStream      ms     = new MemoryStream();
            CodedOutputStream output = new CodedOutputStream(ms);

            uint tag = WireFormat.MakeTag(1, (WireFormat.WireType) 6);

            output.WriteRawVarint32(tag);
            output.WriteLength(-1);
            output.Flush();
            ms.Position = 0;

            CodedInputStream input = new CodedInputStream(ms);

            Assert.AreEqual(tag, input.ReadTag());

            Assert.Throws <InvalidProtocolBufferException>(() => UnknownFieldSet.MergeFieldFrom(null, input));
        }
        public void ReadGroup_WrongEndGroupTag()
        {
            int groupFieldNumber = Proto2.TestAllTypes.OptionalGroupFieldNumber;

            // write Proto2.TestAllTypes with "optional_group" set, but use wrong EndGroup closing tag
            MemoryStream      ms     = new MemoryStream();
            CodedOutputStream output = new CodedOutputStream(ms);

            output.WriteTag(WireFormat.MakeTag(groupFieldNumber, WireFormat.WireType.StartGroup));
            output.WriteGroup(new Proto2.TestAllTypes.Types.OptionalGroup {
                A = 12345
            });
            // end group with different field number
            output.WriteTag(WireFormat.MakeTag(groupFieldNumber + 1, WireFormat.WireType.EndGroup));
            output.Flush();
            var payload = ms.ToArray();

            Assert.Throws <InvalidProtocolBufferException>(() => Proto2.TestAllTypes.Parser.ParseFrom(payload));
        }
        public void ReadMaliciouslyLargeBlob()
        {
            MemoryStream      ms     = new MemoryStream();
            CodedOutputStream output = new CodedOutputStream(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 = new CodedInputStream(ms);

            Assert.AreEqual(tag, input.ReadTag());

            Assert.Throws <InvalidProtocolBufferException>(() => input.ReadBytes());
        }
Beispiel #15
0
        public void CodedInputStream_LimitReachedRightAfterTag()
        {
            MemoryStream ms  = new MemoryStream();
            var          cos = new CodedOutputStream(ms);

            cos.WriteTag(11, WireFormat.WireType.Varint);
            Assert.AreEqual(1, cos.Position);
            cos.WriteString("some extra padding");  // ensure is currentLimit distinct from the end of the buffer.
            cos.Flush();

            var cis = new CodedInputStream(ms.ToArray());

            cis.PushLimit(1);  // make sure we reach the limit right after reading the tag.

            // we still must read the tag correctly, even though the tag is at the very end of our limited input
            // (which is a corner case and will most likely result in an error when trying to read value of the field
            // described by this tag, but it would be a logical error not to read the tag that's actually present).
            // See https://github.com/protocolbuffers/protobuf/pull/7289
            cis.AssertNextTag(WireFormat.MakeTag(11, WireFormat.WireType.Varint));
        }
        public void ReadInvalidUtf8()
        {
            MemoryStream      ms     = new MemoryStream();
            CodedOutputStream output = new CodedOutputStream(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 = new CodedInputStream(ms);

            Assert.AreEqual(tag, input.ReadTag());
            string text = input.ReadString();

            Assert.AreEqual('\ufffd', text[0]);
        }
        public void RecursionLimitAppliedWhileSkippingGroup()
        {
            var stream = new MemoryStream();
            var output = new CodedOutputStream(stream);

            for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
            {
                output.WriteTag(1, WireFormat.WireType.StartGroup);
            }
            for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
            {
                output.WriteTag(1, WireFormat.WireType.EndGroup);
            }
            output.Flush();
            stream.Position = 0;

            // Now act like a generated client
            var input = new CodedInputStream(stream);

            Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.StartGroup), input.ReadTag());
            Assert.Throws <InvalidProtocolBufferException>(input.SkipLastField);
        }
        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;

            Assert.IsTrue(input.ReadTag(out testtag));
            Assert.AreEqual(tag, testtag);

            // TODO(jonskeet): Should this be ArgumentNullException instead?
            Assert.Throws <InvalidProtocolBufferException>(() => input.ReadBytes());
        }
Beispiel #19
0
 /// <summary>
 /// Encodes and writes a tag.
 /// </summary>
 /// <param name="fieldNumber">The number of the field to write the tag for</param>
 /// <param name="type">The wire format type of the tag to write</param>
 public void WriteTag(int fieldNumber, WireFormat.WireType type)
 {
     WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type));
 }
 /// <summary>
 /// Computes the number of bytes that would be needed to encode a tag.
 /// </summary>
 public static int ComputeTagSize(int fieldNumber)
 {
     return(ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, 0)));
 }
Beispiel #21
0
 public static int ComputeTagSize(int fieldNumber)
 {
     return(CodedOutputStream.ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.Varint)));
 }
 /// <summary>
 /// Encodes and writes a tag.
 /// </summary>
 public static void WriteTag(ref Span <byte> buffer, ref WriterInternalState state, int fieldNumber, WireFormat.WireType type)
 {
     WriteRawVarint32(ref buffer, ref state, WireFormat.MakeTag(fieldNumber, type));
 }