RedisDecoder infinite loop
Motivation: RedisDecoder can get into an infinite loop while decoding bulk strings if the final \r and \n to indicate the end of content are split on ByteBuf boundaries. Modifications: - We should break out of the decode loop if remainingBulkLength is 0 and we don't have enough data to read EOL Result: No more infinite loop in RedisDecoder#decodeBulkStringContent.
This commit is contained in:
parent
0b0309624a
commit
742ee76424
@ -201,7 +201,7 @@ public final class RedisDecoder extends ByteToMessageDecoder {
|
|||||||
// ${expectedBulkLength}\r\n <here> {data...}\r\n
|
// ${expectedBulkLength}\r\n <here> {data...}\r\n
|
||||||
private boolean decodeBulkStringContent(ByteBuf in, List<Object> out) throws Exception {
|
private boolean decodeBulkStringContent(ByteBuf in, List<Object> out) throws Exception {
|
||||||
final int readableBytes = in.readableBytes();
|
final int readableBytes = in.readableBytes();
|
||||||
if (readableBytes == 0) {
|
if (readableBytes == 0 || remainingBulkLength == 0 && readableBytes < RedisConstants.EOL_LENGTH) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,9 +27,15 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static io.netty.handler.codec.redis.RedisCodecTestUtil.*;
|
import static io.netty.handler.codec.redis.RedisCodecTestUtil.byteBufOf;
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static io.netty.handler.codec.redis.RedisCodecTestUtil.bytesOf;
|
||||||
import static org.junit.Assert.*;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies the correct functionality of the {@link RedisDecoder} and {@link RedisArrayAggregator}.
|
* Verifies the correct functionality of the {@link RedisDecoder} and {@link RedisArrayAggregator}.
|
||||||
@ -51,6 +57,16 @@ public class RedisDecoderTest {
|
|||||||
assertFalse(channel.finish());
|
assertFalse(channel.finish());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void splitEOLDoesNotInfiniteLoop() throws Exception {
|
||||||
|
assertFalse(channel.writeInbound(byteBufOf("$6\r\nfoobar\r")));
|
||||||
|
assertTrue(channel.writeInbound(byteBufOf("\n")));
|
||||||
|
|
||||||
|
RedisMessage msg = channel.readInbound();
|
||||||
|
assertTrue(msg instanceof FullBulkStringRedisMessage);
|
||||||
|
ReferenceCountUtil.release(msg);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldDecodeSimpleString() {
|
public void shouldDecodeSimpleString() {
|
||||||
assertFalse(channel.writeInbound(byteBufOf("+")));
|
assertFalse(channel.writeInbound(byteBufOf("+")));
|
||||||
|
Loading…
Reference in New Issue
Block a user