mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Allow multiline to be passed in routes when using wildcards.
Fixed a bug in action_dispatch where routes with newlines weren't detected when using wildcard segments
This commit is contained in:
parent
e7fb2b114e
commit
4df32bc139
7 changed files with 64 additions and 15 deletions
|
@ -53,7 +53,7 @@ module ActionDispatch
|
||||||
if formatted != false
|
if formatted != false
|
||||||
# Add a constraint for wildcard route to make it non-greedy and
|
# Add a constraint for wildcard route to make it non-greedy and
|
||||||
# match the optional format part of the route by default.
|
# match the optional format part of the route by default.
|
||||||
wildcard_options[node.name.to_sym] ||= /.+?/
|
wildcard_options[node.name.to_sym] ||= /.+?/m
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,8 @@ module ActionDispatch
|
||||||
# as requirements.
|
# as requirements.
|
||||||
def requirements
|
def requirements
|
||||||
@defaults.merge(path.requirements).delete_if { |_, v|
|
@defaults.merge(path.requirements).delete_if { |_, v|
|
||||||
/.+?/ == v
|
/.+?/ == v ||
|
||||||
|
/.+?/m == v
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ module ActionDispatch
|
||||||
end
|
end
|
||||||
|
|
||||||
requirements, conditions = split_constraints ast.path_params, constraints
|
requirements, conditions = split_constraints ast.path_params, constraints
|
||||||
verify_regexp_requirements requirements.map(&:last).grep(Regexp)
|
verify_regexp_requirements requirements, ast.wildcard_options
|
||||||
|
|
||||||
formats = normalize_format(formatted)
|
formats = normalize_format(formatted)
|
||||||
|
|
||||||
|
@ -246,14 +246,18 @@ module ActionDispatch
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def verify_regexp_requirements(requirements)
|
def verify_regexp_requirements(requirements, wildcard_options)
|
||||||
requirements.each do |requirement|
|
requirements.each do |requirement, regex|
|
||||||
if ANCHOR_CHARACTERS_REGEX.match?(requirement.source)
|
next unless regex.is_a? Regexp
|
||||||
|
|
||||||
|
if ANCHOR_CHARACTERS_REGEX.match?(regex.source)
|
||||||
raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
|
raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
if requirement.multiline?
|
if regex.multiline?
|
||||||
raise ArgumentError, "Regexp multiline option is not allowed in routing requirements: #{requirement.inspect}"
|
next if wildcard_options.key?(requirement)
|
||||||
|
|
||||||
|
raise ArgumentError, "Regexp multiline option is not allowed in routing requirements: #{regex.inspect}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -624,6 +624,34 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
|
||||||
url_for(rs, controller: "content", action: "show_file", path: %w(pages boo))
|
url_for(rs, controller: "content", action: "show_file", path: %w(pages boo))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_escapes_newline_character_for_dynamic_path
|
||||||
|
rs.draw do
|
||||||
|
get "/dynamic/:dynamic_segment" => "subpath_books#show", as: :dynamic
|
||||||
|
|
||||||
|
ActiveSupport::Deprecation.silence do
|
||||||
|
get ":controller/:action/:id"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
results = rs.recognize_path("/dynamic/a%0Anewline")
|
||||||
|
assert(results, "Recognition should have succeeded")
|
||||||
|
assert_equal("a\nnewline", results[:dynamic_segment])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_escapes_newline_character_for_wildcard_path
|
||||||
|
rs.draw do
|
||||||
|
get "/wildcard/*wildcard_segment" => "subpath_books#show", as: :wildcard
|
||||||
|
|
||||||
|
ActiveSupport::Deprecation.silence do
|
||||||
|
get ":controller/:action/:id"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
results = rs.recognize_path("/wildcard/a%0Anewline")
|
||||||
|
assert(results, "Recognition should have succeeded")
|
||||||
|
assert_equal("a\nnewline", results[:wildcard_segment])
|
||||||
|
end
|
||||||
|
|
||||||
def test_dynamic_recall_paths_allowed
|
def test_dynamic_recall_paths_allowed
|
||||||
rs.draw do
|
rs.draw do
|
||||||
get "*path" => "content#show_file"
|
get "*path" => "content#show_file"
|
||||||
|
|
|
@ -92,7 +92,7 @@ module ActionDispatch
|
||||||
scope = Mapper::Scope.new({})
|
scope = Mapper::Scope.new({})
|
||||||
ast = Journey::Parser.parse "/store/:name(*rest)"
|
ast = Journey::Parser.parse "/store/:name(*rest)"
|
||||||
m = Mapper::Mapping.build(scope, FakeSet.new, ast, "foo", "bar", nil, [:get], nil, {}, true, options)
|
m = Mapper::Mapping.build(scope, FakeSet.new, ast, "foo", "bar", nil, [:get], nil, {}, true, options)
|
||||||
assert_equal(/.+?/, m.requirements[:rest])
|
assert_equal(/.+?/m, m.requirements[:rest])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_via_scope
|
def test_via_scope
|
||||||
|
@ -137,7 +137,7 @@ module ActionDispatch
|
||||||
mapper = Mapper.new fakeset
|
mapper = Mapper.new fakeset
|
||||||
mapper.get "/*path", to: "pages#show"
|
mapper.get "/*path", to: "pages#show"
|
||||||
assert_equal "/*path(.:format)", fakeset.asts.first.to_s
|
assert_equal "/*path(.:format)", fakeset.asts.first.to_s
|
||||||
assert_equal(/.+?/, fakeset.requirements.first[:path])
|
assert_equal(/.+?/m, fakeset.requirements.first[:path])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_map_wildcard_with_other_element
|
def test_map_wildcard_with_other_element
|
||||||
|
@ -145,7 +145,7 @@ module ActionDispatch
|
||||||
mapper = Mapper.new fakeset
|
mapper = Mapper.new fakeset
|
||||||
mapper.get "/*path/foo/:bar", to: "pages#show"
|
mapper.get "/*path/foo/:bar", to: "pages#show"
|
||||||
assert_equal "/*path/foo/:bar(.:format)", fakeset.asts.first.to_s
|
assert_equal "/*path/foo/:bar(.:format)", fakeset.asts.first.to_s
|
||||||
assert_equal(/.+?/, fakeset.requirements.first[:path])
|
assert_equal(/.+?/m, fakeset.requirements.first[:path])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_map_wildcard_with_multiple_wildcard
|
def test_map_wildcard_with_multiple_wildcard
|
||||||
|
@ -153,8 +153,8 @@ module ActionDispatch
|
||||||
mapper = Mapper.new fakeset
|
mapper = Mapper.new fakeset
|
||||||
mapper.get "/*foo/*bar", to: "pages#show"
|
mapper.get "/*foo/*bar", to: "pages#show"
|
||||||
assert_equal "/*foo/*bar(.:format)", fakeset.asts.first.to_s
|
assert_equal "/*foo/*bar(.:format)", fakeset.asts.first.to_s
|
||||||
assert_equal(/.+?/, fakeset.requirements.first[:foo])
|
assert_equal(/.+?/m, fakeset.requirements.first[:foo])
|
||||||
assert_equal(/.+?/, fakeset.requirements.first[:bar])
|
assert_equal(/.+?/m, fakeset.requirements.first[:bar])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_map_wildcard_with_format_false
|
def test_map_wildcard_with_format_false
|
||||||
|
|
|
@ -149,6 +149,22 @@ module ActionDispatch
|
||||||
assert_equal "/users/1.json", url_helpers.user_path(1, :json)
|
assert_equal "/users/1.json", url_helpers.user_path(1, :json)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "escape new line for dynamic params" do
|
||||||
|
draw do
|
||||||
|
get "/dynamic/:dynamic_segment", to: SimpleApp.new("foo#index"), as: :dynamic
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "/dynamic/a%0Anewline", url_helpers.dynamic_path(dynamic_segment: "a\nnewline")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "escape new line for wildcard params" do
|
||||||
|
draw do
|
||||||
|
get "/wildcard/*wildcard_segment", to: SimpleApp.new("foo#index"), as: :wildcard
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "/wildcard/a%0Anewline", url_helpers.wildcard_path(wildcard_segment: "a\nnewline")
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def draw(&block)
|
def draw(&block)
|
||||||
@set.draw(&block)
|
@set.draw(&block)
|
||||||
|
|
|
@ -67,7 +67,7 @@ module ActionDispatch
|
||||||
ast = Ast.new(tree, true)
|
ast = Ast.new(tree, true)
|
||||||
|
|
||||||
wildcard_options = ast.wildcard_options
|
wildcard_options = ast.wildcard_options
|
||||||
assert_equal %r{.+?}, wildcard_options[:glob]
|
assert_equal %r{.+?}m, wildcard_options[:glob]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_wildcard_options_when_false
|
def test_wildcard_options_when_false
|
||||||
|
@ -83,7 +83,7 @@ module ActionDispatch
|
||||||
ast = Ast.new(tree, nil)
|
ast = Ast.new(tree, nil)
|
||||||
|
|
||||||
wildcard_options = ast.wildcard_options
|
wildcard_options = ast.wildcard_options
|
||||||
assert_equal %r{.+?}, wildcard_options[:glob]
|
assert_equal %r{.+?}m, wildcard_options[:glob]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue