mirror of https://github.com/rails/rails
Revert "Quote binary strings in Arel"
This commit is contained in:
parent
335733b858
commit
bb7f3be138
|
@ -46,7 +46,6 @@ module ActiveModel
|
||||||
def serialize(value)
|
def serialize(value)
|
||||||
case value
|
case value
|
||||||
when ::Numeric, ::Symbol, ActiveSupport::Duration then value.to_s
|
when ::Numeric, ::Symbol, ActiveSupport::Duration then value.to_s
|
||||||
when ::String then serialize_cast_value(value)
|
|
||||||
when true then @true
|
when true then @true
|
||||||
when false then @false
|
when false then @false
|
||||||
else super
|
else super
|
||||||
|
@ -54,12 +53,6 @@ module ActiveModel
|
||||||
end
|
end
|
||||||
|
|
||||||
def serialize_cast_value(value) # :nodoc:
|
def serialize_cast_value(value) # :nodoc:
|
||||||
if value&.encoding == Encoding::BINARY
|
|
||||||
# If we can treat the bytes as UTF-8 without changing them, then use UTF-8 as encoding
|
|
||||||
new_value = value.dup.force_encoding(Encoding::UTF_8)
|
|
||||||
return new_value if new_value.valid_encoding?
|
|
||||||
end
|
|
||||||
|
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -17,26 +17,6 @@ module ActiveModel
|
||||||
assert_same s, type.cast(s)
|
assert_same s, type.cast(s)
|
||||||
assert_same s, type.deserialize(s)
|
assert_same s, type.deserialize(s)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "leaves validly encoded strings untouched" do
|
|
||||||
s = "string with àccénts".encode(Encoding::ISO_8859_1)
|
|
||||||
type = Type::ImmutableString.new
|
|
||||||
assert_same s, type.serialize(s)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "serializes valid, binary-encoded strings to UTF-8" do
|
|
||||||
s = "string with àccénts".b
|
|
||||||
type = Type::ImmutableString.new
|
|
||||||
serialized = type.serialize(s)
|
|
||||||
assert_equal Encoding::UTF_8, serialized.encoding
|
|
||||||
assert_equal s.bytes, serialized.bytes
|
|
||||||
end
|
|
||||||
|
|
||||||
test "leaves true binary data untouched" do
|
|
||||||
binary_data = "\xEE\x49\xC7".b
|
|
||||||
type = Type::ImmutableString.new
|
|
||||||
assert_same binary_data, type.serialize(binary_data)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,10 +16,7 @@ module ActiveRecord
|
||||||
when false then quoted_false
|
when false then quoted_false
|
||||||
when nil then "NULL"
|
when nil then "NULL"
|
||||||
# BigDecimals need to be put in a non-normalized form and quoted.
|
# BigDecimals need to be put in a non-normalized form and quoted.
|
||||||
# Additionally, for Ruby 2.7, the string returned by `to_s` is ASCII-8BIT.
|
when BigDecimal then value.to_s("F")
|
||||||
# We want to avoid that, as that will cause the string to be quoted as
|
|
||||||
# binary. It is safe to force the encoding to US-ASCII.
|
|
||||||
when BigDecimal then value.to_s("F").force_encoding(Encoding::US_ASCII)
|
|
||||||
when Numeric then value.to_s
|
when Numeric then value.to_s
|
||||||
when Type::Binary::Data then quoted_binary(value)
|
when Type::Binary::Data then quoted_binary(value)
|
||||||
when Type::Time::Value then "'#{quoted_time(value)}'"
|
when Type::Time::Value then "'#{quoted_time(value)}'"
|
||||||
|
|
|
@ -6,30 +6,14 @@ module ActiveRecord
|
||||||
module ConnectionAdapters
|
module ConnectionAdapters
|
||||||
module MySQL
|
module MySQL
|
||||||
module Quoting # :nodoc:
|
module Quoting # :nodoc:
|
||||||
def quote(value)
|
|
||||||
case value
|
|
||||||
when String
|
|
||||||
if value.encoding == Encoding::BINARY
|
|
||||||
quoted_binary(value)
|
|
||||||
else
|
|
||||||
"'#{quote_string(value.to_s)}'"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def cast_bound_value(value)
|
def cast_bound_value(value)
|
||||||
case value
|
case value
|
||||||
when Rational
|
when Rational
|
||||||
value.to_f.to_s
|
value.to_f.to_s
|
||||||
when BigDecimal
|
|
||||||
# For Ruby 2.7, the string returned by `to_s` is ASCII-8BIT.
|
|
||||||
# We want to avoid that, as that will cause the string to be quoted as
|
|
||||||
# binary. It is safe to force the encoding to US-ASCII.
|
|
||||||
value.to_s("F").force_encoding(Encoding::US_ASCII)
|
|
||||||
when Numeric
|
when Numeric
|
||||||
value.to_s
|
value.to_s
|
||||||
|
when BigDecimal
|
||||||
|
value.to_s("F")
|
||||||
when true
|
when true
|
||||||
"1"
|
"1"
|
||||||
when false
|
when false
|
||||||
|
@ -67,11 +51,7 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def quoted_binary(value)
|
def quoted_binary(value)
|
||||||
if value.is_a? String
|
"x'#{value.hex}'"
|
||||||
"x'#{value.unpack1("H*")}'"
|
|
||||||
else
|
|
||||||
"x'#{value.hex}'"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def unquote_identifier(identifier)
|
def unquote_identifier(identifier)
|
||||||
|
|
|
@ -4,19 +4,6 @@ module ActiveRecord
|
||||||
module ConnectionAdapters
|
module ConnectionAdapters
|
||||||
module SQLite3
|
module SQLite3
|
||||||
module Quoting # :nodoc:
|
module Quoting # :nodoc:
|
||||||
def quote(value)
|
|
||||||
case value
|
|
||||||
when String
|
|
||||||
if value.encoding == Encoding::BINARY
|
|
||||||
quoted_binary(value)
|
|
||||||
else
|
|
||||||
"'#{quote_string(value.to_s)}'"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def quote_string(s)
|
def quote_string(s)
|
||||||
::SQLite3::Database.quote(s)
|
::SQLite3::Database.quote(s)
|
||||||
end
|
end
|
||||||
|
@ -39,11 +26,7 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def quoted_binary(value)
|
def quoted_binary(value)
|
||||||
if value.is_a? String
|
"x'#{value.hex}'"
|
||||||
"x'#{value.unpack1("H*")}'"
|
|
||||||
else
|
|
||||||
"x'#{value.hex}'"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def quoted_true
|
def quoted_true
|
||||||
|
@ -79,6 +62,12 @@ module ActiveRecord
|
||||||
case value
|
case value
|
||||||
when BigDecimal
|
when BigDecimal
|
||||||
value.to_f
|
value.to_f
|
||||||
|
when String
|
||||||
|
if value.encoding == Encoding::ASCII_8BIT
|
||||||
|
super(value.encode(Encoding::UTF_8))
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
else
|
else
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,19 +37,4 @@ class BinaryTest < ActiveRecord::TestCase
|
||||||
assert_equal data, bin.reload.data, "Reloaded data differs from original"
|
assert_equal data, bin.reload.data, "Reloaded data differs from original"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
unless current_adapter?(:PostgreSQLAdapter)
|
|
||||||
def test_does_not_cause_database_warnings
|
|
||||||
original_db_warnings_action = ActiveRecord.db_warnings_action
|
|
||||||
ActiveRecord.db_warnings_action = :raise
|
|
||||||
|
|
||||||
Binary.delete_all
|
|
||||||
binary_data = "\xEE\x49\xC7".b
|
|
||||||
Binary.connection.insert(Arel.sql("INSERT INTO binaries(data) VALUES(?)", binary_data))
|
|
||||||
binary = Binary.first
|
|
||||||
assert_equal binary_data, binary.data
|
|
||||||
ensure
|
|
||||||
ActiveRecord.db_warnings_action = original_db_warnings_action || :ignore
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue