summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2018-08-31 11:49:27 +0800
committerzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2018-08-31 20:02:09 +0800
commitdce7cefb7ca5b8efad865fca14c16d773a106e3d (patch)
tree9bdcf317c5d7210dfe64500c4e4bece24813a3b0
parented5cc77ce0ffecc1742587debae944e1bf04128c (diff)
downloadredis-dce7cefb7ca5b8efad865fca14c16d773a106e3d.tar.gz
networking: fix unexpected negative or zero readlen
To avoid copying buffers to create a large Redis Object which exceeding PROTO_IOBUF_LEN 32KB, we just read the remaining data we need, which may less than PROTO_IOBUF_LEN. But the remaining len may be zero, if the bulklen+2 equals sdslen(c->querybuf), in client pause context. For example: Time1: python >>> import os, socket >>> server="127.0.0.1" >>> port=6379 >>> data1="*3\r\n$3\r\nset\r\n$1\r\na\r\n$33000\r\n" >>> data2="".join("x" for _ in range(33000)) + "\r\n" >>> data3="\n\n" >>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) >>> s.settimeout(10) >>> s.connect((server, port)) >>> s.send(data1) 28 Time2: redis-cli client pause 10000 Time3: >>> s.send(data2) 33002 >>> s.send(data3) 2 >>> s.send(data3) Traceback (most recent call last): File "<stdin>", line 1, in <module> socket.error: [Errno 104] Connection reset by peer To fix that, we should check if remaining is greater than zero.
-rw-r--r--src/networking.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/networking.c b/src/networking.c
index 58248ced0..17d82d1a2 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -1439,7 +1439,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
{
ssize_t remaining = (size_t)(c->bulklen+2)-sdslen(c->querybuf);
- if (remaining < readlen) readlen = remaining;
+ if (remaining > 0 && remaining < readlen) readlen = remaining;
}
qblen = sdslen(c->querybuf);