示例#1
0
        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]);
        }
示例#2
0
        public bool SkipField()
        {
            uint tag = this.lastTag;

            switch (WireFormat.GetTagWireType(tag))
            {
            case WireFormat.WireType.Varint:
                this.ReadRawVarint64();
                return(true);

            case WireFormat.WireType.Fixed64:
                this.ReadRawLittleEndian64();
                return(true);

            case WireFormat.WireType.LengthDelimited:
                this.SkipRawBytes((int)this.ReadRawVarint32());
                return(true);

            case WireFormat.WireType.StartGroup:
                this.SkipMessage();
                this.CheckLastTagWas(WireFormat.MakeTag(WireFormat.GetTagFieldNumber(tag), WireFormat.WireType.EndGroup));
                return(true);

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

            case WireFormat.WireType.Fixed32:
                this.ReadRawLittleEndian32();
                return(true);

            default:
                throw InvalidProtocolBufferException.InvalidWireType();
            }
        }
示例#3
0
        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.
            }
        }
示例#4
0
        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));
        }
示例#5
0
 public void ReadUnknownGroup(int fieldNumber, IBuilderLite builder)
 {
     if (this.recursionDepth >= this.recursionLimit)
     {
         throw InvalidProtocolBufferException.RecursionLimitExceeded();
     }
     this.recursionDepth++;
     builder.WeakMergeFrom(this);
     this.CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
     this.recursionDepth--;
 }
示例#6
0
 /// <summary>
 /// Reads a group field value from the stream and merges it into the given
 /// UnknownFieldSet.
 /// </summary>
 public void ReadUnknownGroup(int fieldNumber, UnknownFieldSet.Builder builder)
 {
     if (recursionDepth >= recursionLimit)
     {
         throw InvalidProtocolBufferException.RecursionLimitExceeded();
     }
     ++recursionDepth;
     builder.MergeFrom(this);
     CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
     --recursionDepth;
 }
示例#7
0
 /// <summary>
 /// Reads a group field value from the stream.
 /// </summary>
 public void ReadGroup(int fieldNumber, IBuilderLite builder,
                       ExtensionRegistry extensionRegistry)
 {
     if (recursionDepth >= recursionLimit)
     {
         throw InvalidProtocolBufferException.RecursionLimitExceeded();
     }
     ++recursionDepth;
     builder.WeakMergeFrom(this, extensionRegistry);
     CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
     --recursionDepth;
 }
示例#8
0
            internal void MergeFrom(ICodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder)
            {
                uint   tag;
                string name;

                while (input.ReadTag(out tag, out name))
                {
                    if (tag == 0 && name != null)
                    {
                        FieldDescriptor fieldByName = builder.DescriptorForType.FindFieldByName(name);
                        if (fieldByName != null)
                        {
                            tag = WireFormat.MakeTag(fieldByName);
                        }
                        else
                        {
                            ExtensionInfo extension = extensionRegistry.FindByName(builder.DescriptorForType, name);
                            if (extension != null)
                            {
                                tag = WireFormat.MakeTag(extension.Descriptor);
                            }
                        }
                    }
                    if (tag == 0)
                    {
                        if (input.SkipField())
                        {
                            continue; //can't merge unknown without field tag
                        }
                        break;
                    }

                    if (!MergeFieldFrom(input, extensionRegistry, builder, tag, name))
                    {
                        // end group tag
                        break;
                    }
                }
            }
