protoc-gen-lua icon indicating copy to clipboard operation
protoc-gen-lua copied to clipboard

int64 encoder _VarintSize error!

Open zhenmu opened this issue 9 years ago • 8 comments

有64位字段的message,里面数值很大时 在计算 bytesize时出错, 应该是之前代码没兼容64位

function _VarintSize(value) if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end return 5 end

may need to change:

function _VarintSize(value) if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end if value <= 0x7ffffffff then return 5 end if value <= 0x3ffffffffff then return 6 end if value <= 0x1ffffffffffff then return 7 end if value <= 0xffffffffffffff then return 8 end if value <= 0x7fffffffffffffff then return 9 end return 10 end

不知道这样改可行不可行?

zhenmu avatar Jan 20 '16 07:01 zhenmu

@zhenmu

我今天也遇到你这个问题,测试发现这样改没有效果。

cp790621656 avatar Feb 25 '16 10:02 cp790621656

@cp790621656

我看了一下我们项目里完整的修改

1.encoder.lua

function _VarintSize(value) if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end return 5 end

function _SignedVarintSize(value) if value < 0 then return 10 end if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end return 5 end

改成

function _VarintSize(value) if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end if value <= 0x7ffffffff then return 5 end if value <= 0x3ffffffffff then return 6 end if value <= 0x1ffffffffffff then return 7 end if value <= 0xffffffffffffff then return 8 end if value <= 0x7fffffffffffffff then return 9 end return 10 end

function _SignedVarintSize(value) if value < 0 then return 10 end if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end if value <= 0x7ffffffff then return 5 end if value <= 0x3ffffffffff then return 6 end if value <= 0x1ffffffffffff then return 7 end if value <= 0xffffffffffffff then return 8 end if value <= 0x7fffffffffffffff then return 9 end return 10 end

2.ware_format里 (非必要?)

local function _VarUInt64ByteSizeNoTag(uint64) if uint64 <= 0x7f then return 1 end if uint64 <= 0x3fff then return 2 end if uint64 <= 0x1fffff then return 3 end if uint64 <= 0xfffffff then return 4 end return 5 end

改成

local function _VarUInt64ByteSizeNoTag(uint64) if uint64 <= 0x7f then return 1 end if uint64 <= 0x3fff then return 2 end if uint64 <= 0x1fffff then return 3 end if uint64 <= 0xfffffff then return 4 end if uint64 <= 0x7ffffffff then return 5 end if uint64 <= 0x3ffffffffff then return 6 end if uint64 <= 0x1ffffffffffff then return 7 end if uint64 <= 0xffffffffffffff then return 8 end if uint64 <= 0x7fffffffffffffff then return 9 end return 10 end

  1. type_checkers.lua里 (这个范围是我们自己根据一些情况 设定了一个范围) 增加

function Int64ValueChecker() local _MIN = -562949953421312 local _MAX = 562949953421312 return function(proposed_value) if type(proposed_value) ~= 'number' then error(string.format('%s has type %s, but expected one of: number', proposed_value, type(proposed_value))) end if _MIN > proposed_value or proposed_value > _MAX then error('Value out of range: ' .. proposed_value) end end end

function Uint64ValueChecker(IntValueChecker) local _MIN = 0 local _MAX = 1125899906842624

return function(proposed_value)
    if type(proposed_value) ~= 'number' then
        error(string.format('%s has type %s, but expected one of: number',
            proposed_value, type(proposed_value)))
    end
    if _MIN > proposed_value or proposed_value > _MAX then
        error('Value out of range: ' .. proposed_value)
    end
end

end

4.protobuf.lua 里

[FieldDescriptor.CPPTYPE_INT64] = type_checkers.Int32ValueChecker(),

[FieldDescriptor.CPPTYPE_UINT64] = type_checkers.Uint32ValueChecker(),

改成

[FieldDescriptor.CPPTYPE_INT64] = type_checkers.Int64ValueChecker(),

[FieldDescriptor.CPPTYPE_UINT64] = type_checkers.Uint64ValueChecker(),

仅供参考

zhenmu avatar Feb 26 '16 07:02 zhenmu

测试OK啦,安卓上也测试OK,非常感谢您!! @zhenmu

cp790621656 avatar Feb 27 '16 16:02 cp790621656

测试可用,感谢楼主

mirchd avatar Jun 21 '18 07:06 mirchd

如上修改 发现,java后端传来的long型数值,在客户端解析的数据溢出

NiYun avatar Nov 03 '18 18:11 NiYun

最大支持50位。

mirchd avatar Nov 05 '18 01:11 mirchd

最大支持50位。

为什么最大是50位呀,哪里有限制的呢,不是真的int64呢

yening520 avatar Sep 27 '20 10:09 yening520

最大支持50位。

为什么最大是50位呀,哪里有限制的呢,不是真的int64呢

lua存放数值这类的都是用double的

zhenmu avatar Nov 17 '20 12:11 zhenmu