Skip to content

Commit

Permalink
Fix multipart parser for special files #1308
Browse files Browse the repository at this point in the history
  • Loading branch information
aiomaster authored and jeremyevans committed Jan 22, 2020
1 parent f9ef9a0 commit b50bc8b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
6 changes: 3 additions & 3 deletions lib/rack/multipart/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def initialize(boundary, tempfile, bufsize, query_parser)
@collector = Collector.new tempfile

@sbuf = StringScanner.new("".dup)
@body_regex = /(.*?)(#{EOL})?#{Regexp.quote(@boundary)}(#{EOL}|--)/m
@body_regex = /(?:#{EOL})?#{Regexp.quote(@boundary)}(?:#{EOL}|--)/m
@rx_max_size = EOL.size + @boundary.bytesize + [EOL.size, '--'.size].max
@head_regex = /(.*?#{EOL})#{EOL}/m
end
Expand Down Expand Up @@ -268,8 +268,8 @@ def handle_mime_head
end

def handle_mime_body
if @sbuf.check_until(@body_regex) # check but do not advance the pointer yet
body = @sbuf[1]
if (body_with_boundary = @sbuf.check_until(@body_regex)) # check but do not advance the pointer yet
body = body_with_boundary.sub(/#{@body_regex}\z/m, '') # remove the boundary from the string
@collector.on_mime_body @mime_index, body
@sbuf.pos += body.length + 2 # skip \r\n after the content
@state = :CONSUME_TOKEN
Expand Down
26 changes: 26 additions & 0 deletions test/spec_multipart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require 'rack/multipart/parser'
require 'rack/utils'
require 'rack/mock'
require 'timeout'

describe Rack::Multipart do
def multipart_fixture(name, boundary = "AaB03x")
Expand Down Expand Up @@ -146,6 +147,31 @@ def rd.rewind; end
wr.close
end

# see https://github.com/rack/rack/pull/1309
it "parse strange multipart pdf" do
boundary = '---------------------------932620571087722842402766118'

data = StringIO.new
data.write("--#{boundary}")
data.write("\r\n")
data.write('Content-Disposition: form-data; name="a"; filename="a.pdf"')
data.write("\r\n")
data.write("Content-Type:application/pdf\r\n")
data.write("\r\n")
data.write("-" * (1024 * 1024))
data.write("\r\n")
data.write("--#{boundary}--\r\n")

fixture = {
"CONTENT_TYPE" => "multipart/form-data; boundary=#{boundary}",
"CONTENT_LENGTH" => data.length.to_s,
:input => data,
}

env = Rack::MockRequest.env_for '/', fixture
Timeout::timeout(10) { Rack::Multipart.parse_multipart(env) }
end

it 'raises an EOF error on content-length mistmatch' do
env = Rack::MockRequest.env_for("/", multipart_fixture(:empty))
env['rack.input'] = StringIO.new
Expand Down

0 comments on commit b50bc8b

Please sign in to comment.