aboutsummaryrefslogtreecommitdiff
path: root/src/tp.lua
diff options
context:
space:
mode:
authorCaleb Maclennan <caleb@alerque.com>2026-08-31 11:04:37 +0300
committerGitHub <noreply@github.com>2026-08-31 11:04:37 +0300
commit01162f05408ac4206be15842ef91048c63c23869 (patch)
tree2b7c8a2916cf8083b557a897c7d258e00a9c4fa3 /src/tp.lua
parent5afe174eeffc7f3e3b9ef80b5871237620c68415 (diff)
parentc84e79f6d1ae735bfa191694ec6a62eb8231166d (diff)
downloadluasocket-01162f05408ac4206be15842ef91048c63c23869.tar.gz
luasocket-01162f05408ac4206be15842ef91048c63c23869.tar.bz2
luasocket-01162f05408ac4206be15842ef91048c63c23869.zip
Merge pull request #467 from lunarmodules/fix/http-size-protect
Fix/http size protect
Diffstat (limited to 'src/tp.lua')
-rw-r--r--src/tp.lua18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/tp.lua b/src/tp.lua
index b8ebc56..ff5a5cf 100644
--- a/src/tp.lua
+++ b/src/tp.lua
@@ -19,6 +19,10 @@ local _M = socket.tp
19-- Program constants 19-- Program constants
20----------------------------------------------------------------------------- 20-----------------------------------------------------------------------------
21_M.TIMEOUT = 60 21_M.TIMEOUT = 60
22-- maximum size of a single reply line
23_M.MAXLINE = 8192
24-- maximum total size of a (possibly multiline) reply
25_M.MAXREPLY = 65536
22 26
23----------------------------------------------------------------------------- 27-----------------------------------------------------------------------------
24-- Implementation 28-- Implementation
@@ -26,14 +30,24 @@ _M.TIMEOUT = 60
26-- gets server reply (works for SMTP and FTP) 30-- gets server reply (works for SMTP and FTP)
27local function get_reply(c) 31local function get_reply(c)
28 local code, current, sep 32 local code, current, sep
29 local line, err = c:receive() 33 -- bounds total bytes read across a multiline reply, on top of the
34 -- per-line MAXLINE cap, so a peer can't exhaust memory by sending many
35 -- lines that each individually fit under MAXLINE
36 local budget = _M.MAXREPLY
37 local function recvline()
38 if budget <= 0 then return nil, "oversized" end
39 local line, err = c:receive("*l", nil, math.min(budget, _M.MAXLINE))
40 if line then budget = budget - #line end
41 return line, err
42 end
43 local line, err = recvline()
30 local reply = line 44 local reply = line
31 if err then return nil, err end 45 if err then return nil, err end
32 code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) 46 code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
33 if not code then return nil, "invalid server reply" end 47 if not code then return nil, "invalid server reply" end
34 if sep == "-" then -- reply is multiline 48 if sep == "-" then -- reply is multiline
35 repeat 49 repeat
36 line, err = c:receive() 50 line, err = recvline()
37 if err then return nil, err end 51 if err then return nil, err end
38 current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) 52 current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
39 reply = reply .. "\n" .. line 53 reply = reply .. "\n" .. line