Skip to content

Commit 7fa2550

Browse files
committed
bugfix: unexpected runtime exceptions would be thrown when lua-resty-upload met a in-part header field line or a terminating boundary line that was too long.
1 parent 5e6aba8 commit 7fa2550

File tree

2 files changed

+114
-5
lines changed

2 files changed

+114
-5
lines changed

lib/resty/upload.lua

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
local sub = string.sub
55
local req_socket = ngx.req.socket
66
local insert = table.insert
7+
local concat = table.concat
78
local len = string.len
89
local null = ngx.null
910
local match = string.match
@@ -133,8 +134,7 @@ function discard_line(self)
133134

134135
local dummy, err = self.read_line(1)
135136
if dummy then
136-
return nil, table.concat({"line too long: ", line, dummy,
137-
"..."}, "")
137+
return nil, concat({"line too long: ", line, dummy, "..."}, "")
138138
end
139139

140140
if err then
@@ -172,8 +172,7 @@ function read_header(self)
172172

173173
local dummy, err = read_line(1)
174174
if dummy then
175-
return nil, nil, table.concat({"line too long: ", line, dummy,
176-
"..."}, "")
175+
return nil, nil, concat({"line too long: ", line, dummy, "..."}, "")
177176
end
178177

179178
if err then
@@ -220,7 +219,7 @@ function read_body_part(self)
220219
end
221220

222221
if data ~= "\r\n" then
223-
ok, err = discard_line(self)
222+
local ok, err = discard_line(self)
224223
if not ok then
225224
return nil, nil, err
226225
end

t/sanity.t

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,113 @@ read: ["eof"]
8282
--- no_error_log
8383
[error]
8484

85+
86+
87+
=== TEST 2: in-part header line too long
88+
--- http_config eval: $::HttpConfig
89+
--- config
90+
location /t {
91+
content_by_lua '
92+
local upload = require "resty.upload"
93+
local cjson = require "cjson"
94+
95+
local form = upload:new(5)
96+
97+
form:set_timeout(1000) -- 1 sec
98+
99+
while true do
100+
local typ, res, err = form:read()
101+
if not typ then
102+
ngx.say("failed to read: ", err)
103+
return
104+
end
105+
106+
ngx.say("read: ", cjson.encode({typ, res}))
107+
108+
if typ == "eof" then
109+
break
110+
end
111+
end
112+
113+
local typ, res, err = form:read()
114+
ngx.say("read: ", cjson.encode({typ, res}))
115+
';
116+
}
117+
--- more_headers
118+
Content-Type: multipart/form-data; boundary=---------------------------820127721219505131303151179
119+
--- request eval
120+
qq{POST /t\n-----------------------------820127721219505131303151179\r
121+
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
122+
Content-Type: text/plain\r
123+
} . ("Hello, world" x 64) . qq{\r\n-----------------------------820127721219505131303151179\r
124+
Content-Disposition: form-data; name="test"\r
125+
\r
126+
value\r
127+
\r\n-----------------------------820127721219505131303151179--\r
128+
}
129+
--- response_body
130+
read: ["header",["Content-Disposition","form-data; name=\"file1\"; filename=\"a.txt\"","Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""]]
131+
read: ["header",["Content-Type","text\/plain","Content-Type: text\/plain"]]
132+
failed to read: line too long: Hello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, worldHello, wo...
133+
--- no_error_log
134+
[error]
135+
136+
137+
138+
=== TEST 3: terminate line too long
139+
--- http_config eval: $::HttpConfig
140+
--- config
141+
location /t {
142+
content_by_lua '
143+
local upload = require "resty.upload"
144+
local cjson = require "cjson"
145+
146+
local form = upload:new(5)
147+
148+
form:set_timeout(1000) -- 1 sec
149+
150+
while true do
151+
local typ, res, err = form:read()
152+
if not typ then
153+
ngx.say("failed to read: ", err)
154+
return
155+
end
156+
157+
ngx.say("read: ", cjson.encode({typ, res}))
158+
159+
if typ == "eof" then
160+
break
161+
end
162+
end
163+
164+
local typ, res, err = form:read()
165+
ngx.say("read: ", cjson.encode({typ, res}))
166+
';
167+
}
168+
--- more_headers
169+
Content-Type: multipart/form-data; boundary=---------------------------820127721219505131303151179
170+
--- request eval
171+
qq{POST /t\n-----------------------------820127721219505131303151179\r
172+
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
173+
Content-Type: text/plain\r
174+
\r
175+
Hello, world\r\n-----------------------------820127721219505131303151179\r
176+
Content-Disposition: form-data; name="test"\r
177+
\r
178+
value\r
179+
\r\n-----------------------------820127721219505131303151179} . ("a" x 1024) . qq{--\r
180+
}
181+
--- response_body
182+
read: ["header",["Content-Disposition","form-data; name=\"file1\"; filename=\"a.txt\"","Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""]]
183+
read: ["header",["Content-Type","text\/plain","Content-Type: text\/plain"]]
184+
read: ["body","Hello"]
185+
read: ["body",", wor"]
186+
read: ["body","ld"]
187+
read: ["part_end"]
188+
read: ["header",["Content-Disposition","form-data; name=\"test\"","Content-Disposition: form-data; name=\"test\""]]
189+
read: ["body","value"]
190+
read: ["body","\r\n"]
191+
failed to read: line too long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
192+
--- no_error_log
193+
[error]
194+

0 commit comments

Comments
 (0)