* luci/libs/http: fix a few corner cases which can lead to bugs in mime decoding, allow the message body to exceed Content-Length by two bytes (to ignore a possible trailing \r\n)
This commit is contained in:
parent
21b491c20b
commit
447df436fc
1 changed files with 25 additions and 27 deletions
|
@ -266,6 +266,12 @@ function mimedecode_message_body( src, msg, filecb )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local tlen = 0
|
||||||
|
local inhdr = false
|
||||||
|
local field = nil
|
||||||
|
local store = nil
|
||||||
|
local lchunk = nil
|
||||||
|
|
||||||
local function parse_headers( chunk, field )
|
local function parse_headers( chunk, field )
|
||||||
|
|
||||||
local stat
|
local stat
|
||||||
|
@ -294,24 +300,32 @@ function mimedecode_message_body( src, msg, filecb )
|
||||||
field.headers["Content-Type"] = "text/plain"
|
field.headers["Content-Type"] = "text/plain"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if field.name and field.file and filecb then
|
||||||
|
__initval( msg.params, field.name )
|
||||||
|
__appendval( msg.params, field.name, field.file )
|
||||||
|
|
||||||
|
store = filecb
|
||||||
|
elseif field.name then
|
||||||
|
__initval( msg.params, field.name )
|
||||||
|
|
||||||
|
store = function( hdr, buf, eof )
|
||||||
|
__appendval( msg.params, field.name, buf )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
store = nil
|
||||||
|
end
|
||||||
|
|
||||||
return chunk, true
|
return chunk, true
|
||||||
end
|
end
|
||||||
|
|
||||||
return chunk, false
|
return chunk, false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local tlen = 0
|
|
||||||
local inhdr = false
|
|
||||||
local field = nil
|
|
||||||
local store = nil
|
|
||||||
local lchunk = nil
|
|
||||||
|
|
||||||
local function snk( chunk )
|
local function snk( chunk )
|
||||||
|
|
||||||
tlen = tlen + ( chunk and #chunk or 0 )
|
tlen = tlen + ( chunk and #chunk or 0 )
|
||||||
|
|
||||||
if msg.env.CONTENT_LENGTH and tlen > tonumber(msg.env.CONTENT_LENGTH) then
|
if msg.env.CONTENT_LENGTH and tlen > tonumber(msg.env.CONTENT_LENGTH) + 2 then
|
||||||
return nil, "Message body size exceeds Content-Length"
|
return nil, "Message body size exceeds Content-Length"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -338,9 +352,7 @@ function mimedecode_message_body( src, msg, filecb )
|
||||||
|
|
||||||
if not eof then
|
if not eof then
|
||||||
return nil, "Invalid MIME section header"
|
return nil, "Invalid MIME section header"
|
||||||
end
|
elseif not field.name then
|
||||||
|
|
||||||
if not field.name then
|
|
||||||
return nil, "Invalid Content-Disposition header"
|
return nil, "Invalid Content-Disposition header"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -355,29 +367,15 @@ function mimedecode_message_body( src, msg, filecb )
|
||||||
|
|
||||||
data, eof = parse_headers( data:sub( epos + 1, #data ), field )
|
data, eof = parse_headers( data:sub( epos + 1, #data ), field )
|
||||||
inhdr = not eof
|
inhdr = not eof
|
||||||
|
|
||||||
if eof then
|
|
||||||
if field.file and filecb then
|
|
||||||
msg.params[field.name] = field.file
|
|
||||||
store = filecb
|
|
||||||
else
|
|
||||||
__initval( msg.params, field.name )
|
|
||||||
|
|
||||||
store = function( hdr, buf, eof )
|
|
||||||
__appendval( msg.params, field.name, buf )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
until not spos
|
until not spos
|
||||||
|
|
||||||
|
|
||||||
if found then
|
if found then
|
||||||
if #data > 78 then
|
if #data > 78 then
|
||||||
lchunk = data:sub( #data - 78 + 1, #data )
|
lchunk = data:sub( #data - 78 + 1, #data )
|
||||||
data = data:sub( 1, #data - 78 )
|
data = data:sub( 1, #data - 78 )
|
||||||
|
|
||||||
if store and field and field.name then
|
if store then
|
||||||
store( field.headers, data, false )
|
store( field.headers, data, false )
|
||||||
else
|
else
|
||||||
return nil, "Invalid MIME section header"
|
return nil, "Invalid MIME section header"
|
||||||
|
@ -413,7 +411,7 @@ function urldecode_message_body( src, msg )
|
||||||
|
|
||||||
tlen = tlen + ( chunk and #chunk or 0 )
|
tlen = tlen + ( chunk and #chunk or 0 )
|
||||||
|
|
||||||
if msg.env.CONTENT_LENGTH and tlen > tonumber(msg.env.CONTENT_LENGTH) then
|
if msg.env.CONTENT_LENGTH and tlen > tonumber(msg.env.CONTENT_LENGTH) + 2 then
|
||||||
return nil, "Message body size exceeds Content-Length"
|
return nil, "Message body size exceeds Content-Length"
|
||||||
elseif tlen > HTTP_MAX_CONTENT then
|
elseif tlen > HTTP_MAX_CONTENT then
|
||||||
return nil, "Message body size exceeds maximum allowed length"
|
return nil, "Message body size exceeds maximum allowed length"
|
||||||
|
|
Loading…
Reference in a new issue