Skip to content

Commit

Permalink
Replaced File.expand_path with custom expand_path that works also on …
Browse files Browse the repository at this point in the history
…windows.
  • Loading branch information
david-s-anderson committed Aug 10, 2013
1 parent fa41abf commit dfb1c3b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 12 deletions.
1 change: 1 addition & 0 deletions lib/ftpd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module ListFormat
autoload :FtpServer, 'ftpd/ftp_server'
autoload :InsecureCertificate, 'ftpd/insecure_certificate'
autoload :NullLogger, 'ftpd/null_logger'
autoload :PathHelper, 'ftpd/path_helper'
autoload :ReadOnlyDiskFileSystem, 'ftpd/read_only_disk_file_system'
autoload :Server, 'ftpd/server'
autoload :Session, 'ftpd/session'
Expand Down
28 changes: 28 additions & 0 deletions lib/ftpd/path_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Ftpd
module PathHelper
def self.expand_path(file_name, dir_string)
File.expand_path(file_name, dir_string)

if file_name.start_with?("/") or file_name.start_with?("\\") then
parts = file_name.split(/[\/\\]/)
else
parts = dir_string.split(/[\/\\]/) + file_name.split(/[\/\\]/)
end

new_parts = []
parts.each do |p|
case p
when ""
when "."
when ".."
new_parts.pop
else
new_parts << p
end
end

"/" + new_parts.join("/")
end
end
end

24 changes: 12 additions & 12 deletions lib/ftpd/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def cmd_stor(argument)
ensure_file_system_supports :write
path = argument
syntax_error unless path
path = File.expand_path(path, @name_prefix)
path = PathHelper.expand_path(path, @name_prefix)
ensure_accessible path
ensure_exists File.dirname(path)
contents = receive_file
Expand All @@ -146,7 +146,7 @@ def cmd_stou(argument)
ensure_logged_in
ensure_file_system_supports :write
path = argument || 'ftpd'
path = File.expand_path(path, @name_prefix)
path = PathHelper.expand_path(path, @name_prefix)
path = unique_path(path)
ensure_accessible path
ensure_exists File.dirname(path)
Expand All @@ -162,7 +162,7 @@ def cmd_appe(argument)
ensure_file_system_supports :append
path = argument
syntax_error unless path
path = File.expand_path(path, @name_prefix)
path = PathHelper.expand_path(path, @name_prefix)
ensure_accessible path
contents = receive_file
@file_system.append path, contents
Expand All @@ -176,7 +176,7 @@ def cmd_retr(argument)
ensure_file_system_supports :read
path = argument
syntax_error unless path
path = File.expand_path(path, @name_prefix)
path = PathHelper.expand_path(path, @name_prefix)
ensure_accessible path
ensure_exists path
contents = @file_system.read(path)
Expand All @@ -189,7 +189,7 @@ def cmd_dele(argument)
ensure_file_system_supports :delete
path = argument
error "501 Path required" unless path
path = File.expand_path(path, @name_prefix)
path = PathHelper.expand_path(path, @name_prefix)
ensure_accessible path
ensure_exists path
@file_system.delete path
Expand All @@ -203,7 +203,7 @@ def cmd_list(argument)
ensure_file_system_supports :file_info
path = argument
path ||= '.'
path = File.expand_path(path, @name_prefix)
path = PathHelper.expand_path(path, @name_prefix)
transmit_file(list(path), 'A')
end
end
Expand All @@ -214,7 +214,7 @@ def cmd_nlst(argument)
ensure_file_system_supports :dir
path = argument
path ||= '.'
path = File.expand_path(path, @name_prefix)
path = PathHelper.expand_path(path, @name_prefix)
transmit_file(name_list(path), 'A')
end
end
Expand Down Expand Up @@ -283,7 +283,7 @@ def cmd_pasv(argument)

def cmd_cwd(argument)
ensure_logged_in
path = File.expand_path(argument, @name_prefix)
path = PathHelper.expand_path(argument, @name_prefix)
ensure_accessible path
ensure_exists path
ensure_directory path
Expand All @@ -296,7 +296,7 @@ def cmd_mkd(argument)
syntax_error unless argument
ensure_logged_in
ensure_file_system_supports :mkdir
path = File.expand_path(argument, @name_prefix)
path = PathHelper.expand_path(argument, @name_prefix)
ensure_accessible path
ensure_exists File.dirname(path)
ensure_directory File.dirname(path)
Expand All @@ -310,7 +310,7 @@ def cmd_rmd(argument)
syntax_error unless argument
ensure_logged_in
ensure_file_system_supports :rmdir
path = File.expand_path(argument, @name_prefix)
path = PathHelper.expand_path(argument, @name_prefix)
ensure_accessible path
ensure_exists path
ensure_directory path
Expand Down Expand Up @@ -423,7 +423,7 @@ def cmd_rnfr(argument)
ensure_logged_in
ensure_file_system_supports :rename
syntax_error unless argument
from_path = File.expand_path(argument, @name_prefix)
from_path = PathHelper.expand_path(argument, @name_prefix)
ensure_accessible from_path
ensure_exists from_path
@rename_from_path = from_path
Expand All @@ -435,7 +435,7 @@ def cmd_rnto(argument)
ensure_logged_in
ensure_file_system_supports :rename
syntax_error unless argument
to_path = File.expand_path(argument, @name_prefix)
to_path = PathHelper.expand_path(argument, @name_prefix)
ensure_accessible to_path
ensure_does_not_exist to_path
@file_system.rename(@rename_from_path, to_path)
Expand Down
41 changes: 41 additions & 0 deletions spec/path_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require File.expand_path('spec_helper', File.dirname(__FILE__))

module Ftpd
describe PathHelper do
describe :expand_path do
it "should return root path if given two empty paths" do
PathHelper.expand_path("", "").should == "/"
end

it "should return parent if file_name is .." do
PathHelper.expand_path("..", "/foo/bar").should == "/foo"
end


it "should return same if file_name is ." do
PathHelper.expand_path(".", "/foo/bar").should == "/foo/bar"
end

it "should return subdir with single element file_name" do
PathHelper.expand_path("baz", "/foo/bar").should == "/foo/bar/baz"
end

it "should return subdir with file_name starting with ./" do
PathHelper.expand_path("./baz", "/foo/bar").should == "/foo/bar/baz"
end

it "should handle incorporated .. in file_name" do
PathHelper.expand_path("../baz", "/foo/bar").should == "/foo/baz"
end

it "should handle extra .. in file_name" do
PathHelper.expand_path("../../../../../baz", "/foo/bar").should == "/baz"
end

it "it should return file_name if it is absolute path" do
PathHelper.expand_path("/foo/bar/baz", "/should/ignore/me").should == "/foo/bar/baz"
end
end
end
end

1 comment on commit dfb1c3b

@wconrad
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@david-s-anderson, @m0x is investigating multiple problems with FTPD under Windows, one of which is with the file system. I wonder if this patch fixes any of the issues that @m0x is seeing. We're discussing it over here.

Please sign in to comment.