From 39f79352bc6fe9f7f23af788167f45fb8a93abc4 Mon Sep 17 00:00:00 2001
From: Roman Tsisyk <roman@tsisyk.com>
Date: Tue, 25 Nov 2014 18:08:56 +0300
Subject: [PATCH] Fix #633: builtin/msgpackffi.lua:351: bad argument #1 to
 ''mp_bswap_double''

---
 src/lua/msgpackffi.lua       | 17 +++++++++--------
 test/app/msgpackffi.result   |  7 ++++++-
 test/app/msgpackffi.test.lua | 12 +++++++++++-
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/src/lua/msgpackffi.lua b/src/lua/msgpackffi.lua
index b81e9c31a8..5b758c447e 100644
--- a/src/lua/msgpackffi.lua
+++ b/src/lua/msgpackffi.lua
@@ -17,10 +17,6 @@ local const_char_ptr_t = ffi.typeof('const char *')
 ffi.cdef([[
 uint32_t bswap_u32(uint32_t x);
 uint64_t bswap_u64(uint64_t x);
-double
-mp_bswap_double(double d);
-float
-mp_bswap_float(float f);
 ]])
 local function bswap_u16(num)
     return bit.rshift(bit.bswap(tonumber(num)), 16)
@@ -118,14 +114,16 @@ end
 local function encode_float(buf, num)
     buf:reserve(5)
     buf.p[0] = 0xca;
-    ffi.cast(float_ptr_t, buf.p + 1)[0] = builtin.mp_bswap_float(num)
+    ffi.cast(float_ptr_t, buf.p + 1)[0] = num
+    ffi.cast(uint32_ptr_t, buf.p + 1)[0] = bswap_u32(ffi.cast(uint32_ptr_t, buf.p + 1)[0])
     buf.p = buf.p + 5
 end
 
 local function encode_double(buf, num)
     buf:reserve(9)
     buf.p[0] = 0xcb;
-    ffi.cast(double_ptr_t, buf.p + 1)[0] = builtin.mp_bswap_double(num)
+    ffi.cast(double_ptr_t, buf.p + 1)[0] = num
+    ffi.cast(uint64_ptr_t, buf.p + 1)[0] = bswap_u64(ffi.cast(uint64_ptr_t, buf.p + 1)[0])
     buf.p = buf.p + 9
 end
 
@@ -341,14 +339,17 @@ local function decode_i64(data)
     return ffi.cast('int64_t', ffi.cast('uint64_t', num))
 end
 
+local bswap_buf = ffi.new('char[8]')
 local function decode_float(data)
-    local num = builtin.mp_bswap_float(ffi.cast(float_ptr_t,data[0])[0])
+    ffi.cast(uint32_ptr_t, bswap_buf)[0] = bswap_u32(ffi.cast(uint32_ptr_t, data[0])[0])
+    local num = ffi.cast(float_ptr_t, bswap_buf)[0]
     data[0] = data[0] + 4
     return tonumber(num)
 end
 
 local function decode_double(data)
-    local num = builtin.mp_bswap_double(ffi.cast(double_ptr_t, data[0])[0])
+    ffi.cast(uint64_ptr_t, bswap_buf)[0] = bswap_u64(ffi.cast(uint64_ptr_t, data[0])[0])
+    local num = ffi.cast(double_ptr_t, bswap_buf)[0]
     data[0] = data[0] + 8
     return tonumber(num)
 end
diff --git a/test/app/msgpackffi.result b/test/app/msgpackffi.result
index f26dab8140..940ce93039 100644
--- a/test/app/msgpackffi.result
+++ b/test/app/msgpackffi.result
@@ -1,6 +1,6 @@
 TAP version 13
 # msgpackffi
-1..8
+1..9
     # unsigned
     1..56
     ok - encode/decode for 0
@@ -156,4 +156,9 @@ ok - table
     ok - invalid offset
     # offsets: end
 ok - offsets
+    # other
+    1..1
+    ok - gh-633 double decode
+    # other: end
+ok - other
 # msgpackffi: end
diff --git a/test/app/msgpackffi.test.lua b/test/app/msgpackffi.test.lua
index a3fdf7504b..e70bdf8ba8 100755
--- a/test/app/msgpackffi.test.lua
+++ b/test/app/msgpackffi.test.lua
@@ -35,9 +35,18 @@ local function test_offsets(test, s)
     test:ok(not pcall(s.decode, dump, offset), "invalid offset")
 end
 
+local function test_other(test, s)
+    test:plan(1)
+    local buf = string.char(0x93, 0x6e, 0xcb, 0x42, 0x2b, 0xed, 0x30, 0x47,
+        0x6f, 0xff, 0xff, 0xac, 0x77, 0x6b, 0x61, 0x71, 0x66, 0x7a, 0x73,
+        0x7a, 0x75, 0x71, 0x71, 0x78)
+	local num = s.decode(buf)[2]
+    test:ok(num < 59971740600 and num > 59971740599, "gh-633 double decode")
+end
+
 tap.test("msgpackffi", function(test)
     local serializer = require('msgpackffi')
-    test:plan(8)
+    test:plan(9)
     test:test("unsigned", common.test_unsigned, serializer)
     test:test("signed", common.test_signed, serializer)
     test:test("double", common.test_double, serializer)
@@ -48,4 +57,5 @@ tap.test("msgpackffi", function(test)
     -- udata/cdata hooks are not implemented
     --test:test("ucdata", common.test_ucdata, serializer)
     test:test("offsets", test_offsets, serializer)
+    test:test("other", test_other, serializer)
 end)
-- 
GitLab