aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew White <pixeltrix@users.noreply.github.com>2014-10-14 20:06:36 +0100
committerAndrew White <pixeltrix@users.noreply.github.com>2014-10-14 20:06:36 +0100
commit6bb040b55748269dd2cb2ae3a36fa54ca7c70c5e (patch)
treeaeee85e344150e9faeb9be2e6f33447c22f0b6ea
parent5a5073301c66b7999ad25c18a22d44922002c689 (diff)
parent3041bb2a942711d7e4919795c9aff0d5d568568b (diff)
downloadrails-6bb040b55748269dd2cb2ae3a36fa54ca7c70c5e.tar.gz
rails-6bb040b55748269dd2cb2ae3a36fa54ca7c70c5e.tar.bz2
rails-6bb040b55748269dd2cb2ae3a36fa54ca7c70c5e.zip
Merge pull request #17220 from Bounga/fix_journey_rfc_3986_compliance
Improve Journey compliance to RFC 3986
-rw-r--r--actionpack/CHANGELOG.md10
-rw-r--r--actionpack/lib/action_dispatch/journey/scanner.rb10
-rw-r--r--actionpack/test/journey/route/definition/scanner_test.rb25
3 files changed, 34 insertions, 11 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index de9722c392..64105934cd 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,13 @@
+* Improve Journey compliance to RFC 3986
+
+ The scanner in Journey failed to recognize routes that use literals
+ from the sub-delims section of RFC 3986. It's now able to parse those
+ authorized delimiters and route as expected.
+
+ Fixes #17212
+
+ *Nicolas Cavigneaux*
+
* Deprecate implicit Array conversion for Response objects. It was added
(using `#to_ary`) so we could conveniently use implicit splatting:
diff --git a/actionpack/lib/action_dispatch/journey/scanner.rb b/actionpack/lib/action_dispatch/journey/scanner.rb
index 633be11a2d..ad1cd0f5e8 100644
--- a/actionpack/lib/action_dispatch/journey/scanner.rb
+++ b/actionpack/lib/action_dispatch/journey/scanner.rb
@@ -39,18 +39,18 @@ module ActionDispatch
[:SLASH, text]
when text = @ss.scan(/\*\w+/)
[:STAR, text]
- when text = @ss.scan(/\(/)
+ when text = @ss.scan(/(?<!\\)\(/)
[:LPAREN, text]
- when text = @ss.scan(/\)/)
+ when text = @ss.scan(/(?<!\\)\)/)
[:RPAREN, text]
when text = @ss.scan(/\|/)
[:OR, text]
when text = @ss.scan(/\./)
[:DOT, text]
- when text = @ss.scan(/:\w+/)
+ when text = @ss.scan(/(?<!\\):\w+/)
[:SYMBOL, text]
- when text = @ss.scan(/[\w%\-~]+/)
- [:LITERAL, text]
+ when text = @ss.scan(/(?:[\w%\-~!$&'*+,;=@]|\\:|\\\(|\\\))+/)
+ [:LITERAL, text.gsub('\\', '')]
# any char
when text = @ss.scan(/./)
[:LITERAL, text]
diff --git a/actionpack/test/journey/route/definition/scanner_test.rb b/actionpack/test/journey/route/definition/scanner_test.rb
index 624e6df51a..7a510f1e07 100644
--- a/actionpack/test/journey/route/definition/scanner_test.rb
+++ b/actionpack/test/journey/route/definition/scanner_test.rb
@@ -11,12 +11,25 @@ module ActionDispatch
# /page/:id(/:action)(.:format)
def test_tokens
[
- ['/', [[:SLASH, '/']]],
- ['*omg', [[:STAR, '*omg']]],
- ['/page', [[:SLASH, '/'], [:LITERAL, 'page']]],
- ['/~page', [[:SLASH, '/'], [:LITERAL, '~page']]],
- ['/pa-ge', [[:SLASH, '/'], [:LITERAL, 'pa-ge']]],
- ['/:page', [[:SLASH, '/'], [:SYMBOL, ':page']]],
+ ['/', [[:SLASH, '/']]],
+ ['*omg', [[:STAR, '*omg']]],
+ ['/page', [[:SLASH, '/'], [:LITERAL, 'page']]],
+ ['/page!', [[:SLASH, '/'], [:LITERAL, 'page!']]],
+ ['/page$', [[:SLASH, '/'], [:LITERAL, 'page$']]],
+ ['/page&', [[:SLASH, '/'], [:LITERAL, 'page&']]],
+ ["/page'", [[:SLASH, '/'], [:LITERAL, "page'"]]],
+ ['/page*', [[:SLASH, '/'], [:LITERAL, 'page*']]],
+ ['/page+', [[:SLASH, '/'], [:LITERAL, 'page+']]],
+ ['/page,', [[:SLASH, '/'], [:LITERAL, 'page,']]],
+ ['/page;', [[:SLASH, '/'], [:LITERAL, 'page;']]],
+ ['/page=', [[:SLASH, '/'], [:LITERAL, 'page=']]],
+ ['/page@', [[:SLASH, '/'], [:LITERAL, 'page@']]],
+ ['/page\:', [[:SLASH, '/'], [:LITERAL, 'page:']]],
+ ['/page\(', [[:SLASH, '/'], [:LITERAL, 'page(']]],
+ ['/page\)', [[:SLASH, '/'], [:LITERAL, 'page)']]],
+ ['/~page', [[:SLASH, '/'], [:LITERAL, '~page']]],
+ ['/pa-ge', [[:SLASH, '/'], [:LITERAL, 'pa-ge']]],
+ ['/:page', [[:SLASH, '/'], [:SYMBOL, ':page']]],
['/(:page)', [
[:SLASH, '/'],
[:LPAREN, '('],