From c27af84f239c6ed29ea16df442acd0439dddbc00 Mon Sep 17 00:00:00 2001
From: Roman Tsisyk <roman@tsisyk.com>
Date: Sun, 19 Oct 2014 13:28:32 +0400
Subject: [PATCH] Fix #594: builtin/net.box.lua:632: bad argument #1 to
 'setmetatable'

This patch also fixes incorrect offset calculation in buffer
with multiple responses:

    self.rbuf = string.sub(self.rbuf, off + 1)
---
 src/lua/box_net_box.lua       |  9 ++++++---
 test/box/box.net.box.result   | 14 ++++++++++++++
 test/box/box.net.box.test.lua | 10 ++++++++++
 3 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/src/lua/box_net_box.lua b/src/lua/box_net_box.lua
index b8169e71f5..3aeb1e3455 100644
--- a/src/lua/box_net_box.lua
+++ b/src/lua/box_net_box.lua
@@ -619,21 +619,24 @@ local remote_methods = {
 
             local len, off = msgpack.decode(self.rbuf)
             -- wait for correct package length
-            if len + off - 1 > #self.rbuf then
+            local roff = off + len - 1
+            if roff > #self.rbuf then
                 break
             end
 
 
             local hdr, body
             hdr, off = msgpack.decode(self.rbuf, off)
-            if off < #self.rbuf then
+            -- assert(off <= roff + 1)
+            if off < roff then
                 body, off = msgpack.decode(self.rbuf, off)
+                -- assert(off == roff + 1)
                 -- disable YAML flow output (useful for admin console)
                 setmetatable(body, mapping_mt)
             else
                 body = {}
             end
-            self.rbuf = string.sub(self.rbuf, off + 1)
+            self.rbuf = string.sub(self.rbuf, off)
 
             local sync = hdr[SYNC]
 
diff --git a/test/box/box.net.box.result b/test/box/box.net.box.result
index 58c38375be..b5af04d8a7 100644
--- a/test/box/box.net.box.result
+++ b/test/box/box.net.box.result
@@ -634,3 +634,17 @@ cn:ping()
 cn:close()
 ---
 ...
+-- #594: bad argument #1 to 'setmetatable' (table expected, got number)
+--# setopt delimiter ';'
+function gh594()
+    local cn = remote:new(box.cfg.listen)
+    local ping = fiber.create(function() cn:ping() end)
+    cn:call('dostring', 'return 2 + 2')
+    cn:close()
+end;
+---
+...
+--# setopt delimiter ''
+gh594()
+---
+...
diff --git a/test/box/box.net.box.test.lua b/test/box/box.net.box.test.lua
index 9803bc9c50..65309c0321 100644
--- a/test/box/box.net.box.test.lua
+++ b/test/box/box.net.box.test.lua
@@ -252,3 +252,13 @@ cn = remote.new(uri, { password = 'test' })
 cn:ping()
 cn:close()
 
+-- #594: bad argument #1 to 'setmetatable' (table expected, got number)
+--# setopt delimiter ';'
+function gh594()
+    local cn = remote:new(box.cfg.listen)
+    local ping = fiber.create(function() cn:ping() end)
+    cn:call('dostring', 'return 2 + 2')
+    cn:close()
+end;
+--# setopt delimiter ''
+gh594()
-- 
GitLab