pbc
pbc copied to clipboard
有个optional int32 相关的 bug
optional int32 的字段如果赋值为0, encode 的时候好像没有把这个字段encode 进去, decode的时候也没有应字段的值
这是一个特性
发自我的 iPad
在 2014年12月30日,下午4:59,eligo [email protected] 写道:
optional int32 的字段如果赋值为0, encode 的时候好像没有把这个字段encode 进去, decode的时候也没有应字段的值
— Reply to this email directly or view it on GitHub.
这是个问题额....
在嵌套的协议上面,这是个比较严重的问题额~
message msgone { optional int32 msg1aid = 1; optional int32 msg1bid = 2; optional int32 msg1cid = 3; } message msgtwo { optional int32 msg2aid = 1; optional int32 msg2bid = 2; optional int32 msg2cid = 3; repeated msgthree msgthreeAry = 4; } message msgthree { optional int32 msg3aid = 1; optional int32 msg3bid = 2; optional int32 msg3cid = 3; }
message request6789 { optional int32 pid = 1; optional int32 arg1 = 2; repeated msgone argOneArray = 3; optional msgtwo argTwo = 4; }
如果message msgtwo这里的msgthreeAry里放的是0值的msgthree, 这样msgthree会被忽略掉,但是msgthreeAry的数组,业务上是认为有这个数据的
最后就会导致另一端解析出错。
所以应该是个BUG,而不是特性
在 repeated 里,msgthree 并不会被忽略。只有 optional 的才会。
我填数据测试,将repeated msgthree msgthreeAry 里的msgthree3个值都设置为0,这时候会被忽略掉。 local msgone_arg={} for i=1,3 do local msgtOne ={} msgtOne.msg1aid =1 msgtOne.msg1bid =1 msgtOne.msg1cid =1 msgone_arg[#msgone_arg+1]=msgtOne
end
local msgthreeAry ={} for i=1,3 do local msgthree ={} msgthree.msg3aid=0 --这里设置为0 msgthree.msg3bid=0 --这里设置为0 msgthree.msg3cid=0 --这里设置为0 msgthreeAry[#msgthreeAry+1]=msgthree end
local argTwo_arg ={} argTwo_arg.msg2aid=2 argTwo_arg.msg2bid=2 argTwo_arg.msg2cid=2 argTwo_arg.msgthreeAry = msgthreeAry
local tabPak={ arg1 = 100, argOneArray = msgone_arg, argTwo = argTwo_arg, }
应该说repeated标记msgthreeAry不会被忽略,但是因为它的元素是optional int32的,会被忽略掉
就是导致有数组,但是没有数据,从而在另外一端java解析的时候会解析出错。
是在哪里忽略的?能告诉个范围位置,然后我去掉这个特性试试不?
这是bug, 因为这样做跟其他客户端不兼容了.
不兼容的话,请把其它客户端改对。
这个算是BUG,因为protobuf有一种惯例用法:has_field(),用于判断是否设置了这个字段。实际工作中当作NULL来使用的 也就是说,field=0 和 不set field,field的值都是0,但是has_field不同
has_field 是实现加的东西,不是规范定义的。所谓惯用法指的特定实现的惯用法。这个版本的实现没有这个惯用法。
protobuf 为数据结构定义了类型,对于整数类型来说,NULL 不是个有效值。把 has_field 作为常规用法是一种滥用。这个特性可以纠正这种滥用。