diff --git a/lib/rack/multipart/parser.rb b/lib/rack/multipart/parser.rb index ec2658419..98eceaa15 100644 --- a/lib/rack/multipart/parser.rb +++ b/lib/rack/multipart/parser.rb @@ -125,7 +125,7 @@ def get_filename(head) filename = $1 end - if filename && filename.scan(/%..?/).all? { |s| s =~ /%[0-9a-fA-F]{2}/ } + if filename && filename.scan(/%.?.?/).all? { |s| s =~ /%[0-9a-fA-F]{2}/ } filename = Utils.unescape(filename) end if filename && filename !~ /\\[^\\"]/ diff --git a/test/multipart/filename_with_unescaped_percentages3 b/test/multipart/filename_with_unescaped_percentages3 new file mode 100644 index 000000000..4dba3c885 --- /dev/null +++ b/test/multipart/filename_with_unescaped_percentages3 @@ -0,0 +1,6 @@ +------WebKitFormBoundary2NHc7OhsgU68l3Al +Content-Disposition: form-data; name="document[attachment]"; filename="100%" +Content-Type: image/jpeg + +contents +------WebKitFormBoundary2NHc7OhsgU68l3Al-- diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb index c70cd7ee6..b0bf57c08 100644 --- a/test/spec_multipart.rb +++ b/test/spec_multipart.rb @@ -241,6 +241,21 @@ def multipart_file(name) files[:tempfile].read.should.equal "contents" end + should "parse filename with unescaped percentage characters that look like partial hex escapes" do + env = Rack::MockRequest.env_for("/", multipart_fixture(:filename_with_unescaped_percentages3, "----WebKitFormBoundary2NHc7OhsgU68l3Al")) + params = Rack::Multipart.parse_multipart(env) + files = params["document"]["attachment"] + files[:type].should.equal "image/jpeg" + files[:filename].should.equal "100%" + files[:head].should.equal <<-MULTIPART +Content-Disposition: form-data; name="document[attachment]"; filename="100%"\r +Content-Type: image/jpeg\r + MULTIPART + + files[:name].should.equal "document[attachment]" + files[:tempfile].read.should.equal "contents" + end + it "rewinds input after parsing upload" do options = multipart_fixture(:text) input = options[:input]