From 2df19ab3f1a8aaf20f8ae107d80a8282438398f2 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 13 Oct 2021 20:35:30 +0200 Subject: [PATCH] Handle parts of the command using incompatible encodings --- lib/redis/connection/command_helper.rb | 6 ++++++ test/client_test.rb | 9 +++++++++ test/distributed_commands_requiring_clustering_test.rb | 8 ++++---- test/lint/strings.rb | 8 ++++---- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/redis/connection/command_helper.rb b/lib/redis/connection/command_helper.rb index 04b89113a..2faeb4e03 100644 --- a/lib/redis/connection/command_helper.rb +++ b/lib/redis/connection/command_helper.rb @@ -12,11 +12,13 @@ def build_command(args) if i.is_a? Array i.each do |j| j = j.to_s + j = j.encoding == Encoding::BINARY ? j : j.b command << "$#{j.bytesize}" command << j end else i = i.to_s + i = i.encoding == Encoding::BINARY ? i : i.b command << "$#{i.bytesize}" command << i end @@ -33,6 +35,10 @@ def build_command(args) def encode(string) string.force_encoding(Encoding.default_external) + unless string.valid_encoding? + string.force_encoding(Encoding::BINARY) + end + string end end end diff --git a/test/client_test.rb b/test/client_test.rb index 30f7e2cff..6a6b07e91 100644 --- a/test/client_test.rb +++ b/test/client_test.rb @@ -73,4 +73,13 @@ def resolve end assert_equal 'Error connecting to Redis on 127.0.0.5:999 (Errno::ECONNREFUSED)', error.message end + + def test_mixed_encoding + r.call("MSET", "fée", "\x00\xFF".b, "じ案".encode(Encoding::SHIFT_JIS), "\t".encode(Encoding::ASCII)) + assert_equal "\x00\xFF".b, r.call("GET", "fée") + assert_equal "\t", r.call("GET", "じ案".encode(Encoding::SHIFT_JIS)) + + r.call("SET", "\x00\xFF".b, "fée") + assert_equal "fée", r.call("GET", "\x00\xFF".b) + end end diff --git a/test/distributed_commands_requiring_clustering_test.rb b/test/distributed_commands_requiring_clustering_test.rb index 7ffbe532d..cce43ec9d 100644 --- a/test/distributed_commands_requiring_clustering_test.rb +++ b/test/distributed_commands_requiring_clustering_test.rb @@ -164,13 +164,13 @@ def test_bitop r.set("{qux}bar", "b") r.bitop(:and, "{qux}foo&bar", "{qux}foo", "{qux}bar") - assert_equal "\x60", r.get("{qux}foo&bar") + assert_equal "\x60".b, r.get("{qux}foo&bar") r.bitop(:or, "{qux}foo|bar", "{qux}foo", "{qux}bar") - assert_equal "\x63", r.get("{qux}foo|bar") + assert_equal "\x63".b, r.get("{qux}foo|bar") r.bitop(:xor, "{qux}foo^bar", "{qux}foo", "{qux}bar") - assert_equal "\x03", r.get("{qux}foo^bar") + assert_equal "\x03".b, r.get("{qux}foo^bar") r.bitop(:not, "{qux}~foo", "{qux}foo") - assert_equal "\x9E", r.get("{qux}~foo") + assert_equal "\x9E".b, r.get("{qux}~foo") end end end diff --git a/test/lint/strings.rb b/test/lint/strings.rb index 78a483aa9..ef92b58b4 100644 --- a/test/lint/strings.rb +++ b/test/lint/strings.rb @@ -386,13 +386,13 @@ def test_bitop r.set('bar{1}', 'b') r.bitop(:and, 'foo&bar{1}', 'foo{1}', 'bar{1}') - assert_equal "\x60", r.get('foo&bar{1}') + assert_equal "\x60".b, r.get('foo&bar{1}') r.bitop(:or, 'foo|bar{1}', 'foo{1}', 'bar{1}') - assert_equal "\x63", r.get('foo|bar{1}') + assert_equal "\x63".b, r.get('foo|bar{1}') r.bitop(:xor, 'foo^bar{1}', 'foo{1}', 'bar{1}') - assert_equal "\x03", r.get('foo^bar{1}') + assert_equal "\x03".b, r.get('foo^bar{1}') r.bitop(:not, '~foo{1}', 'foo{1}') - assert_equal "\x9E", r.get('~foo{1}') + assert_equal "\x9E".b, r.get('~foo{1}') end end end