我有兩個路徑:應用程序根路徑和目標路徑。確保目標路徑是應用程序根路徑的子項的最簡單方法是什麼?確定一個路徑是否在Ruby的另一個路徑下?
基本上我的服務器會顯示用戶提供的目標路徑。但我想限制我的服務器,所以只有應用程序根路徑下的文件是可顯示的。所以我想檢查目標路徑是否在根路徑下。
根路徑可以包含嵌套的目錄。
我有兩個路徑:應用程序根路徑和目標路徑。確保目標路徑是應用程序根路徑的子項的最簡單方法是什麼?確定一個路徑是否在Ruby的另一個路徑下?
基本上我的服務器會顯示用戶提供的目標路徑。但我想限制我的服務器,所以只有應用程序根路徑下的文件是可顯示的。所以我想檢查目標路徑是否在根路徑下。
根路徑可以包含嵌套的目錄。
另一種方式:
def child?(root, target)
raise ArgumentError, "target.size=#{target.size} < #{root.size} = root.size"\
if target.size < root.size
target[0...root.size] == root &&
(target.size == root.size || target[root.size] == ?/)
end
root = "/root/app"
p child?(root, "/root/app/some/path") # => true
p child?(root, "/root/apple") # => false
p child?(root, "/root/app") # => true
p child?(root, "/root") # => ArgumentError: target.size = 5 < 9 = root.size
怎麼樣一個正則表達式:
root = "/root/app/"
target = "/root/app/some/path"
target =~ /^#{root}/
你可以使用Pathname#realdirpath
,如果需要的相對路徑轉換爲絕對路徑。
或許有點效率低下,而且萬無一失
require 'find'
Find.find(root).include?(target)
您沒有提供任何的使用情況,因此,我認爲以下變量適用於你的情況
root = "/var/www/"
target = "/var/www/logs/something/else.log"
您可以使用正則表達式或更簡單String#start_with?
target.start_with?(root)
如果'target =「/ var/www/.../...怎麼辦/ etc/password「'?使用'File.realpath(target).start_with?(root)'更安全' –
標題爲「路徑不是字符串」:https://robm.me.uk/ruby/2014/01/18/pathname.html –
爲了避免路徑注射可以使用File.path方法:
[21] pry(main)> path_1 = File.path(Rails.root.join('public', '../config/routes.rb'))
=> "/project_path/config/routes.rb"
[22] pry(main)> path_2 = File.path(Rails.root.join('public', 'robots.txt'))
=> "/project_path/public/robots.txt"
[24] pry(main)> path_1.include?(Rails.root.join('public').to_s)
=> false
[25] pry(main)> path_2.include?(Rails.root.join('public').to_s)
=> true
這樣做實際上回答OP的問題? – RealCheeseLord
嗯,我想這應該可以解決像主目錄或「東西〜/../../../ PWD 」。但我認爲這是可行的。 – lulalala
我添加了一個註釋來使用路徑名方法來幫助 –
如果目標是'「/ root/apple」'? – Max