示例#9
0
            /// <summary>
            /// Like <see cref="MergeFrom(ICodedInputStream, ExtensionRegistry, IBuilder)" />
            /// but parses a single field.
            /// </summary>
            /// <param name="input">The input to read the field from</param>
            /// <param name="extensionRegistry">Registry to use when an extension field is encountered</param>
            /// <param name="builder">Builder to merge field into, if it's a known field</param>
            /// <param name="tag">The tag, which should already have been read from the input</param>
            /// <returns>true unless the tag is an end-group tag</returns>
            internal bool MergeFieldFrom(ICodedInputStream input,
                                         ExtensionRegistry extensionRegistry, IBuilder builder, uint tag,
                                         string fieldName)
            {
                if (tag == 0 && fieldName != null)
                {
                    FieldDescriptor fieldByName = builder.DescriptorForType.FindFieldByName(fieldName);
                    if (fieldByName != null)
                    {
                        tag = WireFormat.MakeTag(fieldByName);
                    }
                    else
                    {
                        ExtensionInfo extension = extensionRegistry.FindByName(builder.DescriptorForType, fieldName);
                        if (extension != null)
                        {
                            tag = WireFormat.MakeTag(extension.Descriptor);
                        }
                    }
                }

                MessageDescriptor type = builder.DescriptorForType;

                if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart)
                {
                    MergeMessageSetExtensionFromCodedStream(input, extensionRegistry, builder);
                    return(true);
                }

                WireFormat.WireType wireType = WireFormat.GetTagWireType(tag);
                int fieldNumber = WireFormat.GetTagFieldNumber(tag);

                FieldDescriptor field;
                IMessageLite    defaultFieldInstance = null;

                if (type.IsExtensionNumber(fieldNumber))
                {
                    ExtensionInfo extension = extensionRegistry[type, fieldNumber];
                    if (extension == null)
                    {
                        field = null;
                    }
                    else
                    {
                        field = extension.Descriptor;
                        defaultFieldInstance = extension.DefaultInstance;
                    }
                }
                else
                {
                    field = type.FindFieldByNumber(fieldNumber);
                }

                // Unknown field or wrong wire type. Skip.
                if (field == null)
                {
                    return(MergeFieldFrom(tag, input));
                }
                if (wireType != WireFormat.GetWireType(field))
                {
                    WireFormat.WireType expectedType = WireFormat.GetWireType(field.FieldType);
                    if (wireType == expectedType)
                    {
                        //Allowed as of 2.3, this is unpacked data for a packed array
                    }
                    else if (field.IsRepeated && wireType == WireFormat.WireType.LengthDelimited &&
                             (expectedType == WireFormat.WireType.Varint || expectedType == WireFormat.WireType.Fixed32 ||
                              expectedType == WireFormat.WireType.Fixed64))
                    {
                        //Allowed as of 2.3, this is packed data for an unpacked array
                    }
                    else
                    {
                        return(MergeFieldFrom(tag, input));
                    }
                }

                switch (field.FieldType)
                {
                case FieldType.Group:
                case FieldType.Message:
                {
                    IBuilderLite subBuilder = (defaultFieldInstance != null)
                                                          ? defaultFieldInstance.WeakCreateBuilderForType()
                                                          : builder.CreateBuilderForField(field);
                    if (!field.IsRepeated)
                    {
                        subBuilder.WeakMergeFrom((IMessageLite)builder[field]);
                        if (field.FieldType == FieldType.Group)
                        {
                            input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);
                        }
                        else
                        {
                            input.ReadMessage(subBuilder, extensionRegistry);
                        }
                        builder[field] = subBuilder.WeakBuild();
                    }
                    else
                    {
                        List <IMessageLite> list = new List <IMessageLite>();
                        if (field.FieldType == FieldType.Group)
                        {
                            input.ReadGroupArray(tag, fieldName, list, subBuilder.WeakDefaultInstanceForType,
                                                 extensionRegistry);
                        }
                        else
                        {
                            input.ReadMessageArray(tag, fieldName, list, subBuilder.WeakDefaultInstanceForType,
                                                   extensionRegistry);
                        }

                        foreach (IMessageLite m in list)
                        {
                            builder.WeakAddRepeatedField(field, m);
                        }
                        return(true);
                    }
                    break;
                }

                case FieldType.Enum:
                {
                    if (!field.IsRepeated)
                    {
                        object    unknown;
                        IEnumLite value = null;
                        if (input.ReadEnum(ref value, out unknown, field.EnumType))
                        {
                            builder[field] = value;
                        }
                        else if (unknown is int)
                        {
                            MergeVarintField(fieldNumber, (ulong)(int)unknown);
                        }
                    }
                    else
                    {
                        ICollection <object> unknown;
                        List <IEnumLite>     list = new List <IEnumLite>();
                        input.ReadEnumArray(tag, fieldName, list, out unknown, field.EnumType);

                        foreach (IEnumLite en in list)
                        {
                            builder.WeakAddRepeatedField(field, en);
                        }

                        if (unknown != null)
                        {
                            foreach (object oval in unknown)
                            {
                                if (oval is int)
                                {
                                    MergeVarintField(fieldNumber, (ulong)(int)oval);
                                }
                            }
                        }
                    }
                    break;
                }

                default:
                {
                    if (!field.IsRepeated)
                    {
                        object value = null;
                        if (input.ReadPrimitiveField(field.FieldType, ref value))
                        {
                            builder[field] = value;
                        }
                    }
                    else
                    {
                        List <object> list = new List <object>();
                        input.ReadPrimitiveArray(field.FieldType, tag, fieldName, list);
                        foreach (object oval in list)
                        {
                            builder.WeakAddRepeatedField(field, oval);
                        }
                    }
                    break;
                }
                }
                return(true);
            }
 /// <summary>
 /// Compute 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)));
 }
示例#11
0
 /// <summary>
 /// Encodes and writes a tag.
 /// </summary>
 public void WriteTag(int fieldNumber, WireFormat.WireType type)
 {
     WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type));
 }