mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Handle broken encoding in #write_query?
If the SQL encoding somehow is invalid, `Regexp#match?` raises `ArgumentError`. Best we can do is to copy the string and try to match the regexp in "binary" mode. Hopefully these cases are rare enough that the string copy should be an important overhead.
This commit is contained in:
parent
86100a1ebf
commit
b629a5bc42
5 changed files with 26 additions and 1 deletions
|
@ -68,7 +68,7 @@ module ActiveRecord
|
|||
def self.build_read_query_regexp(*parts) # :nodoc:
|
||||
parts += DEFAULT_READ_QUERY
|
||||
parts = parts.map { |part| /#{part}/i }
|
||||
/\A(?:[(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
|
||||
/\A(?:[(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/n
|
||||
end
|
||||
|
||||
def self.quoted_column_names # :nodoc:
|
||||
|
|
|
@ -26,6 +26,8 @@ module ActiveRecord
|
|||
|
||||
def write_query?(sql) # :nodoc:
|
||||
!READ_QUERY.match?(sql)
|
||||
rescue ArgumentError # Invalid encoding
|
||||
!READ_QUERY.match?(sql.b)
|
||||
end
|
||||
|
||||
def explain(arel, binds = [])
|
||||
|
|
|
@ -28,6 +28,8 @@ module ActiveRecord
|
|||
|
||||
def write_query?(sql) # :nodoc:
|
||||
!READ_QUERY.match?(sql)
|
||||
rescue ArgumentError # Invalid encoding
|
||||
!READ_QUERY.match?(sql.b)
|
||||
end
|
||||
|
||||
# Executes an SQL statement, returning a PG::Result object on success
|
||||
|
|
|
@ -11,6 +11,8 @@ module ActiveRecord
|
|||
|
||||
def write_query?(sql) # :nodoc:
|
||||
!READ_QUERY.match?(sql)
|
||||
rescue ArgumentError # Invalid encoding
|
||||
!READ_QUERY.match?(sql.b)
|
||||
end
|
||||
|
||||
def explain(arel, binds = [])
|
||||
|
|
|
@ -51,6 +51,25 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
if current_adapter?(:PostgreSQLAdapter)
|
||||
def test_doesnt_error_when_a_select_query_has_encoding_errors
|
||||
ActiveRecord::Base.while_preventing_writes do
|
||||
# Contrary to other adapters, Postgres will eagerly fail on encoding errors.
|
||||
# But at least we can assert it fails in the client and not before when trying to
|
||||
# match the query.
|
||||
assert_raises ActiveRecord::StatementInvalid do
|
||||
@connection.select_all("SELECT '\xC8'")
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
def test_doesnt_error_when_a_select_query_has_encoding_errors
|
||||
ActiveRecord::Base.while_preventing_writes do
|
||||
@connection.select_all("SELECT '\xC8'")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_doesnt_error_when_a_select_query_is_called_while_preventing_writes
|
||||
@connection.insert("INSERT INTO subscribers(nick) VALUES ('138853948594')")
|
||||
|
||||
|
|
Loading…
Reference in a new issue