From 5114c948391fba8a3828027b6ff32bf063e6bd68 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Thu, 15 Jan 2009 14:37:38 -0600 Subject: [PATCH] Trim IE's full file path in multipart uploads --- lib/rack/utils.rb | 8 ++++++++ test/multipart/ie | 6 ++++++ test/spec_rack_utils.rb | 15 ++++++++++++++- 3 files changed, 28 insertions(+), 1 deletions(-) create mode 100644 test/multipart/ie diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index 03009a9..1b2417e 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -293,6 +293,14 @@ module Rack if filename body.rewind + + # Take the basename of the upload's original filename. + # This handles the full Windows paths given by Internet Explorer + # (and perhaps other broken user agents) without affecting + # those which give the lone filename. + filename =~ /^(?:.*[:\\\/])?(.*)/m + filename = $1 + data = {:filename => filename, :type => content_type, :name => name, :tempfile => body, :head => head} else diff --git a/test/multipart/ie b/test/multipart/ie new file mode 100644 index 0000000..eae06ab --- /dev/null +++ b/test/multipart/ie @@ -0,0 +1,6 @@ +--AaB03x +Content-Disposition: form-data; name="files"; filename="C:\Documents and Settings\Administrator\Desktop\file1.txt" +Content-Type: text/plain + +contents +--AaB03x-- diff --git a/test/spec_rack_utils.rb b/test/spec_rack_utils.rb index 435ea52..f16ac4c 100644 --- a/test/spec_rack_utils.rb +++ b/test/spec_rack_utils.rb @@ -29,7 +29,7 @@ context "Rack::Utils" do Rack::Utils.parse_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F"). should.equal "my weird field" => "q1!2\"'w$5&7/z8)?" end - + specify "should build query strings correctly" do Rack::Utils.build_query("foo" => "bar").should.equal "foo=bar" Rack::Utils.build_query("foo" => ["bar", "quux"]). @@ -184,6 +184,19 @@ context "Rack::Utils::Multipart" do params["files"][:tempfile].read.length.should.equal 26473 end + specify "should parse IE multipart upload and clean up filename" do + env = Rack::MockRequest.env_for("/", multipart_fixture(:ie)) + params = Rack::Utils::Multipart.parse_multipart(env) + params["files"][:type].should.equal "text/plain" + params["files"][:filename].should.equal "file1.txt" + params["files"][:head].should.equal "Content-Disposition: form-data; " + + "name=\"files\"; " + + 'filename="C:\Documents and Settings\Administrator\Desktop\file1.txt"' + + "\r\nContent-Type: text/plain\r\n" + params["files"][:name].should.equal "files" + params["files"][:tempfile].read.should.equal "contents" + end + specify "rewinds input after parsing upload" do options = multipart_fixture(:text) input = options[:input] -- 1.6.0.4