protobuf-net反序列化:;算术运算导致溢出&”;

本文关键字:溢出 算术运算 反序列化 protobuf-net | 更新日期: 2023-09-27 17:58:11

我正在使用protobuf-net来序列化/取消序列化我的模型。

我的模型相当简单,序列化似乎一直有效,但如果我稍后向模型反序列化添加特定类型,则似乎会失败。

一旦我在模型中添加"int"、"long"或"DateTime",就会出现"算术运算导致溢出"异常。

型号:

[ProtoContract]
public class MyModel
{
    [ProtoMember(1)]
    public DateTime Time { get; set; }
    [ProtoMember(2)]
    public List<string> SomeList { get; set; }
    [ProtoMember(3)]
    public string Key { get; set; }
    [ProtoMember(4)]
    public string Value { get; set; }
}

当我删除"时间"属性时,它似乎总是有效的。

例外:

 at ProtoBuf.ProtoReader.TryReadUInt64VariantWithoutMoving(UInt64& value) in c:'Dev'protobuf-net'protobuf-net'ProtoReader.cs:line 375
   at ProtoBuf.ProtoReader.ReadInt64() in c:'Dev'protobuf-net'protobuf-net'ProtoReader.cs:line 357
   at ProtoBuf.BclHelpers.ReadTimeSpanTicks(ProtoReader source) in c:'Dev'protobuf-net'protobuf-net'BclHelpers.cs:line 191
   at ProtoBuf.Serializers.DateTimeSerializer.Read(Object value, ProtoReader source) in c:'Dev'protobuf-net'protobuf-net'Serializers'DateTimeSerializer.cs:line 35
   at ProtoBuf.Serializers.PropertyDecorator.Read(Object value, ProtoReader source) in c:'Dev'protobuf-net'protobuf-net'Serializers'PropertyDecorator.cs:line 77
   at ProtoBuf.Serializers.TypeSerializer.Read(Object value, ProtoReader source) in c:'Dev'protobuf-net'protobuf-net'Serializers'TypeSerializer.cs:line 230
   at ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, Object value, Boolean noAutoCreate) in c:'Dev'protobuf-net'protobuf-net'Meta'TypeModel.cs:line 700
   at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) in c:'Dev'protobuf-net'protobuf-net'Meta'TypeModel.cs:line 589
   at ProtoBuf.Serializer.Deserialize[T](Stream source) in c:'Dev'protobuf-net'protobuf-net'Serializer.cs:line 77

我做错什么了吗?

[编辑]

private static void Main(string[] args)
        {
            var proto = new SerializeProtoTest();
            var model = new MyModel
                            {
                                Key = "abc",
                                SomeList = new List<string> { "cde" },
                                Time = DateTime.UtcNow,
                                Value = "something"
                            };
            var s = proto.Serialize(model);
            var d = proto.Deserialize<MyModel>(s);
            Console.ReadKey();
        }
        [ProtoContract]
        public class MyModel
        {
            [ProtoMember(3)]
            public string Key { get; set; }
            [ProtoMember(2)]
            public List<string> SomeList { get; set; }
            [ProtoMember(1)]
            public DateTime Time { get; set; }
            [ProtoMember(4)]
            public string Value { get; set; }
        }
        public class SerializeProtoTest
        {
            public T Deserialize<T>(string value)
            {
                using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(value)))
                {
                    return Serializer.Deserialize<T>(ms);
                }
            }
            public string Serialize<T>(T obj)
            {
                using (var ms = new MemoryStream())
                {
                    Serializer.Serialize(ms, obj);
                    var buffer = ms.ToArray();
                    return Encoding.UTF8.GetString(buffer, 0, buffer.Length);
                }
            }
        }
    }

protobuf-net反序列化:;算术运算导致溢出&”;

来自注释:

最有可能的是:编码不当

叫它!(来自您的编辑)

return编码。UTF8.GetString(缓冲区,0,缓冲区长度);

protobuf数据不是文本。您不能使用文本编码来获得它的文本表示-事实上,您正在向后使用此文本编码,并且它在这里没有定义的行为。您已损坏数据。这里有一篇更大的综述(因为我经常看到)(第一部分)。

然而,简短的说法是:不要那样做。如果您需要string,请使用base-64或类似产品:

var buffer = ms.GetBuffer();
return Convert.ToBase64String(buffer, 0, (int)ms.Length);

(同样,使用Convert.FromBase64String来反转此过程)

然而,如果可能的话,最好简单地避免绕过string的需要。CCD_ 4将正常工作(即return ms.ToArray())。