doujiang24 / lua-resty-kafka

Lua kafka client driver for the Openresty based on the cosocket API
BSD 3-Clause "New" or "Revised" License
802 stars 275 forks source link

Fix bug about str_int64 and add protect #82

Open anhzhi opened 4 years ago

anhzhi commented 4 years ago

https://github.com/doujiang24/lua-resty-kafka/blob/6875e6cd42faffb6de974127234d48bdb4388737/lib/resty/kafka/request.lua#L57


-- XX int can be cdata: LL or lua number
-- by anhzhi: LL(cdata, 64-bit number) not supported by math, not supported by lua, only supported by luajit
local function str_int64(int)
    if type(int) == 'cdata' then
        -- if int is a lua number ge than 2^32, which can not be represented by an 4-bit number,
        -- rshift will leads to overflow
        -- the result is equivalent to circular_rshift(int % 2 ^ 32, offset)
        -- which is unexpected
        -- for example:
        -- timestamp = os.time()*1000
        -- rshift(timestamp, 56) == rshift(timestamp, 24) == rshift(timestamp % 2 ^ 32, 24)
        return char(tonumber(band(rshift(int, 56), 0xff)),
                tonumber(band(rshift(int, 48), 0xff)),
                tonumber(band(rshift(int, 40), 0xff)),
                tonumber(band(rshift(int, 32), 0xff)),
                tonumber(band(rshift(int, 24), 0xff)),
                tonumber(band(rshift(int, 16), 0xff)),
                tonumber(band(rshift(int, 8), 0xff)),
                tonumber(band(int, 0xff)))
    elseif type(int) == 'number' then
        return str_int32(math.floor(int / 2 ^ 32)) .. str_int32(int % 2 ^ 32)
    elseif type(int) == 'string' then
        local _int = tonumber(int) or tonumber(int, 16)
        if _int ~= nil then
            return str_int64(_int)
        end
    end
    return int
end
anhzhi commented 4 years ago

of cource, you can correct the note:

-- XX int can be cdata: LL or lua number
doujiang24 commented 4 years ago

@anhzhi please create a pull request, thanks