From a189b4b3770930cf7a38fa53dd533ef074ced501 Mon Sep 17 00:00:00 2001 From: Toshi MARUYAMA Date: Mon, 21 Feb 2011 12:10:39 +0000 Subject: [PATCH] scm: filesystem: refactor for path encoding (#2274). git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4907 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- .../scm/adapters/filesystem_adapter.rb | 59 +++++++++++-------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/lib/redmine/scm/adapters/filesystem_adapter.rb b/lib/redmine/scm/adapters/filesystem_adapter.rb index b88892b5e..477629536 100644 --- a/lib/redmine/scm/adapters/filesystem_adapter.rb +++ b/lib/redmine/scm/adapters/filesystem_adapter.rb @@ -23,7 +23,7 @@ require 'find' module Redmine module Scm - module Adapters + module Adapters class FilesystemAdapter < AbstractAdapter class << self @@ -34,6 +34,7 @@ module Redmine def initialize(url, root_url=nil, login=nil, password=nil) @url = with_trailling_slash(url) + @path_encoding = 'UTF-8' end def format_path_ends(path, leading=true, trailling=true) @@ -51,47 +52,59 @@ module Redmine rescue CommandFailed return nil end - + def entries(path="", identifier=nil) entries = Entries.new - Dir.new(target(path)).each do |e| - relative_path = format_path_ends((format_path_ends(path, - false, - true) + e), - false,false) - target = target(relative_path) - entries << - Entry.new({ :name => File.basename(e), + trgt_utf8 = target(path) + trgt = scm_iconv(@path_encoding, 'UTF-8', trgt_utf8) + Dir.new(trgt).each do |e1| + e_utf8 = scm_iconv('UTF-8', @path_encoding, e1) + relative_path_utf8 = format_path_ends((format_path_ends(path,false,true) + e_utf8),false,false) + t1_utf8 = target(relative_path_utf8) + t1 = scm_iconv(@path_encoding, 'UTF-8', t1_utf8) + relative_path = scm_iconv(@path_encoding, 'UTF-8', relative_path_utf8) + e1 = scm_iconv(@path_encoding, 'UTF-8', e_utf8) + if File.exist?(t1) and # paranoid test + %w{file directory}.include?(File.ftype(t1)) and # avoid special types + not File.basename(e1).match(/^\.+$/) # avoid . and .. + p1 = File.readable?(t1) ? relative_path : "" + utf_8_path = scm_iconv('UTF-8', @path_encoding, p1) + entries << + Entry.new({ :name => scm_iconv('UTF-8', @path_encoding, File.basename(e1)), # below : list unreadable files, but dont link them. - :path => File.readable?(target) ? relative_path : "", - :kind => (File.directory?(target) ? 'dir' : 'file'), - :size => (File.directory?(target) ? nil : [File.size(target)].pack('l').unpack('L').first), + :path => utf_8_path, + :kind => (File.directory?(t1) ? 'dir' : 'file'), + :size => (File.directory?(t1) ? nil : [File.size(t1)].pack('l').unpack('L').first), :lastrev => - Revision.new({:time => (File.mtime(target)).localtime, - }) - }) if File.exist?(target) and # paranoid test - %w{file directory}.include?(File.ftype(target)) and # avoid special types - not File.basename(e).match(/^\.+$/) # avoid . and .. + Revision.new({:time => (File.mtime(t1)) }) + }) + end end entries.sort_by_name + rescue => err + logger.error "scm: filesystem: error: #{err.message}" + raise CommandFailed.new(err.message) end - + def cat(path, identifier=nil) - File.new(target(path), "rb").read + p = scm_iconv(@path_encoding, 'UTF-8', target(path)) + File.new(p, "rb").read + rescue => err + logger.error "scm: filesystem: error: #{err.message}" + raise CommandFailed.new(err.message) end private - + # AbstractAdapter::target is implicitly made to quote paths. # Here we do not shell-out, so we do not want quotes. def target(path=nil) - #Prevent the use of .. + # Prevent the use of .. if path and !path.match(/(^|\/)\.\.(\/|$)/) return "#{self.url}#{without_leading_slash(path)}" end return self.url end - end end end