Skip to content

Commit

Permalink
Merge pull request rails#44010 from siegfault/dangerous_query_method_…
Browse files Browse the repository at this point in the history
…allow_nested_functions

Accept nested functions in Dangerous Query Methods
  • Loading branch information
byroot authored Jul 19, 2022
2 parents fa7f977 + 8fe1bd5 commit 71c59c6
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 8 deletions.
4 changes: 4 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
* Allow nested functions as safe SQL string

*Michael Siegfried*

* Allow `destroy_association_async_job=` to be configured with a class string instead of a constant.

Defers an autoloading dependency between `ActiveRecord::Base` and `ActiveJob::Base`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def column_name_with_order_matcher # :nodoc:
(
(?:
# table_name.column_name | function(one or no argument)
((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
((?:\w+\.)?\w+ | \w+\((?:|\g<2>)\))
)
(?:(?:\s+AS)?\s+\w+)?
)
Expand All @@ -191,7 +191,7 @@ def column_name_with_order_matcher # :nodoc:
(
(?:
# table_name.column_name | function(one or no argument)
((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
((?:\w+\.)?\w+ | \w+\((?:|\g<2>)\))
)
(?:\s+ASC|\s+DESC)?
(?:\s+NULLS\s+(?:FIRST|LAST))?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def column_name_with_order_matcher
(
(?:
# `table_name`.`column_name` | function(one or no argument)
((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`)) | \w+\((?:|\g<2>)\)
((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`) | \w+\((?:|\g<2>)\))
)
(?:(?:\s+AS)?\s+(?:\w+|`\w+`))?
)
Expand All @@ -97,7 +97,7 @@ def column_name_with_order_matcher
(
(?:
# `table_name`.`column_name` | function(one or no argument)
((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`)) | \w+\((?:|\g<2>)\)
((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`) | \w+\((?:|\g<2>)\))
)
(?:\s+COLLATE\s+(?:\w+|"\w+"))?
(?:\s+ASC|\s+DESC)?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def column_name_with_order_matcher
(
(?:
# "schema_name"."table_name"."column_name"::type_name | function(one or no argument)::type_name
((?:\w+\.|"\w+"\.){,2}(?:\w+|"\w+")(?:::\w+)?) | \w+\((?:|\g<2>)\)(?:::\w+)?
((?:\w+\.|"\w+"\.){,2}(?:\w+|"\w+")(?:::\w+)? | \w+\((?:|\g<2>)\)(?:::\w+)?)
)
(?:(?:\s+AS)?\s+(?:\w+|"\w+"))?
)
Expand All @@ -147,7 +147,7 @@ def column_name_with_order_matcher
(
(?:
# "schema_name"."table_name"."column_name"::type_name | function(one or no argument)::type_name
((?:\w+\.|"\w+"\.){,2}(?:\w+|"\w+")(?:::\w+)?) | \w+\((?:|\g<2>)\)(?:::\w+)?
((?:\w+\.|"\w+"\.){,2}(?:\w+|"\w+")(?:::\w+)? | \w+\((?:|\g<2>)\)(?:::\w+)?)
)
(?:\s+COLLATE\s+"\w+")?
(?:\s+ASC|\s+DESC)?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def column_name_with_order_matcher
(
(?:
# "table_name"."column_name" | function(one or no argument)
((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
((?:\w+\.|"\w+"\.)?(?:\w+|"\w+") | \w+\((?:|\g<2>)\))
)
(?:(?:\s+AS)?\s+(?:\w+|"\w+"))?
)
Expand All @@ -99,7 +99,7 @@ def column_name_with_order_matcher
(
(?:
# "table_name"."column_name" | function(one or no argument)
((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
((?:\w+\.|"\w+"\.)?(?:\w+|"\w+") | \w+\((?:|\g<2>)\))
)
(?:\s+COLLATE\s+(?:\w+|"\w+"))?
(?:\s+ASC|\s+DESC)?
Expand Down
16 changes: 16 additions & 0 deletions activerecord/test/cases/unsafe_raw_sql_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@ class UnsafeRawSqlTest < ActiveRecord::TestCase
assert_equal ids_expected, ids
end

test "order: allows nested functions" do
ids_expected = Post.order(Arel.sql("author_id, length(trim(title))")).pluck(:id)

ids = Post.order("author_id, length(trim(title))").pluck(:id)

assert_equal ids_expected, ids
end

test "order: logs deprecation warning for unrecognized column" do
e = assert_raises(ActiveRecord::UnknownAttributeReference) do
Post.order("REPLACE(title, 'misc', 'zzzz')")
Expand Down Expand Up @@ -253,6 +261,14 @@ class UnsafeRawSqlTest < ActiveRecord::TestCase
assert_equal titles_expected, titles
end

test "pluck: allows nested functions" do
title_lengths_expected = Post.pluck(Arel.sql("length(trim(title))"))

title_lengths = Post.pluck("length(trim(title))")

assert_equal title_lengths_expected, title_lengths
end

test "pluck: disallows invalid column name" do
assert_raises(ActiveRecord::UnknownAttributeReference) do
Post.pluck("REPLACE(title, 'misc', 'zzzz')")
Expand Down

0 comments on commit 71c59c6

Please sign in to comment.