mysql : 修复读写负数导致溢出处错误 (#1182) (#1183)

* mysql : 修复读写负数导致溢出处错误 #1182

* modify mysql test cases

* 对于db内部整型值的处理使用独立函数
This commit is contained in:
Zhongyue Yue
2020-04-25 19:26:27 +08:00
committed by GitHub
parent 87cde31c28
commit b68b27f26b
2 changed files with 49 additions and 7 deletions

View File

@@ -4,6 +4,8 @@
-- The license is under the BSD license. -- The license is under the BSD license.
-- Modified by Cloud Wu (remove bit32 for lua 5.3) -- Modified by Cloud Wu (remove bit32 for lua 5.3)
-- protocol detail: https://mariadb.com/kb/en/clientserver-protocol/
local socketchannel = require "skynet.socketchannel" local socketchannel = require "skynet.socketchannel"
local crypt = require "skynet.crypt" local crypt = require "skynet.crypt"
@@ -100,7 +102,10 @@ local function _get_byte1(data, i)
return strbyte(data, i), i + 1 return strbyte(data, i), i + 1
end end
local function _get_int1(data, i) local function _get_int1(data, i, is_signed)
if not is_signed then
return strunpack("<I1", data, i)
end
return strunpack("<i1", data, i) return strunpack("<i1", data, i)
end end
@@ -108,7 +113,10 @@ local function _get_byte2(data, i)
return strunpack("<I2", data, i) return strunpack("<I2", data, i)
end end
local function _get_int2(data, i) local function _get_int2(data, i, is_signed)
if not is_signed then
return strunpack("<I2", data, i)
end
return strunpack("<i2", data, i) return strunpack("<i2", data, i)
end end
@@ -116,11 +124,21 @@ local function _get_byte3(data, i)
return strunpack("<I3", data, i) return strunpack("<I3", data, i)
end end
local function _get_int3(data, i, is_signed)
if not is_signed then
return strunpack("<I3", data, i)
end
return strunpack("<i3", data, i)
end
local function _get_byte4(data, i) local function _get_byte4(data, i)
return strunpack("<I4", data, i) return strunpack("<I4", data, i)
end end
local function _get_int4(data, i) local function _get_int4(data, i, is_signed)
if not is_signed then
return strunpack("<I4", data, i)
end
return strunpack("<i4", data, i) return strunpack("<i4", data, i)
end end
@@ -128,7 +146,10 @@ local function _get_byte8(data, i)
return strunpack("<I8", data, i) return strunpack("<I8", data, i)
end end
local function _get_int8(data, i) local function _get_int8(data, i, is_signed)
if not is_signed then
return strunpack("<I8", data, i)
end
return strunpack("<i8", data, i) return strunpack("<i8", data, i)
end end
@@ -354,10 +375,13 @@ local function _parse_field_packet(data)
charsetnr, pos = _get_byte2(data, pos) charsetnr, pos = _get_byte2(data, pos)
length, pos = _get_byte4(data, pos) length, pos = _get_byte4(data, pos)
col.type = strbyte(data, pos) col.type = strbyte(data, pos)
pos = pos + 1
local flags, pos = _get_byte2(data, pos)
if flags & 0x20 == 0 then -- https://mariadb.com/kb/en/resultset/
col.is_signed = true
end
--[[ --[[
pos = pos + 1
col.flags, pos = _get_byte2(data, pos)
col.decimals = strbyte(data, pos) col.decimals = strbyte(data, pos)
pos = pos + 1 pos = pos + 1
local default = sub(data, pos + 2) local default = sub(data, pos + 2)
@@ -812,6 +836,7 @@ local _binary_parser = {
[0x05] = _get_double, [0x05] = _get_double,
[0x07] = _get_datetime, [0x07] = _get_datetime,
[0x08] = _get_int8, [0x08] = _get_int8,
[0x09] = _get_int3,
[0x0c] = _get_datetime, [0x0c] = _get_datetime,
[0x0f] = _from_length_coded_str, [0x0f] = _from_length_coded_str,
[0x10] = _from_length_coded_str, [0x10] = _from_length_coded_str,
@@ -859,7 +884,7 @@ local function _parse_row_data_binary(data, cols, compact)
if not parser then if not parser then
error("_parse_row_data_binary()error,unsupported field type " .. typ) error("_parse_row_data_binary()error,unsupported field type " .. typ)
end end
value, pos = parser(data, pos) value, pos = parser(data, pos, col.is_signed)
if compact then if compact then
row[i] = value row[i] = value
else else

View File

@@ -117,6 +117,21 @@ local function test_sp_blob(db)
print("test stored procedure ok") print("test stored procedure ok")
end end
local function test_signed(db)
local res = db:query("drop table if exists test_i_u")
res = db:query("create table test_i_u (i tinyint primary key, u tinyint unsigned)")
print(dump(res))
res = db:query("insert into test_i_u (i,u) values (-1,1),(127,128),(-127,255)")
print(dump(res))
local prep = "SELECT * FROM test_i_u"
local stmt = db:prepare(prep)
local res = db:execute(stmt)
print("test_i_u: ", dump(res))
db:stmt_close(stmt)
end
skynet.start(function() skynet.start(function()
local function on_connect(db) local function on_connect(db)
@@ -151,6 +166,8 @@ skynet.start(function()
-- 测试存储过程和二进制blob -- 测试存储过程和二进制blob
test_sp_blob(db) test_sp_blob(db)
test_signed(db)
-- test in another coroutine -- test in another coroutine
skynet.fork( test2, db) skynet.fork( test2, db)