actionpack 5.2.4.4 → 6.1.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +264 -322
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/abstract_controller.rb +1 -0
- data/lib/abstract_controller/base.rb +38 -4
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/caching/fragments.rb +6 -22
- data/lib/abstract_controller/callbacks.rb +14 -2
- data/lib/abstract_controller/collector.rb +1 -2
- data/lib/abstract_controller/helpers.rb +106 -90
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -1
- data/lib/abstract_controller/rendering.rb +9 -9
- data/lib/abstract_controller/translation.rb +11 -5
- data/lib/action_controller.rb +7 -4
- data/lib/action_controller/api.rb +4 -3
- data/lib/action_controller/base.rb +6 -9
- data/lib/action_controller/caching.rb +1 -3
- data/lib/action_controller/log_subscriber.rb +10 -7
- data/lib/action_controller/metal.rb +10 -8
- data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
- data/lib/action_controller/metal/conditional_get.rb +19 -5
- data/lib/action_controller/metal/content_security_policy.rb +1 -2
- data/lib/action_controller/metal/cookies.rb +3 -1
- data/lib/action_controller/metal/data_streaming.rb +6 -7
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +3 -5
- data/lib/action_controller/metal/exceptions.rb +56 -2
- data/lib/action_controller/metal/flash.rb +5 -5
- data/lib/action_controller/metal/head.rb +7 -4
- data/lib/action_controller/metal/helpers.rb +14 -5
- data/lib/action_controller/metal/http_authentication.rb +24 -23
- data/lib/action_controller/metal/implicit_render.rb +5 -15
- data/lib/action_controller/metal/instrumentation.rb +13 -14
- data/lib/action_controller/metal/live.rb +30 -32
- data/lib/action_controller/metal/logging.rb +20 -0
- data/lib/action_controller/metal/mime_responds.rb +19 -4
- data/lib/action_controller/metal/parameter_encoding.rb +35 -4
- data/lib/action_controller/metal/params_wrapper.rb +31 -22
- data/lib/action_controller/metal/permissions_policy.rb +46 -0
- data/lib/action_controller/metal/redirecting.rb +6 -6
- data/lib/action_controller/metal/renderers.rb +4 -4
- data/lib/action_controller/metal/rendering.rb +8 -3
- data/lib/action_controller/metal/request_forgery_protection.rb +62 -34
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/streaming.rb +0 -1
- data/lib/action_controller/metal/strong_parameters.rb +167 -58
- data/lib/action_controller/metal/url_for.rb +1 -1
- data/lib/action_controller/railties/helpers.rb +1 -1
- data/lib/action_controller/renderer.rb +37 -13
- data/lib/action_controller/template_assertions.rb +1 -1
- data/lib/action_controller/test_case.rb +70 -65
- data/lib/action_dispatch.rb +9 -3
- data/lib/action_dispatch/http/cache.rb +26 -21
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +33 -19
- data/lib/action_dispatch/http/filter_parameters.rb +9 -8
- data/lib/action_dispatch/http/filter_redirect.rb +2 -3
- data/lib/action_dispatch/http/headers.rb +4 -4
- data/lib/action_dispatch/http/mime_negotiation.rb +26 -13
- data/lib/action_dispatch/http/mime_type.rb +42 -23
- data/lib/action_dispatch/http/parameters.rb +14 -23
- data/lib/action_dispatch/http/permissions_policy.rb +173 -0
- data/lib/action_dispatch/http/request.rb +45 -22
- data/lib/action_dispatch/http/response.rb +45 -25
- data/lib/action_dispatch/http/upload.rb +9 -1
- data/lib/action_dispatch/http/url.rb +82 -82
- data/lib/action_dispatch/journey.rb +0 -2
- data/lib/action_dispatch/journey/formatter.rb +54 -30
- data/lib/action_dispatch/journey/gtg/builder.rb +22 -37
- data/lib/action_dispatch/journey/gtg/simulator.rb +8 -7
- data/lib/action_dispatch/journey/gtg/transition_table.rb +6 -5
- data/lib/action_dispatch/journey/nfa/dot.rb +0 -11
- data/lib/action_dispatch/journey/nodes/node.rb +13 -11
- data/lib/action_dispatch/journey/parser.rb +13 -13
- data/lib/action_dispatch/journey/parser.y +1 -1
- data/lib/action_dispatch/journey/path/pattern.rb +19 -21
- data/lib/action_dispatch/journey/route.rb +10 -20
- data/lib/action_dispatch/journey/router.rb +26 -34
- data/lib/action_dispatch/journey/router/utils.rb +14 -12
- data/lib/action_dispatch/journey/routes.rb +0 -2
- data/lib/action_dispatch/journey/scanner.rb +10 -4
- data/lib/action_dispatch/journey/visitors.rb +1 -4
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -4
- data/lib/action_dispatch/middleware/cookies.rb +128 -109
- data/lib/action_dispatch/middleware/debug_exceptions.rb +43 -66
- data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
- data/lib/action_dispatch/middleware/debug_view.rb +66 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +75 -30
- data/lib/action_dispatch/middleware/flash.rb +1 -1
- data/lib/action_dispatch/middleware/host_authorization.rb +121 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +6 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +14 -16
- data/lib/action_dispatch/middleware/request_id.rb +5 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +3 -9
- data/lib/action_dispatch/middleware/show_exceptions.rb +3 -2
- data/lib/action_dispatch/middleware/ssl.rb +20 -15
- data/lib/action_dispatch/middleware/stack.rb +56 -2
- data/lib/action_dispatch/middleware/static.rb +153 -93
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +3 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +6 -3
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +3 -1
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +104 -8
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +24 -1
- data/lib/action_dispatch/railtie.rb +8 -2
- data/lib/action_dispatch/request/session.rb +10 -9
- data/lib/action_dispatch/request/utils.rb +26 -2
- data/lib/action_dispatch/routing.rb +21 -20
- data/lib/action_dispatch/routing/inspector.rb +100 -52
- data/lib/action_dispatch/routing/mapper.rb +155 -103
- data/lib/action_dispatch/routing/polymorphic_routes.rb +13 -15
- data/lib/action_dispatch/routing/redirection.rb +3 -3
- data/lib/action_dispatch/routing/route_set.rb +71 -69
- data/lib/action_dispatch/routing/url_for.rb +2 -2
- data/lib/action_dispatch/system_test_case.rb +54 -11
- data/lib/action_dispatch/system_testing/browser.rb +53 -16
- data/lib/action_dispatch/system_testing/driver.rb +11 -3
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +49 -7
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +8 -10
- data/lib/action_dispatch/testing/assertion_response.rb +0 -1
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +4 -7
- data/lib/action_dispatch/testing/assertions/routing.rb +20 -8
- data/lib/action_dispatch/testing/integration.rb +61 -28
- data/lib/action_dispatch/testing/request_encoder.rb +2 -2
- data/lib/action_dispatch/testing/test_process.rb +29 -4
- data/lib/action_dispatch/testing/test_request.rb +3 -3
- data/lib/action_dispatch/testing/test_response.rb +4 -32
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/gem_version.rb +4 -4
- metadata +38 -26
- data/lib/action_controller/metal/force_ssl.rb +0 -99
- data/lib/action_dispatch/http/parameter_filter.rb +0 -86
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -78
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -49
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -120
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +0 -26
@@ -1,99 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "active_support/core_ext/hash/except"
|
4
|
-
require "active_support/core_ext/hash/slice"
|
5
|
-
|
6
|
-
module ActionController
|
7
|
-
# This module provides a method which will redirect the browser to use the secured HTTPS
|
8
|
-
# protocol. This will ensure that users' sensitive information will be
|
9
|
-
# transferred safely over the internet. You _should_ always force the browser
|
10
|
-
# to use HTTPS when you're transferring sensitive information such as
|
11
|
-
# user authentication, account information, or credit card information.
|
12
|
-
#
|
13
|
-
# Note that if you are really concerned about your application security,
|
14
|
-
# you might consider using +config.force_ssl+ in your config file instead.
|
15
|
-
# That will ensure all the data is transferred via HTTPS, and will
|
16
|
-
# prevent the user from getting their session hijacked when accessing the
|
17
|
-
# site over unsecured HTTP protocol.
|
18
|
-
module ForceSSL
|
19
|
-
extend ActiveSupport::Concern
|
20
|
-
include AbstractController::Callbacks
|
21
|
-
|
22
|
-
ACTION_OPTIONS = [:only, :except, :if, :unless]
|
23
|
-
URL_OPTIONS = [:protocol, :host, :domain, :subdomain, :port, :path]
|
24
|
-
REDIRECT_OPTIONS = [:status, :flash, :alert, :notice]
|
25
|
-
|
26
|
-
module ClassMethods
|
27
|
-
# Force the request to this particular controller or specified actions to be
|
28
|
-
# through the HTTPS protocol.
|
29
|
-
#
|
30
|
-
# If you need to disable this for any reason (e.g. development) then you can use
|
31
|
-
# an +:if+ or +:unless+ condition.
|
32
|
-
#
|
33
|
-
# class AccountsController < ApplicationController
|
34
|
-
# force_ssl if: :ssl_configured?
|
35
|
-
#
|
36
|
-
# def ssl_configured?
|
37
|
-
# !Rails.env.development?
|
38
|
-
# end
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
# ==== URL Options
|
42
|
-
# You can pass any of the following options to affect the redirect URL
|
43
|
-
# * <tt>host</tt> - Redirect to a different host name
|
44
|
-
# * <tt>subdomain</tt> - Redirect to a different subdomain
|
45
|
-
# * <tt>domain</tt> - Redirect to a different domain
|
46
|
-
# * <tt>port</tt> - Redirect to a non-standard port
|
47
|
-
# * <tt>path</tt> - Redirect to a different path
|
48
|
-
#
|
49
|
-
# ==== Redirect Options
|
50
|
-
# You can pass any of the following options to affect the redirect status and response
|
51
|
-
# * <tt>status</tt> - Redirect with a custom status (default is 301 Moved Permanently)
|
52
|
-
# * <tt>flash</tt> - Set a flash message when redirecting
|
53
|
-
# * <tt>alert</tt> - Set an alert message when redirecting
|
54
|
-
# * <tt>notice</tt> - Set a notice message when redirecting
|
55
|
-
#
|
56
|
-
# ==== Action Options
|
57
|
-
# You can pass any of the following options to affect the before_action callback
|
58
|
-
# * <tt>only</tt> - The callback should be run only for this action
|
59
|
-
# * <tt>except</tt> - The callback should be run for all actions except this action
|
60
|
-
# * <tt>if</tt> - A symbol naming an instance method or a proc; the
|
61
|
-
# callback will be called only when it returns a true value.
|
62
|
-
# * <tt>unless</tt> - A symbol naming an instance method or a proc; the
|
63
|
-
# callback will be called only when it returns a false value.
|
64
|
-
def force_ssl(options = {})
|
65
|
-
action_options = options.slice(*ACTION_OPTIONS)
|
66
|
-
redirect_options = options.except(*ACTION_OPTIONS)
|
67
|
-
before_action(action_options) do
|
68
|
-
force_ssl_redirect(redirect_options)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# Redirect the existing request to use the HTTPS protocol.
|
74
|
-
#
|
75
|
-
# ==== Parameters
|
76
|
-
# * <tt>host_or_options</tt> - Either a host name or any of the URL and
|
77
|
-
# redirect options available to the <tt>force_ssl</tt> method.
|
78
|
-
def force_ssl_redirect(host_or_options = nil)
|
79
|
-
unless request.ssl?
|
80
|
-
options = {
|
81
|
-
protocol: "https://",
|
82
|
-
host: request.host,
|
83
|
-
path: request.fullpath,
|
84
|
-
status: :moved_permanently
|
85
|
-
}
|
86
|
-
|
87
|
-
if host_or_options.is_a?(Hash)
|
88
|
-
options.merge!(host_or_options)
|
89
|
-
elsif host_or_options
|
90
|
-
options[:host] = host_or_options
|
91
|
-
end
|
92
|
-
|
93
|
-
secure_url = ActionDispatch::Http::URL.url_for(options.slice(*URL_OPTIONS))
|
94
|
-
flash.keep if respond_to?(:flash) && request.respond_to?(:flash)
|
95
|
-
redirect_to secure_url, options.slice(*REDIRECT_OPTIONS)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "active_support/core_ext/object/duplicable"
|
4
|
-
|
5
|
-
module ActionDispatch
|
6
|
-
module Http
|
7
|
-
class ParameterFilter
|
8
|
-
FILTERED = "[FILTERED]".freeze # :nodoc:
|
9
|
-
|
10
|
-
def initialize(filters = [])
|
11
|
-
@filters = filters
|
12
|
-
end
|
13
|
-
|
14
|
-
def filter(params)
|
15
|
-
compiled_filter.call(params)
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def compiled_filter
|
21
|
-
@compiled_filter ||= CompiledFilter.compile(@filters)
|
22
|
-
end
|
23
|
-
|
24
|
-
class CompiledFilter # :nodoc:
|
25
|
-
def self.compile(filters)
|
26
|
-
return lambda { |params| params.dup } if filters.empty?
|
27
|
-
|
28
|
-
strings, regexps, blocks = [], [], []
|
29
|
-
|
30
|
-
filters.each do |item|
|
31
|
-
case item
|
32
|
-
when Proc
|
33
|
-
blocks << item
|
34
|
-
when Regexp
|
35
|
-
regexps << item
|
36
|
-
else
|
37
|
-
strings << Regexp.escape(item.to_s)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.".freeze) }
|
42
|
-
deep_strings, strings = strings.partition { |s| s.include?("\\.".freeze) }
|
43
|
-
|
44
|
-
regexps << Regexp.new(strings.join("|".freeze), true) unless strings.empty?
|
45
|
-
deep_regexps << Regexp.new(deep_strings.join("|".freeze), true) unless deep_strings.empty?
|
46
|
-
|
47
|
-
new regexps, deep_regexps, blocks
|
48
|
-
end
|
49
|
-
|
50
|
-
attr_reader :regexps, :deep_regexps, :blocks
|
51
|
-
|
52
|
-
def initialize(regexps, deep_regexps, blocks)
|
53
|
-
@regexps = regexps
|
54
|
-
@deep_regexps = deep_regexps.any? ? deep_regexps : nil
|
55
|
-
@blocks = blocks
|
56
|
-
end
|
57
|
-
|
58
|
-
def call(original_params, parents = [])
|
59
|
-
filtered_params = original_params.class.new
|
60
|
-
|
61
|
-
original_params.each do |key, value|
|
62
|
-
parents.push(key) if deep_regexps
|
63
|
-
if regexps.any? { |r| key =~ r }
|
64
|
-
value = FILTERED
|
65
|
-
elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| joined =~ r }
|
66
|
-
value = FILTERED
|
67
|
-
elsif value.is_a?(Hash)
|
68
|
-
value = call(value, parents)
|
69
|
-
elsif value.is_a?(Array)
|
70
|
-
value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v }
|
71
|
-
elsif blocks.any?
|
72
|
-
key = key.dup if key.duplicable?
|
73
|
-
value = value.dup if value.duplicable?
|
74
|
-
blocks.each { |b| b.call(key, value) }
|
75
|
-
end
|
76
|
-
parents.pop if deep_regexps
|
77
|
-
|
78
|
-
filtered_params[key] = value
|
79
|
-
end
|
80
|
-
|
81
|
-
filtered_params
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "action_dispatch/journey/nfa/transition_table"
|
4
|
-
require "action_dispatch/journey/gtg/transition_table"
|
5
|
-
|
6
|
-
module ActionDispatch
|
7
|
-
module Journey # :nodoc:
|
8
|
-
module NFA # :nodoc:
|
9
|
-
class Visitor < Visitors::Visitor # :nodoc:
|
10
|
-
def initialize(tt)
|
11
|
-
@tt = tt
|
12
|
-
@i = -1
|
13
|
-
end
|
14
|
-
|
15
|
-
def visit_CAT(node)
|
16
|
-
left = visit(node.left)
|
17
|
-
right = visit(node.right)
|
18
|
-
|
19
|
-
@tt.merge(left.last, right.first)
|
20
|
-
|
21
|
-
[left.first, right.last]
|
22
|
-
end
|
23
|
-
|
24
|
-
def visit_GROUP(node)
|
25
|
-
from = @i += 1
|
26
|
-
left = visit(node.left)
|
27
|
-
to = @i += 1
|
28
|
-
|
29
|
-
@tt.accepting = to
|
30
|
-
|
31
|
-
@tt[from, left.first] = nil
|
32
|
-
@tt[left.last, to] = nil
|
33
|
-
@tt[from, to] = nil
|
34
|
-
|
35
|
-
[from, to]
|
36
|
-
end
|
37
|
-
|
38
|
-
def visit_OR(node)
|
39
|
-
from = @i += 1
|
40
|
-
children = node.children.map { |c| visit(c) }
|
41
|
-
to = @i += 1
|
42
|
-
|
43
|
-
children.each do |child|
|
44
|
-
@tt[from, child.first] = nil
|
45
|
-
@tt[child.last, to] = nil
|
46
|
-
end
|
47
|
-
|
48
|
-
@tt.accepting = to
|
49
|
-
|
50
|
-
[from, to]
|
51
|
-
end
|
52
|
-
|
53
|
-
def terminal(node)
|
54
|
-
from_i = @i += 1 # new state
|
55
|
-
to_i = @i += 1 # new state
|
56
|
-
|
57
|
-
@tt[from_i, to_i] = node
|
58
|
-
@tt.accepting = to_i
|
59
|
-
@tt.add_memo(to_i, node.memo)
|
60
|
-
|
61
|
-
[from_i, to_i]
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
class Builder # :nodoc:
|
66
|
-
def initialize(ast)
|
67
|
-
@ast = ast
|
68
|
-
end
|
69
|
-
|
70
|
-
def transition_table
|
71
|
-
tt = TransitionTable.new
|
72
|
-
Visitor.new(tt).accept(@ast)
|
73
|
-
tt
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "strscan"
|
4
|
-
|
5
|
-
module ActionDispatch
|
6
|
-
module Journey # :nodoc:
|
7
|
-
module NFA # :nodoc:
|
8
|
-
class MatchData # :nodoc:
|
9
|
-
attr_reader :memos
|
10
|
-
|
11
|
-
def initialize(memos)
|
12
|
-
@memos = memos
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class Simulator # :nodoc:
|
17
|
-
attr_reader :tt
|
18
|
-
|
19
|
-
def initialize(transition_table)
|
20
|
-
@tt = transition_table
|
21
|
-
end
|
22
|
-
|
23
|
-
def simulate(string)
|
24
|
-
input = StringScanner.new(string)
|
25
|
-
state = tt.eclosure(0)
|
26
|
-
until input.eos?
|
27
|
-
sym = input.scan(%r([/.?]|[^/.?]+))
|
28
|
-
|
29
|
-
# FIXME: tt.eclosure is not needed for the GTG
|
30
|
-
state = tt.eclosure(tt.move(state, sym))
|
31
|
-
end
|
32
|
-
|
33
|
-
acceptance_states = state.find_all { |s|
|
34
|
-
tt.accepting?(tt.eclosure(s).sort.last)
|
35
|
-
}
|
36
|
-
|
37
|
-
return if acceptance_states.empty?
|
38
|
-
|
39
|
-
memos = acceptance_states.flat_map { |x| tt.memo(x) }.compact
|
40
|
-
|
41
|
-
MatchData.new(memos)
|
42
|
-
end
|
43
|
-
|
44
|
-
alias :=~ :simulate
|
45
|
-
alias :match :simulate
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,120 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "action_dispatch/journey/nfa/dot"
|
4
|
-
|
5
|
-
module ActionDispatch
|
6
|
-
module Journey # :nodoc:
|
7
|
-
module NFA # :nodoc:
|
8
|
-
class TransitionTable # :nodoc:
|
9
|
-
include Journey::NFA::Dot
|
10
|
-
|
11
|
-
attr_accessor :accepting
|
12
|
-
attr_reader :memos
|
13
|
-
|
14
|
-
def initialize
|
15
|
-
@table = Hash.new { |h, f| h[f] = {} }
|
16
|
-
@memos = {}
|
17
|
-
@accepting = nil
|
18
|
-
@inverted = nil
|
19
|
-
end
|
20
|
-
|
21
|
-
def accepting?(state)
|
22
|
-
accepting == state
|
23
|
-
end
|
24
|
-
|
25
|
-
def accepting_states
|
26
|
-
[accepting]
|
27
|
-
end
|
28
|
-
|
29
|
-
def add_memo(idx, memo)
|
30
|
-
@memos[idx] = memo
|
31
|
-
end
|
32
|
-
|
33
|
-
def memo(idx)
|
34
|
-
@memos[idx]
|
35
|
-
end
|
36
|
-
|
37
|
-
def []=(i, f, s)
|
38
|
-
@table[f][i] = s
|
39
|
-
end
|
40
|
-
|
41
|
-
def merge(left, right)
|
42
|
-
@memos[right] = @memos.delete(left)
|
43
|
-
@table[right] = @table.delete(left)
|
44
|
-
end
|
45
|
-
|
46
|
-
def states
|
47
|
-
(@table.keys + @table.values.flat_map(&:keys)).uniq
|
48
|
-
end
|
49
|
-
|
50
|
-
# Returns set of NFA states to which there is a transition on ast symbol
|
51
|
-
# +a+ from some state +s+ in +t+.
|
52
|
-
def following_states(t, a)
|
53
|
-
Array(t).flat_map { |s| inverted[s][a] }.uniq
|
54
|
-
end
|
55
|
-
|
56
|
-
# Returns set of NFA states to which there is a transition on ast symbol
|
57
|
-
# +a+ from some state +s+ in +t+.
|
58
|
-
def move(t, a)
|
59
|
-
Array(t).map { |s|
|
60
|
-
inverted[s].keys.compact.find_all { |sym|
|
61
|
-
sym === a
|
62
|
-
}.map { |sym| inverted[s][sym] }
|
63
|
-
}.flatten.uniq
|
64
|
-
end
|
65
|
-
|
66
|
-
def alphabet
|
67
|
-
inverted.values.flat_map(&:keys).compact.uniq.sort_by(&:to_s)
|
68
|
-
end
|
69
|
-
|
70
|
-
# Returns a set of NFA states reachable from some NFA state +s+ in set
|
71
|
-
# +t+ on nil-transitions alone.
|
72
|
-
def eclosure(t)
|
73
|
-
stack = Array(t)
|
74
|
-
seen = {}
|
75
|
-
children = []
|
76
|
-
|
77
|
-
until stack.empty?
|
78
|
-
s = stack.pop
|
79
|
-
next if seen[s]
|
80
|
-
|
81
|
-
seen[s] = true
|
82
|
-
children << s
|
83
|
-
|
84
|
-
stack.concat(inverted[s][nil])
|
85
|
-
end
|
86
|
-
|
87
|
-
children.uniq
|
88
|
-
end
|
89
|
-
|
90
|
-
def transitions
|
91
|
-
@table.flat_map { |to, hash|
|
92
|
-
hash.map { |from, sym| [from, sym, to] }
|
93
|
-
}
|
94
|
-
end
|
95
|
-
|
96
|
-
private
|
97
|
-
|
98
|
-
def inverted
|
99
|
-
return @inverted if @inverted
|
100
|
-
|
101
|
-
@inverted = Hash.new { |h, from|
|
102
|
-
h[from] = Hash.new { |j, s| j[s] = [] }
|
103
|
-
}
|
104
|
-
|
105
|
-
@table.each { |to, hash|
|
106
|
-
hash.each { |from, sym|
|
107
|
-
if sym
|
108
|
-
sym = Nodes::Symbol === sym ? sym.regexp : sym.left
|
109
|
-
end
|
110
|
-
|
111
|
-
@inverted[from][sym] << to
|
112
|
-
}
|
113
|
-
}
|
114
|
-
|
115
|
-
@inverted
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActionDispatch
|
4
|
-
module SystemTesting
|
5
|
-
module TestHelpers
|
6
|
-
module UndefMethods # :nodoc:
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
included do
|
9
|
-
METHODS = %i(get post put patch delete).freeze
|
10
|
-
|
11
|
-
METHODS.each do |verb|
|
12
|
-
undef_method verb
|
13
|
-
end
|
14
|
-
|
15
|
-
def method_missing(method, *args, &block)
|
16
|
-
if METHODS.include?(method)
|
17
|
-
raise NoMethodError, "System tests cannot make direct requests via ##{method}; use #visit and #click_on instead. See http://www.rubydoc.info/github/teamcapybara/capybara/master#The_DSL for more information."
|
18
|
-
else
|
19
|
-
super
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|