diff options
author | Nicolas Cavigneaux <nico@bounga.org> | 2014-10-09 15:06:26 +0200 |
---|---|---|
committer | Nicolas Cavigneaux <nico@bounga.org> | 2014-10-14 16:42:50 +0200 |
commit | 3041bb2a942711d7e4919795c9aff0d5d568568b (patch) | |
tree | aeee85e344150e9faeb9be2e6f33447c22f0b6ea | |
parent | 5a5073301c66b7999ad25c18a22d44922002c689 (diff) | |
download | rails-3041bb2a942711d7e4919795c9aff0d5d568568b.tar.gz rails-3041bb2a942711d7e4919795c9aff0d5d568568b.tar.bz2 rails-3041bb2a942711d7e4919795c9aff0d5d568568b.zip |
Improve Journey compliance to RFC 3986
The scanner in Journey fails to recognize routes that use literals
from the sub-delims section of RFC 3986.
This commit enhance the compatibility of Journey with the RFC by
adding support of authorized delimiters to the scanner.
Fix #17212
-rw-r--r-- | actionpack/CHANGELOG.md | 10 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/journey/scanner.rb | 10 | ||||
-rw-r--r-- | actionpack/test/journey/route/definition/scanner_test.rb | 25 |
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, '('], |