【问题标题】:protocol buffers ParseFromString does not check end of message协议缓冲区 ParseFromString 不检查消息的结尾
【发布时间】:2019-01-04 20:22:47
【问题描述】:

我发现了一个关于协议缓冲区的有趣问题。如果您有两条相似的消息,则可以使用 C++ API 或命令行来解析一条,就好像它是另一条一样。

limited documentation for ParseFromString 没有提到它不需要消耗所有字符串,如果不消耗也不会失败。

我曾预计 ParseFromString 无法解析 A 类型的消息,如果它与 B 类型的消息一起呈现。毕竟该消息包含额外的数据。然而,这种情况并非如此。 一个示例脚本演示了这个问题:

#!/bin/sh

cat - >./foobar.proto <<EOF
syntax = "proto3";
package demo;
message A
{
   uint64 foo = 1;
};

enum flagx { 
  y = 0; 
  z = 1; 
}

message B {
   uint64 foolish = 1;
   flagx bar = 2;
};

EOF

cat - >./mess.B.in.txtfmt <<EOF
foolish: 10
bar: y
EOF

cat - >./mess.in.txtfmt <<EOF
foo: 10
EOF

protoc --encode=demo.A foobar.proto <./mess.A.in.txtfmt >./mess.A.proto
protoc --encode=demo.B foobar.proto <./mess.B.in.txtfmt >./mess.B.proto
protoc --decode=demo.A foobar.proto >./mess.out.txtfmt <./mess.B.proto

echo "in: "
cat mess.B.in.txtfmt
echo "out: "
cat mess.out.txtfmt

echo "xxd mess.A.proto:"
xxd mess.A.proto

echo "xxd mess.B.proto:"
xxd mess.B.proto

输出是:

in: 
foolish: 10
bar: 20
out: 
foo: 10
xxd mess.A.proto:
00000000: 080a                                    
xxd mess.B.proto:
00000000: 080a

所以消息 A 和 B 的二进制消息是相同的。

如果您更改协议,以便使用另一个 varint (uint64) 而不是枚举,您将获得不同的二进制消息,但 ParseFromString 仍然会成功地将较长的消息解析为较短的消息。

为了真正混淆事物,它似乎也能够将较短的消息解析为较长的消息。

这是错误还是功能?

【问题讨论】:

    标签: c++ protocol-buffers


    【解决方案1】:

    我认为这是设计使然,但文档可能会更好。

    如果您尝试使用 API 而不首先阅读有关无线格式的信息,则可能会出现这种混淆。如您所料,有线格式与 API 无关。

    有线格式强调紧凑性而不是正确性。如果您想检查消息的正确性,请使用其他方式。

    您可能(可以说应该或必须)在您的信息中包含以下一项或多项:

    • 消息类型字段
    • 消息长度字段
    • 校验和

    关于能够将较短消息解析为较长消息的第二点是因为在协议缓冲区 3 中所有字段都是可选的。 协议缓冲区 2 有一个必填字段的概念。它的删除引起了一些争议(例如参见Why required and optional is removed in Protocol Buffers 3https://capnproto.org/faq.html#how-do-i-make-a-field-required-like-in-protocol-buffers)。 消息中不包含具有默认值(通常为 0)的字段。字段的名称也被数字替换。因此,“不同”协议的两条消息可能很容易被双方解释。

    【讨论】:

    • 注意:如果有人有更好的答案,请加入。如果一段时间后没有人回复,我会将其设为社区 wiki
    猜你喜欢
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    相关资源
    最近更新 更多