如何判断 protobuf.net 中的反序列化是不是失败?

Posted

技术标签:

【中文标题】如何判断 protobuf.net 中的反序列化是不是失败?【英文标题】:How can I tell if Deserialization failed in protobuf.net?如何判断 protobuf.net 中的反序列化是否失败? 【发布时间】:2012-02-22 16:14:59 【问题描述】:

我让 protobuf.net 将无效(随机)字节反序列化为 KeyValuePair(即不可为空)。不是(如预期的那样)抛出异常,而是返回了一个空结构。

由于此默认结构可能是有效数据,因此我看不到判断源数据是否实际有效的方法。这是一个错误,还是我错过了什么?

(protobuf-net 2.0.0.480, 2011.12.11)

【问题讨论】:

【参考方案1】:

更新:

在 v2 中的某些情况下,它不会发现这一点,而是会终止,就好像它已经到达流的末尾 - 特别是如果“字段编号”在应用移位后为非正数。但是,这在 protobuf 流中无效有效,这将在下一次构建中修复。


这取决于它的随机性;p 实际上,让它在不抛出错误的情况下做任何事情是非常令人印象深刻的——protobuf 规范对布局非常具体,通常它抛出一个那里有很大的例外(可能提到“意外的线型”或类似的)。

强调:几乎在所有情况下它都会抛出异常。如果您对正确规范的某些数据进行了侥幸,但字段编号不同,那么它将默默地忽略意外数据,您将获得一个全零结构。如果您侥幸获得正确规范的一些数据,但使用正确的字段编号和布局,您将得到垃圾。但这就像在说

如果我随机生成恰好是"foo":"0" 的数据,javascriptSerializer 不会抱怨!!!错误!!!

确定你真的在这里反序列化了一些数据吗?并且流还不是EOF位置?例如,以下内容不会出错,因为您没有倒带流 - 您正在有效地反序列化零字节:

var ms = new MemoryStream();
ms.Write(randomBytes, 0, randomBytes.Length);
var obj = Serializer.Deserialize<Foo>(ms);

(零字节对 protobuf 对象完全有效)

如果您想测试流的有效性,可以使用ProtoReader,只是跳过(SkipField() 或类似的)每个字段,直到ReadNextHeader()(或其他)返回一个非正整数。

【讨论】:

本例中的“随机”输入是一个 XML 文件,所以我认为它应该是非常无效的。不过我会再检查一次,如果它没有抛出异常,那将是非常奇怪的。 @mafutrct 你成功复制了吗?如果你这样做,我会对一个例子非常感兴趣 我对它进行了更多尝试,只要输入足够长,显然反序列化不会对我产生影响。它只是返回默认值。 @mafutrct 这听起来与我所看到的一切都相反;你有具体的例子吗? 在另一台机器上重新安装 VS'10 进行了尝试,结果相同。我使用 protobuf-net.dll 作为反序列化的输入。

以上是关于如何判断 protobuf.net 中的反序列化是不是失败?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Protobuf .net 反序列化单个结构字段

protobuf -net 不知道如何序列化 type = object 的数据成员

如何使用 Protobuf.net C# 序列化自定义对象基础属性

列表的 Protobuf.net 对象图序列化

Protobuf.net 异常 - 检查元数据时超时

Protobuf-net - 啥被序列化了?