2014-01-21 41 views
4

我有两个路径:应用程序根路径和目标路径。确保目标路径是应用程序根路径的子项的最简单方法是什么?确定一个路径是否在Ruby的另一个路径下?

基本上我的服务器会显示用户提供的目标路径。但我想限制我的服务器,所以只有应用程序根路径下的文件是可显示的。所以我想检查目标路径是否在根路径下。

根路径可以包含嵌套的目录。

回答

3

另一种方式:

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 
2

怎么样一个正则表达式:

root = "/root/app/" 
target = "/root/app/some/path" 

target =~ /^#{root}/ 

你可以使用Pathname#realdirpath,如果需要的相对路径转换为绝对路径。

+0

嗯,我想这应该可以解决像主目录或“东西〜/../../../ PWD ”。但我认为这是可行的。 – lulalala

+0

我添加了一个注释来使用路径名方法来帮助 –

+3

如果目标是'“/ root/apple”'? – Max

2

或许有点效率低下,而且万无一失

require 'find' 
Find.find(root).include?(target) 
1

您没有提供任何的使用情况,因此,我认为以下变量适用于你的情况

root = "/var/www/" 
target = "/var/www/logs/something/else.log" 

您可以使用正则表达式或更简单String#start_with?

target.start_with?(root) 
+2

如果'target =“/ var/www/.../...怎么办/ etc/password“'?使用'File.realpath(target).start_with?(root)'更安全' –

+0

标题为“路径不是字符串”:https://robm.me.uk/ruby/2014/01/18/pathname.html –

0

为了避免路径注射可以使用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 
+0

这样做实际上回答OP的问题? – RealCheeseLord

相关问题