Module: Pray::PathSafety

Defined in:
lib/pray/path_safety.rb

Class Method Summary collapse

Class Method Details

.join_under_root(root, *segments) ⇒ Object



15
16
17
18
19
20
21
# File 'lib/pray/path_safety.rb', line 15

def join_under_root(root, *segments)
  root_path = Pathname.new(File.expand_path(root)).cleanpath
  candidate = root_path.join(*segments).cleanpath
  return candidate.to_s if path_under_root?(root_path.to_s, candidate.to_s)

  nil
end

.path_under_root?(root, candidate) ⇒ Boolean

Returns:

  • (Boolean)


9
10
11
12
13
# File 'lib/pray/path_safety.rb', line 9

def path_under_root?(root, candidate)
  root_path = Pathname.new(File.expand_path(root)).cleanpath
  candidate_path = Pathname.new(File.expand_path(candidate)).cleanpath
  candidate_path == root_path || candidate_path.to_s.start_with?("#{root_path}#{File::SEPARATOR}")
end

.reject_unsafe_package_name!(package_name) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/pray/path_safety.rb', line 23

def reject_unsafe_package_name!(package_name)
  if package_name.nil? || package_name.empty? || package_name.include?("\0") || package_name.include?("\\") ||
      package_name.include?("..")
    raise Error.resolution("invalid package name: #{package_name.inspect}")
  end

  package_name
end

.sanitize_relative_path(path) ⇒ Object



32
33
34
35
36
37
38
39
# File 'lib/pray/path_safety.rb', line 32

def sanitize_relative_path(path)
  cleaned = path.to_s.delete_prefix("/").tr("\\", "/")
  if cleaned.empty? || cleaned.include?("\0") || cleaned.split("/").include?("..")
    raise Error.resolution("unsafe relative path: #{path.inspect}")
  end

  cleaned
end