您使用什么版本的 protobuf 以及什么语言? 最新的:
> protoc --version
libprotoc 3.19.1
什么操作系统(Linux、Windows...)和版本?
操作系统 X 11.6.1
您使用什么运行时/编译器(例如,python 版本或 gcc 版本)
不适用
你做了什么?
我编译了一个包含无效二进制数据的文件。虽然规范没有规定源代码应该采用 UTF-8 编码,但 GitHub 中的这个问题表明这是正确的:#1418。 (注意:为了清楚起见,确实应该更新文档以明确说明这一点。)
为了使源成为有效的可编译源,我将其放入类型为 的选项的字符串文字中string
。我实际上创建了两个在语义上等效的文件:
// tmp.proto
syntax = "proto3";
package foo;
option java_outer_classname= "my?value";
上面的问号实际上是二进制值0xbc
。要使用此示例文件的二进制数据,您可以使用xxd -r
以下命令:
00000000: 7379 6e74 6178 203d 2022 7072 6f74 6f33 syntax = "proto3
00000010: 223b 0a0a 7061 636b 6167 6520 666f 6f3b ";..package foo;
00000020: 0a0a 6f70 7469 6f6e 206a 6176 615f 6f75 ..option java_ou
00000030: 7465 725f 636c 6173 736e 616d 653d 2022 ter_classname= "
00000040: 6d79 bc76 616c 7565 223b 0a my.value";.
第二个文件使用转义序列:
// tmp2.proto
syntax = "proto3";
package foo;
option java_outer_classname= "my\xbcvalue";
因此tmp.proto
在源中包含无效的 UTF8 输入。并tmp2.proto
在源中包含有效的 UTF8,但它定义了一个具有无效 UTF8 数据的字符串常量。
我只是将文件编译为描述符集:
protoc -o tmp.protoset tmp.proto
protoc -o tmp2.protoset tmp2.proto
你期望看到什么
我期望protoc
:
- 使用UTF 替换字符替换无效数据 � (U+FFFD)
- 或者抱怨输入的 UTF-8 格式不正确。
对于第一个文件,它应该抱怨源程序本身的输入。
对于第二个文件,它应该抱怨字符串选项的值不是有效输入(因为根据文档 ,字符串预计为 UTF-8 或 7 位 ASCII )。
你看到了什么?
这两个文件都编译成功。除了文件名之外,它们还生成相同的描述符:
> protoc --decode google.protobuf.FileDescriptorSet google/protobuf/descriptor.proto < tmp.protoset
file {
name: "tmp.proto"
package: "foo"
options {
java_outer_classname: "my\274value"
}
syntax: "proto3"
}
是\274
转义字节,而不是 unicode point 0xbc
。这不是有效的 UTF8,但该java_outer_classname
选项定义为 type string
。