aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThijs Schreijer <thijs@thijsschreijer.nl>2026-08-29 17:09:47 +0200
committerThijs Schreijer <thijs@thijsschreijer.nl>2026-08-29 17:22:29 +0200
commit8cbbce56e64c84b53593c815f6dcdd9214897b74 (patch)
tree101db7e5d326b8e7b8394840dda6d4de6eec343a
parente912d157b242e661dca37d0a8269202dda974ba7 (diff)
downloadluasocket-8cbbce56e64c84b53593c815f6dcdd9214897b74.tar.gz
luasocket-8cbbce56e64c84b53593c815f6dcdd9214897b74.tar.bz2
luasocket-8cbbce56e64c84b53593c815f6dcdd9214897b74.zip
fix(receive): guard maxsize against size_t overflow on cast
Casting a double larger than SIZE_MAX to size_t is undefined behavior; bound-check maxsize before the cast.
-rw-r--r--src/buffer.c3
-rw-r--r--test/testclnt.lua6
2 files changed, 6 insertions, 3 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 05d6fb3..5f06fc1 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -134,7 +134,8 @@ int buffer_meth_receive(lua_State *L, p_buffer buf) {
134 } 134 }
135 if (!lua_isnoneornil(L, 4)) { 135 if (!lua_isnoneornil(L, 4)) {
136 double m = luaL_checknumber(L, 4); 136 double m = luaL_checknumber(L, 4);
137 luaL_argcheck(L, m >= 1, 4, "maxsize must be a positive number"); 137 luaL_argcheck(L, m >= 1 && m < (lua_Number) ((size_t) -1), 4,
138 "maxsize must be a positive number");
138 maxsize = (size_t) m; 139 maxsize = (size_t) m;
139 luaL_argcheck(L, size < maxsize, 4, 140 luaL_argcheck(L, size < maxsize, 4,
140 "prefix length >= maxsize (drain with prefix=\"\" or raise maxsize)"); 141 "prefix length >= maxsize (drain with prefix=\"\" or raise maxsize)");
diff --git a/test/testclnt.lua b/test/testclnt.lua
index 3e897c9..ec154ea 100644
--- a/test/testclnt.lua
+++ b/test/testclnt.lua
@@ -640,14 +640,16 @@ function test_maxsize()
640 assert(not ok, "A5 failed: #prefix > maxsize should raise") 640 assert(not ok, "A5 failed: #prefix > maxsize should raise")
641 ok = pcall(data.receive, data, 100, nil, 50) 641 ok = pcall(data.receive, data, 100, nil, 50)
642 assert(not ok, "A6 failed: wanted > maxsize should raise") 642 assert(not ok, "A6 failed: wanted > maxsize should raise")
643 ok = pcall(data.receive, data, "*l", nil, math.huge)
644 assert(not ok, "A7 failed: maxsize=math.huge should raise (size_t overflow)")
643 data:settimeout(0.1) 645 data:settimeout(0.1)
644 ok = pcall(data.receive, data, 50, nil, 100) 646 ok = pcall(data.receive, data, 50, nil, 100)
645 assert(ok, "A7 failed: wanted <= maxsize should not raise") 647 assert(ok, "A8 failed: wanted <= maxsize should not raise")
646 data:settimeout(-1) 648 data:settimeout(-1)
647 remote [[ data:send('intact\n') ]] 649 remote [[ data:send('intact\n') ]]
648 local line, err = data:receive("*l", nil, 100) 650 local line, err = data:receive("*l", nil, 100)
649 assert(line == "intact", 651 assert(line == "intact",
650 "A8 failed: socket touched by a failed argcheck (err=" .. 652 "A9 failed: socket touched by a failed argcheck (err=" ..
651 tostring(err) .. ")") 653 tostring(err) .. ")")
652 pass("ok") 654 pass("ok")
653 655