From 8ef71ac4a119a4c03d78db2372b41ddcc8a95035 Mon Sep 17 00:00:00 2001 From: Ben Toews Date: Wed, 18 Oct 2017 10:21:45 -0600 Subject: push order arg checks down to allow for binds --- .../lib/active_record/relation/query_methods.rb | 33 ++++------------------ activerecord/lib/active_record/sanitization.rb | 6 +++- 2 files changed, 11 insertions(+), 28 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 1dcd786498..cef0847651 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -297,11 +297,6 @@ module ActiveRecord # Same as #order but operates on relation in-place instead of copying. def order!(*args) # :nodoc: - @klass.enforce_raw_sql_whitelist( - column_names_from_order_arguments(args), - whitelist: AttributeMethods::ClassMethods::COLUMN_NAME_ORDER_WHITELIST - ) - preprocess_order_args(args) self.order_values += args @@ -324,11 +319,6 @@ module ActiveRecord # Same as #reorder but operates on relation in-place instead of copying. def reorder!(*args) # :nodoc: - @klass.enforce_raw_sql_whitelist( - column_names_from_order_arguments(args), - whitelist: AttributeMethods::ClassMethods::COLUMN_NAME_ORDER_WHITELIST - ) - preprocess_order_args(args) self.reordering_value = true @@ -928,23 +918,6 @@ module ActiveRecord private - # Extract column names from arguments passed to #order or #reorder. - def column_names_from_order_arguments(args) - args.flat_map do |arg| - case arg - when Hash - # Tag.order(id: :desc) - arg.keys - when Array - # Tag.order([Arel.sql("field(id, ?)"), [1, 3, 2]]) - arg.flatten - else - # Tag.order(:id) - arg - end - end - end - def assert_mutability! raise ImmutableRelation if @loaded raise ImmutableRelation if defined?(@arel) && @arel @@ -1146,6 +1119,12 @@ module ActiveRecord klass.send(:sanitize_sql_for_order, arg) end order_args.flatten! + + @klass.enforce_raw_sql_whitelist( + order_args.flat_map { |a| a.is_a?(Hash) ? a.keys : a }, + whitelist: AttributeMethods::ClassMethods::COLUMN_NAME_ORDER_WHITELIST + ) + validate_order_args(order_args) references = order_args.grep(String) diff --git a/activerecord/lib/active_record/sanitization.rb b/activerecord/lib/active_record/sanitization.rb index 4caf1145f0..232743d3b6 100644 --- a/activerecord/lib/active_record/sanitization.rb +++ b/activerecord/lib/active_record/sanitization.rb @@ -63,13 +63,17 @@ module ActiveRecord # # => "id ASC" def sanitize_sql_for_order(condition) # :doc: if condition.is_a?(Array) && condition.first.to_s.include?("?") + enforce_raw_sql_whitelist([condition.first], + whitelist: AttributeMethods::ClassMethods::COLUMN_NAME_ORDER_WHITELIST + ) + # Ensure we aren't dealing with a subclass of String that might # override methods we use (eg. Arel::Nodes::SqlLiteral). if condition.first.kind_of?(String) && !condition.first.instance_of?(String) condition = [String.new(condition.first), *condition[1..-1]] end - sanitize_sql_array(condition) + Arel.sql(sanitize_sql_array(condition)) else condition end -- cgit v1.2.3