Skip to content

Commit 0a8b39f

Browse files
Oleg Chaplashkinylobankov
authored andcommitted
Raise error when non-array arguments passed to server:exec
An error will be raised if the non-array arguments have been passed to the `server:exec()`. Resolves #230
1 parent 42d4e24 commit 0a8b39f

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
- Auto-require `luatest` module in `Server:exec()` function where it is available
4747
via the corresponding upvalue.
4848
- Add new function `tarantool.skip_if_not_enterprise`.
49+
- Raise an error when non-array arguments passed to the `server:exec()`.
4950

5051
## 0.5.7
5152

luatest/server.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,19 @@ local function exec_tail(ok, ...)
504504
end
505505
end
506506

507+
-- Check that the passed `args` to the `fn` function are an array.
508+
local function are_fn_args_array(fn, args)
509+
local fn_details = debug.getinfo(fn)
510+
if args and #args ~= fn_details.nparams then
511+
for k, _ in pairs(args) do
512+
if type(k) ~= 'number' then
513+
return false
514+
end
515+
end
516+
end
517+
return true
518+
end
519+
507520
--- Run given function on the server.
508521
--
509522
-- Much like `Server:eval`, but takes a function instead of a string.
@@ -562,6 +575,11 @@ function Server:exec(fn, args, options)
562575
error(err, 2)
563576
end
564577

578+
if not are_fn_args_array(fn, args) then
579+
error(('bad argument #3 for exec at %s: an array is required')
580+
:format(utils.get_fn_location(fn)))
581+
end
582+
565583
return exec_tail(self.net_box:eval([[
566584
local dump, args, passthrough_ups = ...
567585
local fn = loadstring(dump)

luatest/utils.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,10 @@ function utils.upvalues(fn)
142142
return ret
143143
end
144144

145+
function utils.get_fn_location(fn)
146+
local fn_details = debug.getinfo(fn)
147+
local fn_source = fn_details.source:split('/')
148+
return ('%s:%s'):format(fn_source[#fn_source], fn_details.linedefined)
149+
end
145150

146151
return utils

test/malformed_args_test.lua

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
local fio = require('fio')
2+
local t = require('luatest')
3+
4+
local g = t.group()
5+
local Server = t.Server
6+
7+
local root = fio.dirname(fio.dirname(fio.abspath(package.search('test.helper'))))
8+
local datadir = fio.pathjoin(root, 'tmp', 'malformed_args')
9+
local command = fio.pathjoin(root, 'test', 'server_instance.lua')
10+
11+
g.before_all(function()
12+
fio.rmtree(datadir)
13+
14+
local log = fio.pathjoin(datadir, 'malformed_args_server.log')
15+
g.server = Server:new({
16+
command = command,
17+
workdir = datadir,
18+
env = {
19+
TARANTOOL_LOG = log
20+
},
21+
http_port = 8186,
22+
net_box_port = 3139,
23+
})
24+
fio.mktree(g.server.workdir)
25+
26+
g.server:start()
27+
t.helpers.retrying({timeout = 2}, function()
28+
g.server:http_request('get', '/ping')
29+
end)
30+
31+
g.server:connect_net_box()
32+
end)
33+
34+
g.after_all(function()
35+
g.server:drop()
36+
fio.rmtree(datadir)
37+
end)
38+
39+
g.test_exec_correct_args = function()
40+
local a = g.server:exec(function(a, b) return a + b end, {1, 1})
41+
t.assert_equals(a, 2)
42+
end
43+
44+
g.test_exec_no_args = function()
45+
local a = g.server:exec(function() return 1 + 1 end)
46+
t.assert_equals(a, 2)
47+
end
48+
49+
g.test_exec_specific_args = function()
50+
-- nil
51+
local a = g.server:exec(function(a) return a end)
52+
t.assert_equals(a, nil)
53+
54+
-- too few args
55+
local b, c = g.server:exec(function(b, c) return b, c end, {1})
56+
t.assert_equals(b, 1)
57+
t.assert_equals(c, nil)
58+
59+
-- too many args
60+
local d = g.server:exec(function(d) return d end, {1, 2})
61+
t.assert_equals(d, 1)
62+
end
63+
64+
g.test_exec_non_array_args = function()
65+
local function f1()
66+
g.server:exec(function(a, b, c) return a, b, c end, {a="a", 2, 3})
67+
end
68+
69+
local function f2()
70+
g.server:exec(function(a, b, c) return a, b, c end, {1, a="a", 2})
71+
end
72+
73+
local function f3()
74+
g.server:exec(function(a, b, c) return a, b, c end, {1, 2, a="a"})
75+
end
76+
77+
t.assert_error_msg_contains("bad argument #3 for exec at malformed_args_test.lua:66:", f1)
78+
t.assert_error_msg_contains("bad argument #3 for exec at malformed_args_test.lua:70:", f2)
79+
t.assert_error_msg_contains("bad argument #3 for exec at malformed_args_test.lua:74:", f3)
80+
end

0 commit comments

Comments
 (0)