Skip to content

Commit

Permalink
Handle UTF-8 characters in command arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
tishun committed Dec 12, 2024
1 parent b76f985 commit 8bdaf6e
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 21 deletions.
27 changes: 8 additions & 19 deletions src/main/java/io/lettuce/core/protocol/CommandArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package io.lettuce.core.protocol;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
Expand Down Expand Up @@ -53,7 +54,7 @@
*/
public class CommandArgs<K, V> {

static final byte[] CRLF = "\r\n".getBytes(StandardCharsets.US_ASCII);
static final byte[] CRLF = "\r\n".getBytes(StandardCharsets.UTF_8);

protected final RedisCodec<K, V> codec;

Expand Down Expand Up @@ -609,16 +610,9 @@ void encode(ByteBuf target) {
}

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

target.writeByte('$');

IntegerArgument.writeInteger(target, value.length());
target.writeBytes(CRLF);

for (int i = 0; i < value.length(); i++) {
target.writeByte((byte) value.charAt(i));
}
target.writeBytes(CRLF);
BytesArgument.writeBytes(target, output);
}

@Override
Expand Down Expand Up @@ -646,16 +640,11 @@ void encode(ByteBuf target) {
}

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

target.writeByte('$');

IntegerArgument.writeInteger(target, value.length);
target.writeBytes(CRLF);

for (char c : value) {
target.writeByte((byte) c);
}
target.writeBytes(CRLF);
BytesArgument.writeBytes(target, output);
}

@Override
Expand Down
15 changes: 15 additions & 0 deletions src/test/java/io/lettuce/core/AuthenticationIntegrationTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ void setUp(StatefulRedisConnection<String, String> connection) {

connection.sync().dispatch(CommandType.ACL, new StatusOutput<>(StringCodec.UTF8),
new CommandArgs<>(StringCodec.UTF8).add("SETUSER").add("john").add("on").add(">foobared").add("-@all"));

connection.sync().dispatch(CommandType.ACL, new StatusOutput<>(StringCodec.UTF8),
new CommandArgs<>(StringCodec.UTF8).add("SETUSER").add("日本語").add("on").add(">日本語").add("+@all"));
}

@Test
Expand Down Expand Up @@ -71,4 +74,16 @@ void ownCredentialProvider(RedisClient client) {
});
}

@Test
@Inject
void authAsJapanese(RedisClient client) {

RedisURI uri = RedisURI.builder().withHost(TestSettings.host()).withPort(TestSettings.port())
.withAuthentication("日本語", "日本語".toCharArray()).build();

StatefulRedisConnection<String, String> connection = client.connect(uri);
assertThat(connection.sync().ping()).isEqualTo("PONG");
connection.close();
}

}
11 changes: 11 additions & 0 deletions src/test/java/io/lettuce/core/RedisCommandBuilderUnitTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ class RedisCommandBuilderUnitTests {

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

@Test()
void shouldCorrectlyConstructHello() {

Command<String, String, ?> command = sut.hello(3, "日本語", "日本語".toCharArray(), null);
ByteBuf buf = Unpooled.directBuffer();
command.encode(buf);

assertThat(buf.toString(StandardCharsets.UTF_8)).isEqualTo("*5\r\n" + "$5\r\n" + "HELLO\r\n" + "$1\r\n" + "3\r\n"
+ "$4\r\n" + "AUTH\r\n" + "$9\r\n" + "日本語\r\n" + "$9\r\n" + "日本語\r\n");
}

@Test
void shouldCorrectlyConstructXreadgroup() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void aclLog() {

@Test
void aclList() {
assertThat(redis.aclList()).hasSize(1).first().asString().contains("user default");
assertThat(redis.aclList()).hasSize(2).first().asString().contains("user default");
}

@Test
Expand Down Expand Up @@ -161,7 +161,7 @@ void aclSetuserWithCategories() {

@Test
void aclUsers() {
assertThat(redis.aclUsers()).hasSize(1).first().isEqualTo("default");
assertThat(redis.aclUsers()).hasSize(2).first().isEqualTo("default");
}

@Test
Expand Down

0 comments on commit 8bdaf6e

Please sign in to comment.