aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_controller/metal/strong_parameters.rb3
-rw-r--r--actionpack/lib/action_dispatch/middleware/static.rb6
-rw-r--r--actionpack/test/controller/parameters/accessors_test.rb6
-rw-r--r--actionpack/test/dispatch/static_test.rb4
-rw-r--r--activerecord/lib/active_record/relation/where_clause.rb21
-rw-r--r--activerecord/test/cases/relation/where_clause_test.rb17
6 files changed, 42 insertions, 15 deletions
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb
index b0a943c768..5cbf4157a4 100644
--- a/actionpack/lib/action_controller/metal/strong_parameters.rb
+++ b/actionpack/lib/action_controller/metal/strong_parameters.rb
@@ -109,7 +109,8 @@ module ActionController
cattr_accessor :permit_all_parameters, instance_accessor: false
cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false
- delegate :keys, :key?, :has_key?, :empty?, :include?, :inspect, to: :@parameters
+ delegate :keys, :key?, :has_key?, :empty?, :include?, :inspect,
+ :as_json, to: :@parameters
# By default, never raise an UnpermittedParameters exception if these
# params are present. The default includes both 'controller' and 'action'
diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
index ea9ab3821d..41c220236a 100644
--- a/actionpack/lib/action_dispatch/middleware/static.rb
+++ b/actionpack/lib/action_dispatch/middleware/static.rb
@@ -27,7 +27,7 @@ module ActionDispatch
# in the server's `public/` directory (see Static#call).
def match?(path)
path = ::Rack::Utils.unescape_path path
- return false unless path.valid_encoding?
+ return false unless valid_path?(path)
path = Rack::Utils.clean_path_info path
paths = [path, "#{path}#{ext}", "#{path}/#{@index}#{ext}"]
@@ -94,6 +94,10 @@ module ActionDispatch
false
end
end
+
+ def valid_path?(path)
+ path.valid_encoding? && !path.include?("\0")
+ end
end
# This middleware will attempt to return the contents of a file's body from
diff --git a/actionpack/test/controller/parameters/accessors_test.rb b/actionpack/test/controller/parameters/accessors_test.rb
index 97875c3cbb..a8f4d877a6 100644
--- a/actionpack/test/controller/parameters/accessors_test.rb
+++ b/actionpack/test/controller/parameters/accessors_test.rb
@@ -27,6 +27,12 @@ class ParametersAccessorsTest < ActiveSupport::TestCase
assert_not @params[:person][:name].permitted?
end
+ test "as_json returns the JSON representation of the parameters hash" do
+ assert_not @params.as_json.key? "parameters"
+ assert_not @params.as_json.key? "permitted"
+ assert @params.as_json.key? "person"
+ end
+
test "each carries permitted status" do
@params.permit!
@params.each { |key, value| assert(value.permitted?) if key == "person" }
diff --git a/actionpack/test/dispatch/static_test.rb b/actionpack/test/dispatch/static_test.rb
index 1da57ab50b..ea8b5e904e 100644
--- a/actionpack/test/dispatch/static_test.rb
+++ b/actionpack/test/dispatch/static_test.rb
@@ -40,6 +40,10 @@ module StaticTests
assert_equal "Hello, World!", get("/doorkeeper%E3E4".force_encoding('ASCII-8BIT')).body
end
+ def test_handles_urls_with_null_byte
+ assert_equal "Hello, World!", get("/doorkeeper%00").body
+ end
+
def test_sets_cache_control
app = assert_deprecated do
ActionDispatch::Static.new(DummyApp, @root, "public, max-age=60")
diff --git a/activerecord/lib/active_record/relation/where_clause.rb b/activerecord/lib/active_record/relation/where_clause.rb
index 2c2d6cfa47..e39dbac0d5 100644
--- a/activerecord/lib/active_record/relation/where_clause.rb
+++ b/activerecord/lib/active_record/relation/where_clause.rb
@@ -18,9 +18,10 @@ module ActiveRecord
end
def merge(other)
+ conflict_indices = indices_of_predicates_referenced_by(other).to_set
WhereClause.new(
- predicates_unreferenced_by(other) + other.predicates,
- non_conflicting_binds(other) + other.binds,
+ non_conflicting(predicates, conflict_indices) + other.predicates,
+ non_conflicting(binds, conflict_indices) + other.binds,
)
end
@@ -97,20 +98,18 @@ module ActiveRecord
private
- def predicates_unreferenced_by(other)
- predicates.reject do |n|
+ def indices_of_predicates_referenced_by(other)
+ predicates.each_with_index.select do |(n, _)|
equality_node?(n) && other.referenced_columns.include?(n.left)
- end
+ end.map(&:last)
end
- def equality_node?(node)
- node.respond_to?(:operator) && node.operator == :==
+ def non_conflicting(values, conflict_indices)
+ values.reject.with_index { |_, i| conflict_indices.include?(i) }
end
- def non_conflicting_binds(other)
- conflicts = referenced_columns & other.referenced_columns
- conflicts.map! { |node| node.name.to_s }
- binds.reject { |attr| conflicts.include?(attr.name) }
+ def equality_node?(node)
+ node.respond_to?(:operator) && node.operator == :==
end
def inverted_predicates
diff --git a/activerecord/test/cases/relation/where_clause_test.rb b/activerecord/test/cases/relation/where_clause_test.rb
index c20ed94d90..c3296b28fd 100644
--- a/activerecord/test/cases/relation/where_clause_test.rb
+++ b/activerecord/test/cases/relation/where_clause_test.rb
@@ -62,8 +62,21 @@ class ActiveRecord::Relation
end
test "merge allows for columns with the same name from different tables" do
- skip "This is not possible as of 4.2, and the binds do not yet contain sufficient information for this to happen"
- # We might be able to change the implementation to remove conflicts by index, rather than column name
+ table2 = Arel::Table.new("table2")
+ a = WhereClause.new(
+ [table["id"].eq(bind_param), table2["id"].eq(bind_param), table["name"].eq(bind_param)],
+ [attribute("id", 3), attribute("id", 2), attribute("name", "Jim")]
+ )
+ b = WhereClause.new(
+ [table["id"].eq(bind_param), table["name"].eq(bind_param)],
+ [attribute("id", 1), attribute("name", "Sean")],
+ )
+ expected = WhereClause.new(
+ [table2["id"].eq(bind_param), table["id"].eq(bind_param), table["name"].eq(bind_param)],
+ [attribute("id", 2), attribute("id", 1), attribute("name", "Sean")],
+ )
+
+ assert_equal expected, a.merge(b)
end
test "a clause knows if it is empty" do