我有两条路径:应用程序根路径和目标路径。确保目标路径是应用程序根路径的子节点的最简单方法是什么?
基本上,用户提供的目标路径将由我的服务器显示。但我想约束我的服务器,因此只有应用程序根路径下的文件可以显示。所以我想检查目标路径是否在根路径下。
根路径可以包含嵌套目录。
答案 0 :(得分: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
答案 1 :(得分:2)
也许效率低下但是万无一失
require 'find'
Find.find(root).include?(target)
答案 2 :(得分:1)
正则表达式怎么样:
root = "/root/app/"
target = "/root/app/some/path"
target =~ /^#{root}/
如果需要,您可以使用Pathname#realdirpath
将相对路径转换为绝对路径。
答案 3 :(得分:1)
您尚未提供任何用例,因此我假设以下变量适用于您的案例
root = "/var/www/"
target = "/var/www/logs/something/else.log"
您可以使用正则表达式或更简单的String#start_with?
target.start_with?(root)
答案 4 :(得分: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
答案 5 :(得分:0)
我喜欢Pathname#ascend
:
ancestor = Pathnew.new(path1).realdirpath
descendant = Pathnew.new(path2).realdirpath
descendant.ascend { |path| break true if path == ancestor } || false
(Pathname#==
通过字符串比较工作,因此它有助于先使用 #realdirpath
清理您的输入。)