aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/journey/scanner.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/journey/scanner.rb')
-rw-r--r--actionpack/lib/action_dispatch/journey/scanner.rb44
1 files changed, 27 insertions, 17 deletions
diff --git a/actionpack/lib/action_dispatch/journey/scanner.rb b/actionpack/lib/action_dispatch/journey/scanner.rb
index 19e0bc03d6..2a075862e9 100644
--- a/actionpack/lib/action_dispatch/journey/scanner.rb
+++ b/actionpack/lib/action_dispatch/journey/scanner.rb
@@ -1,4 +1,6 @@
-require 'strscan'
+# frozen_string_literal: true
+
+require "strscan"
module ActionDispatch
module Journey # :nodoc:
@@ -32,27 +34,35 @@ module ActionDispatch
private
+ # takes advantage of String @- deduping capabilities in Ruby 2.5 upwards
+ # see: https://bugs.ruby-lang.org/issues/13077
+ def dedup_scan(regex)
+ r = @ss.scan(regex)
+ r ? -r : nil
+ end
+
def scan
case
# /
- when text = @ss.scan(/\//)
- [:SLASH, text]
- when text = @ss.scan(/\*\w+/)
- [:STAR, text]
- when text = @ss.scan(/(?<!\\)\(/)
- [:LPAREN, text]
- when text = @ss.scan(/(?<!\\)\)/)
- [:RPAREN, text]
- when text = @ss.scan(/\|/)
- [:OR, text]
- when text = @ss.scan(/\./)
- [:DOT, text]
- when text = @ss.scan(/(?<!\\):\w+/)
+ when @ss.skip(/\//)
+ [:SLASH, "/"]
+ when @ss.skip(/\(/)
+ [:LPAREN, "("]
+ when @ss.skip(/\)/)
+ [:RPAREN, ")"]
+ when @ss.skip(/\|/)
+ [:OR, "|"]
+ when @ss.skip(/\./)
+ [:DOT, "."]
+ when text = dedup_scan(/:\w+/)
[:SYMBOL, text]
- when text = @ss.scan(/(?:[\w%\-~!$&'*+,;=@]|\\:|\\\(|\\\))+/)
- [:LITERAL, text.tr('\\', '')]
+ when text = dedup_scan(/\*\w+/)
+ [:STAR, text]
+ when text = @ss.scan(/(?:[\w%\-~!$&'*+,;=@]|\\[:()])+/)
+ text.tr! "\\", ""
+ [:LITERAL, -text]
# any char
- when text = @ss.scan(/./)
+ when text = dedup_scan(/./)
[:LITERAL, text]
end
end