Skip to content

Commit fbb3951

Browse files
tishunthachlp
authored andcommitted
Handle UTF-8 characters in command arguments (#3075)
1 parent 76b52c5 commit fbb3951

File tree

4 files changed

+36
-21
lines changed

4 files changed

+36
-21
lines changed

src/main/java/io/lettuce/core/protocol/CommandArgs.java

+8-19
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package io.lettuce.core.protocol;
2121

2222
import java.nio.ByteBuffer;
23+
import java.nio.CharBuffer;
2324
import java.nio.charset.StandardCharsets;
2425
import java.util.ArrayList;
2526
import java.util.Base64;
@@ -53,7 +54,7 @@
5354
*/
5455
public class CommandArgs<K, V> {
5556

56-
static final byte[] CRLF = "\r\n".getBytes(StandardCharsets.US_ASCII);
57+
static final byte[] CRLF = "\r\n".getBytes(StandardCharsets.UTF_8);
5758

5859
protected final RedisCodec<K, V> codec;
5960

@@ -609,16 +610,9 @@ void encode(ByteBuf target) {
609610
}
610611

611612
static void writeString(ByteBuf target, String value) {
613+
byte[] output = value.getBytes(StandardCharsets.UTF_8);
612614

613-
target.writeByte('$');
614-
615-
IntegerArgument.writeInteger(target, value.length());
616-
target.writeBytes(CRLF);
617-
618-
for (int i = 0; i < value.length(); i++) {
619-
target.writeByte((byte) value.charAt(i));
620-
}
621-
target.writeBytes(CRLF);
615+
BytesArgument.writeBytes(target, output);
622616
}
623617

624618
@Override
@@ -646,16 +640,11 @@ void encode(ByteBuf target) {
646640
}
647641

648642
static void writeString(ByteBuf target, char[] value) {
643+
final ByteBuffer byteBuffer = StandardCharsets.UTF_8.encode(CharBuffer.wrap(value));
644+
final byte[] output = new byte[byteBuffer.remaining()];
645+
byteBuffer.get(output);
649646

650-
target.writeByte('$');
651-
652-
IntegerArgument.writeInteger(target, value.length);
653-
target.writeBytes(CRLF);
654-
655-
for (char c : value) {
656-
target.writeByte((byte) c);
657-
}
658-
target.writeBytes(CRLF);
647+
BytesArgument.writeBytes(target, output);
659648
}
660649

661650
@Override

src/test/java/io/lettuce/core/AuthenticationIntegrationTests.java

+15
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ void setUp(StatefulRedisConnection<String, String> connection) {
5454
connection.sync().dispatch(CommandType.ACL, new StatusOutput<>(StringCodec.UTF8),
5555
new CommandArgs<>(StringCodec.UTF8).add("SETUSER").add("john").add("on").add(">foobared").add("-@all"));
5656

57+
connection.sync().dispatch(CommandType.ACL, new StatusOutput<>(StringCodec.UTF8),
58+
new CommandArgs<>(StringCodec.UTF8).add("SETUSER").add("日本語").add("on").add(">日本語").add("+@all"));
59+
5760
connection.sync().dispatch(CommandType.ACL, new StatusOutput<>(StringCodec.UTF8),
5861
new CommandArgs<>(StringCodec.UTF8).add("SETUSER").add("steave").add("on").add(">foobared").add("+@all"));
5962
}
@@ -90,6 +93,18 @@ void ownCredentialProvider(RedisClient client) {
9093
});
9194
}
9295

96+
@Test
97+
@Inject
98+
void authAsJapanese(RedisClient client) {
99+
100+
RedisURI uri = RedisURI.builder().withHost(TestSettings.host()).withPort(TestSettings.port())
101+
.withAuthentication("日本語", "日本語".toCharArray()).build();
102+
103+
StatefulRedisConnection<String, String> connection = client.connect(uri);
104+
assertThat(connection.sync().ping()).isEqualTo("PONG");
105+
connection.close();
106+
}
107+
93108
// Simulate test user credential rotation, and verify that re-authentication is successful
94109
@Test
95110
@Inject

src/test/java/io/lettuce/core/RedisCommandBuilderUnitTests.java

+11
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ class RedisCommandBuilderUnitTests {
3232

3333
RedisCommandBuilder<String, String> sut = new RedisCommandBuilder<>(StringCodec.UTF8);
3434

35+
@Test()
36+
void shouldCorrectlyConstructHello() {
37+
38+
Command<String, String, ?> command = sut.hello(3, "日本語", "日本語".toCharArray(), null);
39+
ByteBuf buf = Unpooled.directBuffer();
40+
command.encode(buf);
41+
42+
assertThat(buf.toString(StandardCharsets.UTF_8)).isEqualTo("*5\r\n" + "$5\r\n" + "HELLO\r\n" + "$1\r\n" + "3\r\n"
43+
+ "$4\r\n" + "AUTH\r\n" + "$9\r\n" + "日本語\r\n" + "$9\r\n" + "日本語\r\n");
44+
}
45+
3546
@Test
3647
void shouldCorrectlyConstructXreadgroup() {
3748

src/test/java/io/lettuce/core/commands/AclCommandIntegrationTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ void aclLog() {
131131

132132
@Test
133133
void aclList() {
134-
assertThat(redis.aclList()).hasSize(1).first().asString().contains("user default");
134+
assertThat(redis.aclList()).hasSize(2).first().asString().contains("user default");
135135
}
136136

137137
@Test
@@ -161,7 +161,7 @@ void aclSetuserWithCategories() {
161161

162162
@Test
163163
void aclUsers() {
164-
assertThat(redis.aclUsers()).hasSize(1).first().isEqualTo("default");
164+
assertThat(redis.aclUsers()).hasSize(2).first().isEqualTo("default");
165165
}
166166

167167
@Test

0 commit comments

Comments
 (0)