aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-08-16 15:16:45 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2011-08-16 15:28:27 -0700
commit5f94b93279f6d0682fafb237c301302c107a9552 (patch)
treeb98a166df8dd74c123be6bcb3a555ec777f24f1d
parentbfc432574d0b141fd7fe759edfe9b6771dd306bd (diff)
downloadrails-5f94b93279f6d0682fafb237c301302c107a9552.tar.gz
rails-5f94b93279f6d0682fafb237c301302c107a9552.tar.bz2
rails-5f94b93279f6d0682fafb237c301302c107a9552.zip
Properly escape glob characters.
-rw-r--r--actionpack/lib/action_view/template/resolver.rb15
-rw-r--r--actionpack/test/controller/render_test.rb14
-rw-r--r--actionpack/test/fixtures/test/hello_w*rld.erb1
3 files changed, 27 insertions, 3 deletions
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index 7abaa07bc7..e78d3a82be 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -142,8 +142,12 @@ module ActionView
# Helper for building query glob string based on resolver's pattern.
def build_query(path, details)
query = @pattern.dup
- query.gsub!(/\:prefix(\/)?/, path.prefix.empty? ? "" : "#{path.prefix}\\1") # prefix can be empty...
- query.gsub!(/\:action/, path.partial? ? "_#{path.name}" : path.name)
+
+ prefix = path.prefix.empty? ? "" : "#{escape_entry(path.prefix)}\\1"
+ query.gsub!(/\:prefix(\/)?/, prefix)
+
+ partial = escape_entry(path.partial? ? "_#{path.name}" : path.name)
+ query.gsub!(/\:action/, partial)
details.each do |ext, variants|
query.gsub!(/\:#{ext}/, "{#{variants.compact.uniq.join(',')}}")
@@ -152,6 +156,10 @@ module ActionView
File.expand_path(query, @path)
end
+ def escape_entry(entry)
+ entry.gsub(/(\*|\[|\]|\{|\}|\?)/, "\\\\\\1")
+ end
+
# Returns the file mtime from the filesystem.
def mtime(p)
File.mtime(p)
@@ -228,8 +236,9 @@ module ActionView
class OptimizedFileSystemResolver < FileSystemResolver #:nodoc:
def build_query(path, details)
exts = EXTENSIONS.map { |ext| details[ext] }
+ query = escape_entry(File.join(@path, path))
- File.join(@path, path) + exts.map { |ext|
+ query + exts.map { |ext|
"{#{ext.compact.uniq.map { |e| ".#{e}," }.join}}"
}.join
end
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index ce4b407c7d..6bcd606bf4 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -405,6 +405,14 @@ class TestController < ActionController::Base
render :template => "test/hello_world"
end
+ def render_with_explicit_unescaped_template
+ render :template => "test/h*llo_world"
+ end
+
+ def render_with_explicit_escaped_template
+ render :template => "test/hello_w*rld"
+ end
+
def render_with_explicit_string_template
render "test/hello_world"
end
@@ -1057,6 +1065,12 @@ class RenderTest < ActionController::TestCase
assert_response :success
end
+ def test_render_with_explicit_unescaped_template
+ assert_raise(ActionView::MissingTemplate) { get :render_with_explicit_unescaped_template }
+ get :render_with_explicit_escaped_template
+ assert_equal "Hello w*rld!", @response.body
+ end
+
def test_render_with_explicit_string_template
get :render_with_explicit_string_template
assert_equal "<html>Hello world!</html>", @response.body
diff --git a/actionpack/test/fixtures/test/hello_w*rld.erb b/actionpack/test/fixtures/test/hello_w*rld.erb
new file mode 100644
index 0000000000..bc8fa5e0ca
--- /dev/null
+++ b/actionpack/test/fixtures/test/hello_w*rld.erb
@@ -0,0 +1 @@
+Hello w*rld! \ No newline at end of file