actionpack 7.1.5.1 → 8.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +308 -523
- data/README.rdoc +1 -1
- data/lib/abstract_controller/asset_paths.rb +6 -2
- data/lib/abstract_controller/base.rb +104 -105
- data/lib/abstract_controller/caching/fragments.rb +50 -53
- data/lib/abstract_controller/caching.rb +8 -3
- data/lib/abstract_controller/callbacks.rb +70 -62
- data/lib/abstract_controller/collector.rb +7 -7
- data/lib/abstract_controller/deprecator.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +71 -84
- data/lib/abstract_controller/logger.rb +4 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +13 -13
- data/lib/abstract_controller/translation.rb +12 -13
- data/lib/abstract_controller/url_for.rb +8 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +76 -72
- data/lib/action_controller/base.rb +199 -126
- data/lib/action_controller/caching.rb +16 -14
- data/lib/action_controller/deprecator.rb +2 -0
- data/lib/action_controller/form_builder.rb +21 -18
- data/lib/action_controller/log_subscriber.rb +23 -2
- data/lib/action_controller/metal/allow_browser.rb +133 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +217 -175
- data/lib/action_controller/metal/content_security_policy.rb +25 -24
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +72 -63
- data/lib/action_controller/metal/default_headers.rb +5 -3
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
- data/lib/action_controller/metal/exceptions.rb +16 -9
- data/lib/action_controller/metal/flash.rb +13 -14
- data/lib/action_controller/metal/head.rb +15 -11
- data/lib/action_controller/metal/helpers.rb +63 -55
- data/lib/action_controller/metal/http_authentication.rb +209 -201
- data/lib/action_controller/metal/implicit_render.rb +17 -15
- data/lib/action_controller/metal/instrumentation.rb +16 -14
- data/lib/action_controller/metal/live.rb +177 -128
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +57 -59
- data/lib/action_controller/metal/permissions_policy.rb +22 -12
- data/lib/action_controller/metal/rate_limiting.rb +92 -0
- data/lib/action_controller/metal/redirecting.rb +213 -94
- data/lib/action_controller/metal/renderers.rb +78 -57
- data/lib/action_controller/metal/rendering.rb +111 -77
- data/lib/action_controller/metal/request_forgery_protection.rb +182 -143
- data/lib/action_controller/metal/rescue.rb +20 -9
- data/lib/action_controller/metal/streaming.rb +118 -195
- data/lib/action_controller/metal/strong_parameters.rb +720 -530
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +17 -15
- data/lib/action_controller/metal.rb +86 -60
- data/lib/action_controller/railtie.rb +36 -15
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +41 -36
- data/lib/action_controller/structured_event_subscriber.rb +116 -0
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +160 -131
- data/lib/action_controller.rb +5 -1
- data/lib/action_dispatch/constants.rb +8 -0
- data/lib/action_dispatch/deprecator.rb +2 -0
- data/lib/action_dispatch/http/cache.rb +163 -35
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +54 -39
- data/lib/action_dispatch/http/filter_parameters.rb +14 -8
- data/lib/action_dispatch/http/filter_redirect.rb +22 -1
- data/lib/action_dispatch/http/headers.rb +22 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +89 -41
- data/lib/action_dispatch/http/mime_type.rb +25 -21
- data/lib/action_dispatch/http/mime_types.rb +3 -0
- data/lib/action_dispatch/http/param_builder.rb +187 -0
- data/lib/action_dispatch/http/param_error.rb +26 -0
- data/lib/action_dispatch/http/parameters.rb +14 -12
- data/lib/action_dispatch/http/permissions_policy.rb +25 -36
- data/lib/action_dispatch/http/query_parser.rb +55 -0
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +141 -92
- data/lib/action_dispatch/http/response.rb +137 -77
- data/lib/action_dispatch/http/upload.rb +18 -16
- data/lib/action_dispatch/http/url.rb +187 -89
- data/lib/action_dispatch/journey/formatter.rb +21 -9
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +34 -11
- data/lib/action_dispatch/journey/gtg/transition_table.rb +47 -53
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +8 -6
- data/lib/action_dispatch/journey/parser.rb +99 -195
- data/lib/action_dispatch/journey/path/pattern.rb +4 -1
- data/lib/action_dispatch/journey/route.rb +54 -38
- data/lib/action_dispatch/journey/router/utils.rb +22 -27
- data/lib/action_dispatch/journey/router.rb +63 -83
- data/lib/action_dispatch/journey/routes.rb +11 -2
- data/lib/action_dispatch/journey/scanner.rb +46 -42
- data/lib/action_dispatch/journey/visitors.rb +57 -23
- data/lib/action_dispatch/journey/visualizer/fsm.js +4 -6
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +7 -1
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
- data/lib/action_dispatch/middleware/callbacks.rb +3 -1
- data/lib/action_dispatch/middleware/cookies.rb +125 -106
- data/lib/action_dispatch/middleware/debug_exceptions.rb +37 -8
- data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
- data/lib/action_dispatch/middleware/debug_view.rb +13 -5
- data/lib/action_dispatch/middleware/exception_wrapper.rb +18 -23
- data/lib/action_dispatch/middleware/executor.rb +19 -4
- data/lib/action_dispatch/middleware/flash.rb +63 -51
- data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
- data/lib/action_dispatch/middleware/public_exceptions.rb +14 -12
- data/lib/action_dispatch/middleware/reloader.rb +5 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +87 -77
- data/lib/action_dispatch/middleware/request_id.rb +16 -10
- data/lib/action_dispatch/middleware/server_timing.rb +4 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +30 -8
- data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +16 -16
- data/lib/action_dispatch/middleware/ssl.rb +53 -40
- data/lib/action_dispatch/middleware/stack.rb +11 -10
- data/lib/action_dispatch/middleware/static.rb +33 -31
- data/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +3 -5
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +9 -5
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +4 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +50 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +23 -3
- data/lib/action_dispatch/request/session.rb +24 -21
- data/lib/action_dispatch/request/utils.rb +11 -3
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +85 -60
- data/lib/action_dispatch/routing/mapper.rb +1031 -851
- data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
- data/lib/action_dispatch/routing/redirection.rb +47 -39
- data/lib/action_dispatch/routing/route_set.rb +79 -56
- data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
- data/lib/action_dispatch/routing/url_for.rb +130 -125
- data/lib/action_dispatch/routing.rb +150 -148
- data/lib/action_dispatch/structured_event_subscriber.rb +20 -0
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +16 -23
- data/lib/action_dispatch/system_testing/driver.rb +2 -0
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +34 -23
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +9 -7
- data/lib/action_dispatch/testing/assertions/response.rb +52 -25
- data/lib/action_dispatch/testing/assertions/routing.rb +168 -87
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/integration.rb +233 -223
- data/lib/action_dispatch/testing/request_encoder.rb +11 -9
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +11 -8
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +27 -26
- data/lib/action_dispatch.rb +36 -32
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +17 -16
- metadata +36 -32
- data/lib/action_dispatch/journey/parser.y +0 -50
- data/lib/action_dispatch/journey/parser_extras.rb +0 -31
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# :markup: markdown
|
|
4
|
+
|
|
3
5
|
require "action_dispatch/journey/nfa/dot"
|
|
4
6
|
|
|
5
7
|
module ActionDispatch
|
|
@@ -11,7 +13,6 @@ module ActionDispatch
|
|
|
11
13
|
attr_reader :memos
|
|
12
14
|
|
|
13
15
|
DEFAULT_EXP = /[^.\/?]+/
|
|
14
|
-
DEFAULT_EXP_ANCHORED = /\A#{DEFAULT_EXP}\Z/
|
|
15
16
|
|
|
16
17
|
def initialize
|
|
17
18
|
@stdparam_states = {}
|
|
@@ -45,32 +46,34 @@ module ActionDispatch
|
|
|
45
46
|
Array(t)
|
|
46
47
|
end
|
|
47
48
|
|
|
48
|
-
def move(t, full_string, start_index,
|
|
49
|
+
def move(t, full_string, token, start_index, token_matches_default)
|
|
49
50
|
return [] if t.empty?
|
|
50
51
|
|
|
51
52
|
next_states = []
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
transitions_count = t.size
|
|
55
|
+
i = 0
|
|
56
|
+
while i < transitions_count
|
|
57
|
+
s = t[i]
|
|
58
|
+
previous_start = t[i + 1]
|
|
57
59
|
if previous_start.nil?
|
|
58
|
-
# In the simple case of a "default" param regex do this fast-path
|
|
59
|
-
#
|
|
60
|
-
if
|
|
61
|
-
|
|
60
|
+
# In the simple case of a "default" param regex do this fast-path and add all
|
|
61
|
+
# next states.
|
|
62
|
+
if token_matches_default && std_state = @stdparam_states[s]
|
|
63
|
+
next_states << std_state << nil
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
# When we have a literal string, we can just pull the next state
|
|
65
67
|
if states = @string_states[s]
|
|
66
|
-
|
|
68
|
+
state = states[token]
|
|
69
|
+
next_states << state << nil unless state.nil?
|
|
67
70
|
end
|
|
68
71
|
end
|
|
69
72
|
|
|
70
|
-
# For regexes that aren't the "default" style, they may potentially
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
73
|
+
# For regexes that aren't the "default" style, they may potentially not be
|
|
74
|
+
# terminated by the first "token" [./?], so we need to continue to attempt to
|
|
75
|
+
# match this regexp as well as any successful paths that continue out of it.
|
|
76
|
+
# both paths could be valid.
|
|
74
77
|
if states = @regexp_states[s]
|
|
75
78
|
slice_start = if previous_start.nil?
|
|
76
79
|
start_index
|
|
@@ -78,19 +81,21 @@ module ActionDispatch
|
|
|
78
81
|
previous_start
|
|
79
82
|
end
|
|
80
83
|
|
|
81
|
-
slice_length =
|
|
84
|
+
slice_length = start_index + token.length - slice_start
|
|
82
85
|
curr_slice = full_string.slice(slice_start, slice_length)
|
|
83
86
|
|
|
84
87
|
states.each { |re, v|
|
|
85
88
|
# if we match, we can try moving past this
|
|
86
|
-
next_states <<
|
|
89
|
+
next_states << v << nil if !v.nil? && re.match?(curr_slice)
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
# and regardless, we must continue accepting tokens and retrying this regexp.
|
|
90
|
-
#
|
|
91
|
-
next_states <<
|
|
92
|
+
# and regardless, we must continue accepting tokens and retrying this regexp. we
|
|
93
|
+
# need to remember where we started as well so we can take bigger slices.
|
|
94
|
+
next_states << s << slice_start
|
|
92
95
|
end
|
|
93
|
-
|
|
96
|
+
|
|
97
|
+
i += 2
|
|
98
|
+
end
|
|
94
99
|
|
|
95
100
|
next_states
|
|
96
101
|
end
|
|
@@ -105,10 +110,10 @@ module ActionDispatch
|
|
|
105
110
|
end
|
|
106
111
|
|
|
107
112
|
{
|
|
108
|
-
regexp_states: simple_regexp,
|
|
109
|
-
string_states: @string_states,
|
|
110
|
-
stdparam_states: @stdparam_states,
|
|
111
|
-
accepting: @accepting
|
|
113
|
+
regexp_states: simple_regexp.stringify_keys,
|
|
114
|
+
string_states: @string_states.stringify_keys,
|
|
115
|
+
stdparam_states: @stdparam_states.stringify_keys,
|
|
116
|
+
accepting: @accepting.stringify_keys
|
|
112
117
|
}
|
|
113
118
|
end
|
|
114
119
|
|
|
@@ -161,54 +166,43 @@ module ActionDispatch
|
|
|
161
166
|
end
|
|
162
167
|
|
|
163
168
|
def []=(from, to, sym)
|
|
164
|
-
to_mappings = states_hash_for(sym)[from] ||= {}
|
|
165
169
|
case sym
|
|
170
|
+
when String, Symbol
|
|
171
|
+
to_mapping = @string_states[from] ||= {}
|
|
172
|
+
# account for symbols in the constraints the same as strings
|
|
173
|
+
to_mapping[sym.to_s] = to
|
|
166
174
|
when Regexp
|
|
167
|
-
# we must match the whole string to a token boundary
|
|
168
175
|
if sym == DEFAULT_EXP
|
|
169
|
-
|
|
176
|
+
@stdparam_states[from] = to
|
|
170
177
|
else
|
|
171
|
-
|
|
178
|
+
to_mapping = @regexp_states[from] ||= {}
|
|
179
|
+
# we must match the whole string to a token boundary
|
|
180
|
+
to_mapping[/\A#{sym}\Z/] = to
|
|
172
181
|
end
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
sym = sym.to_s
|
|
182
|
+
else
|
|
183
|
+
raise ArgumentError, "unknown symbol: %s" % sym.class
|
|
176
184
|
end
|
|
177
|
-
to_mappings[sym] = to
|
|
178
185
|
end
|
|
179
186
|
|
|
180
187
|
def states
|
|
181
188
|
ss = @string_states.keys + @string_states.values.flat_map(&:values)
|
|
182
|
-
ps = @stdparam_states.keys + @stdparam_states.values
|
|
189
|
+
ps = @stdparam_states.keys + @stdparam_states.values
|
|
183
190
|
rs = @regexp_states.keys + @regexp_states.values.flat_map(&:values)
|
|
184
191
|
(ss + ps + rs).uniq
|
|
185
192
|
end
|
|
186
193
|
|
|
187
194
|
def transitions
|
|
195
|
+
# double escaped because dot evaluates escapes
|
|
196
|
+
default_exp_anchored = "\\\\A#{DEFAULT_EXP.source}\\\\Z"
|
|
197
|
+
|
|
188
198
|
@string_states.flat_map { |from, hash|
|
|
189
199
|
hash.map { |s, to| [from, s, to] }
|
|
190
|
-
} + @stdparam_states.
|
|
191
|
-
|
|
200
|
+
} + @stdparam_states.map { |from, to|
|
|
201
|
+
[from, default_exp_anchored, to]
|
|
192
202
|
} + @regexp_states.flat_map { |from, hash|
|
|
193
|
-
hash.map { |
|
|
203
|
+
hash.map { |r, to| [from, r.source.gsub("\\") { "\\\\" }, to] }
|
|
194
204
|
}
|
|
195
205
|
end
|
|
196
|
-
|
|
197
|
-
private
|
|
198
|
-
def states_hash_for(sym)
|
|
199
|
-
case sym
|
|
200
|
-
when String, Symbol
|
|
201
|
-
@string_states
|
|
202
|
-
when Regexp
|
|
203
|
-
if sym == DEFAULT_EXP
|
|
204
|
-
@stdparam_states
|
|
205
|
-
else
|
|
206
|
-
@regexp_states
|
|
207
|
-
end
|
|
208
|
-
else
|
|
209
|
-
raise ArgumentError, "unknown symbol: %s" % sym.class
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
206
|
end
|
|
213
207
|
end
|
|
214
208
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# :markup: markdown
|
|
4
|
+
|
|
3
5
|
require "action_dispatch/journey/visitors"
|
|
4
6
|
|
|
5
7
|
module ActionDispatch
|
|
@@ -21,9 +23,8 @@ module ActionDispatch
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def requirements=(requirements)
|
|
24
|
-
# inject any regexp requirements for `star` nodes so they can be
|
|
25
|
-
#
|
|
26
|
-
# empty string.
|
|
26
|
+
# inject any regexp requirements for `star` nodes so they can be determined
|
|
27
|
+
# nullable, which requires knowing if the regex accepts an empty string.
|
|
27
28
|
(symbols + stars).each do |node|
|
|
28
29
|
re = requirements[node.to_sym]
|
|
29
30
|
node.regexp = re if re
|
|
@@ -51,8 +52,8 @@ module ActionDispatch
|
|
|
51
52
|
stars << node
|
|
52
53
|
|
|
53
54
|
if formatted != false
|
|
54
|
-
# Add a constraint for wildcard route to make it non-greedy and
|
|
55
|
-
#
|
|
55
|
+
# Add a constraint for wildcard route to make it non-greedy and match the
|
|
56
|
+
# optional format part of the route by default.
|
|
56
57
|
wildcard_options[node.name.to_sym] ||= /.+?/m
|
|
57
58
|
end
|
|
58
59
|
end
|
|
@@ -73,6 +74,7 @@ module ActionDispatch
|
|
|
73
74
|
def initialize(left)
|
|
74
75
|
@left = left
|
|
75
76
|
@memo = nil
|
|
77
|
+
@to_s = nil
|
|
76
78
|
end
|
|
77
79
|
|
|
78
80
|
def each(&block)
|
|
@@ -80,7 +82,7 @@ module ActionDispatch
|
|
|
80
82
|
end
|
|
81
83
|
|
|
82
84
|
def to_s
|
|
83
|
-
Visitors::String::INSTANCE.accept(self, "")
|
|
85
|
+
@to_s ||= Visitors::String::INSTANCE.accept(self, "".dup).freeze
|
|
84
86
|
end
|
|
85
87
|
|
|
86
88
|
def to_dot
|
|
@@ -1,199 +1,103 @@
|
|
|
1
|
-
#
|
|
2
|
-
# DO NOT MODIFY!!!!
|
|
3
|
-
# This file is automatically generated by Racc 1.4.16
|
|
4
|
-
# from Racc grammar file "".
|
|
5
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
6
2
|
|
|
7
|
-
require
|
|
3
|
+
require "action_dispatch/journey/scanner"
|
|
4
|
+
require "action_dispatch/journey/nodes/node"
|
|
8
5
|
|
|
9
|
-
# :stopdoc:
|
|
10
|
-
|
|
11
|
-
require "action_dispatch/journey/parser_extras"
|
|
12
6
|
module ActionDispatch
|
|
13
|
-
module Journey
|
|
14
|
-
class Parser
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
"$end",
|
|
110
|
-
"error",
|
|
111
|
-
"SLASH",
|
|
112
|
-
"LITERAL",
|
|
113
|
-
"SYMBOL",
|
|
114
|
-
"LPAREN",
|
|
115
|
-
"RPAREN",
|
|
116
|
-
"DOT",
|
|
117
|
-
"STAR",
|
|
118
|
-
"OR",
|
|
119
|
-
"$start",
|
|
120
|
-
"expressions",
|
|
121
|
-
"expression",
|
|
122
|
-
"or",
|
|
123
|
-
"terminal",
|
|
124
|
-
"group",
|
|
125
|
-
"star",
|
|
126
|
-
"symbol",
|
|
127
|
-
"literal",
|
|
128
|
-
"slash",
|
|
129
|
-
"dot" ]
|
|
130
|
-
|
|
131
|
-
Racc_debug_parser = false
|
|
132
|
-
|
|
133
|
-
##### State transition tables end #####
|
|
134
|
-
|
|
135
|
-
# reduce 0 omitted
|
|
136
|
-
|
|
137
|
-
def _reduce_1(val, _values)
|
|
138
|
-
Cat.new(val.first, val.last)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def _reduce_2(val, _values)
|
|
142
|
-
val.first
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# reduce 3 omitted
|
|
146
|
-
|
|
147
|
-
# reduce 4 omitted
|
|
148
|
-
|
|
149
|
-
# reduce 5 omitted
|
|
150
|
-
|
|
151
|
-
# reduce 6 omitted
|
|
152
|
-
|
|
153
|
-
def _reduce_7(val, _values)
|
|
154
|
-
Group.new(val[1])
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
def _reduce_8(val, _values)
|
|
158
|
-
Or.new([val.first, val.last])
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def _reduce_9(val, _values)
|
|
162
|
-
Or.new([val.first, val.last])
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def _reduce_10(val, _values)
|
|
166
|
-
Star.new(Symbol.new(val.last, Symbol::GREEDY_EXP))
|
|
7
|
+
module Journey # :nodoc:
|
|
8
|
+
class Parser # :nodoc:
|
|
9
|
+
include Journey::Nodes
|
|
10
|
+
|
|
11
|
+
def self.parse(string)
|
|
12
|
+
new.parse string
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
@scanner = Scanner.new
|
|
17
|
+
@next_token = nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def parse(string)
|
|
21
|
+
@scanner.scan_setup(string)
|
|
22
|
+
advance_token
|
|
23
|
+
do_parse
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
def advance_token
|
|
28
|
+
@next_token = @scanner.next_token
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def do_parse
|
|
32
|
+
parse_expressions
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def parse_expressions
|
|
36
|
+
node = parse_expression
|
|
37
|
+
|
|
38
|
+
while @next_token
|
|
39
|
+
case @next_token
|
|
40
|
+
when :RPAREN
|
|
41
|
+
break
|
|
42
|
+
when :OR
|
|
43
|
+
node = parse_or(node)
|
|
44
|
+
else
|
|
45
|
+
node = Cat.new(node, parse_expressions)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
node
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def parse_or(lhs)
|
|
53
|
+
advance_token
|
|
54
|
+
node = parse_expression
|
|
55
|
+
Or.new([lhs, node])
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def parse_expression
|
|
59
|
+
if @next_token == :STAR
|
|
60
|
+
parse_star
|
|
61
|
+
elsif @next_token == :LPAREN
|
|
62
|
+
parse_group
|
|
63
|
+
else
|
|
64
|
+
parse_terminal
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def parse_star
|
|
69
|
+
node = Star.new(Symbol.new(@scanner.last_string, Symbol::GREEDY_EXP))
|
|
70
|
+
advance_token
|
|
71
|
+
node
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def parse_group
|
|
75
|
+
advance_token
|
|
76
|
+
node = parse_expressions
|
|
77
|
+
if @next_token == :RPAREN
|
|
78
|
+
node = Group.new(node)
|
|
79
|
+
advance_token
|
|
80
|
+
node
|
|
81
|
+
else
|
|
82
|
+
raise ArgumentError, "missing right parenthesis."
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def parse_terminal
|
|
87
|
+
node = case @next_token
|
|
88
|
+
when :SYMBOL
|
|
89
|
+
Symbol.new(@scanner.last_string)
|
|
90
|
+
when :LITERAL
|
|
91
|
+
Literal.new(@scanner.last_literal)
|
|
92
|
+
when :SLASH
|
|
93
|
+
Slash.new("/")
|
|
94
|
+
when :DOT
|
|
95
|
+
Dot.new(".")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
advance_token
|
|
99
|
+
node
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
167
103
|
end
|
|
168
|
-
|
|
169
|
-
# reduce 11 omitted
|
|
170
|
-
|
|
171
|
-
# reduce 12 omitted
|
|
172
|
-
|
|
173
|
-
# reduce 13 omitted
|
|
174
|
-
|
|
175
|
-
# reduce 14 omitted
|
|
176
|
-
|
|
177
|
-
def _reduce_15(val, _values)
|
|
178
|
-
Slash.new(val.first)
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
def _reduce_16(val, _values)
|
|
182
|
-
Symbol.new(val.first)
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
def _reduce_17(val, _values)
|
|
186
|
-
Literal.new(val.first)
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
def _reduce_18(val, _values)
|
|
190
|
-
Dot.new(val.first)
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
def _reduce_none(val, _values)
|
|
194
|
-
val[0]
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
end # class Parser
|
|
198
|
-
end # module Journey
|
|
199
|
-
end # module ActionDispatch
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# :markup: markdown
|
|
4
|
+
|
|
3
5
|
module ActionDispatch
|
|
4
6
|
module Journey # :nodoc:
|
|
5
7
|
module Path # :nodoc:
|
|
@@ -32,7 +34,8 @@ module ActionDispatch
|
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def requirements_anchored?
|
|
35
|
-
# each required param must not be surrounded by a literal, otherwise it isn't
|
|
37
|
+
# each required param must not be surrounded by a literal, otherwise it isn't
|
|
38
|
+
# simple to chunk-match the url piecemeal
|
|
36
39
|
terminals = ast.terminals
|
|
37
40
|
|
|
38
41
|
terminals.each_with_index { |s, index|
|