1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/actionview/lib/action_view/path_set.rb
John Hawthorn eb52904eb5 Always reject files external to app
Previously, when using `render file:`, it was possible to render files
not only at an absolute path or relative to the current directory, but
relative to ANY view paths. This was probably done for absolutely
maximum compatibility when addressing CVE-2016-0752, but I think is
unlikely to be used in practice.

Tihs commit removes the ability to `render file:` with a path relative
to a non-fallback view path.

Make FallbackResolver.new private

To ensure nobody is making FallbackResolvers other than "/" and "".

Make reject_files_external_... no-op for fallbacks

Because there are only two values used for path: "" and "/", and
File.join("", "") == File.join("/", "") == "/", this method was only
testing that the absolute paths started at "/" (which of course all do).

This commit doesn't change any behaviour, but it makes it explicit that
the FallbackFileSystemResolver works this way.

Remove outside_app_allowed argument

Deprecate find_all_anywhere

This is now equivalent to find_all

Remove outside_app argument

Deprecate find_file for find

Both LookupContext#find_file and PathSet#find_file are now equivalent to
their respective #find methods.
2019-04-03 09:02:28 -07:00

95 lines
2.1 KiB
Ruby

# frozen_string_literal: true
module ActionView #:nodoc:
# = Action View PathSet
#
# This class is used to store and access paths in Action View. A number of
# operations are defined so that you can search among the paths in this
# set and also perform operations on other +PathSet+ objects.
#
# A +LookupContext+ will use a +PathSet+ to store the paths in its context.
class PathSet #:nodoc:
include Enumerable
attr_reader :paths
delegate :[], :include?, :pop, :size, :each, to: :paths
def initialize(paths = [])
@paths = typecast paths
end
def initialize_copy(other)
@paths = other.paths.dup
self
end
def to_ary
paths.dup
end
def compact
PathSet.new paths.compact
end
def +(array)
PathSet.new(paths + array)
end
%w(<< concat push insert unshift).each do |method|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{method}(*args)
paths.#{method}(*typecast(args))
end
METHOD
end
def find(*args)
find_all(*args).first || raise(MissingTemplate.new(self, *args))
end
alias :find_file :find
deprecate :find_file
def find_all(path, prefixes = [], *args)
_find_all path, prefixes, args
end
def exists?(path, prefixes, *args)
find_all(path, prefixes, *args).any?
end
def find_all_with_query(query) # :nodoc:
paths.each do |resolver|
templates = resolver.find_all_with_query(query)
return templates unless templates.empty?
end
[]
end
private
def _find_all(path, prefixes, args)
prefixes = [prefixes] if String === prefixes
prefixes.each do |prefix|
paths.each do |resolver|
templates = resolver.find_all(path, prefix, *args)
return templates unless templates.empty?
end
end
[]
end
def typecast(paths)
paths.map do |path|
case path
when Pathname, String
OptimizedFileSystemResolver.new path.to_s
else
path
end
end
end
end
end