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

时间:2012-02-22 16:14:59

标签: deserialization protobuf-net data-integrity

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

由于这个默认结构可能是有效数据,因此我没有办法判断源数据是否实际有效。这是一个错误,还是有一种方法我错过了?

(protobuf-net 2.0.0.480,2011.12.11)

1 个答案:

答案 0 :(得分: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()(或其他)返回非正整数。