class ActiveStorage::Service::DiskService

def path_for(key) # :nodoc:

:nodoc:
path_for or make_path_for -- never construct paths from +root+ directly.
path-traversal protection is enforced here. New methods that touch the filesystem MUST use
make_path_for, which delegates here). This is the primary filesystem security check: all
Every filesystem operation in DiskService resolves paths through this method (or through
def path_for(key) # :nodoc:
  if key.blank?
    raise ActiveStorage::InvalidKeyError, "key is blank"
  end
  # Reject keys with dot segments as defense in depth. This prevents path traversal both outside
  # and within the storage root. The root containment check below is a more fundamental check on
  # path traversal outside of the disk service root.
  begin
    if key.split("/").intersect?(%w[. ..])
      raise ActiveStorage::InvalidKeyError, "key has path traversal segments"
    end
  rescue Encoding::CompatibilityError
    raise ActiveStorage::InvalidKeyError, "key has incompatible encoding"
  end
  begin
    path = File.expand_path(File.join(root, folder_for(key), key))
  rescue ArgumentError
    # ArgumentError catches null bytes
    raise ActiveStorage::InvalidKeyError, "key is an invalid string"
  end
  # The resolved path must be inside the root directory.
  unless path.start_with?(File.expand_path(root) + "/")
    raise ActiveStorage::InvalidKeyError, "key is outside of disk service root"
  end
  path
end