You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kvrocks.apache.org by ti...@apache.org on 2022/09/03 07:46:20 UTC
[incubator-kvrocks] branch unstable updated: Fix inline protocol don't allow LF only EOL (#808)
This is an automated email from the ASF dual-hosted git repository.
tison pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/incubator-kvrocks.git
The following commit(s) were added to refs/heads/unstable by this push:
new 2cb5190 Fix inline protocol don't allow LF only EOL (#808)
2cb5190 is described below
commit 2cb51903532e26db231f040e57c6e1e9a74edc13
Author: hulk <hu...@gmail.com>
AuthorDate: Sat Sep 3 15:46:15 2022 +0800
Fix inline protocol don't allow LF only EOL (#808)
---
src/redis_request.cc | 18 ++++++++++++++----
tests/tcl/tests/unit/protocol.tcl | 23 +++++++++++++++++++++++
2 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/src/redis_request.cc b/src/redis_request.cc
index 158f531..88a18c4 100644
--- a/src/redis_request.cc
+++ b/src/redis_request.cc
@@ -43,7 +43,16 @@ Status Request::Tokenize(evbuffer *input) {
while (true) {
switch (state_) {
case ArrayLen: {
- UniqueEvbufReadln line(input, EVBUFFER_EOL_CRLF_STRICT);
+ bool isOnlyLF = true;
+ // We don't use the `EVBUFFER_EOL_CRLF_STRICT` here since only LF is allowed in INLINE protocol.
+ // So we need to search LF EOL and figure out current line has CR or not.
+ UniqueEvbufReadln line(input, EVBUFFER_EOL_LF);
+ if (line && line.length > 0 && line[line.length-1] == '\r') {
+ // remove `\r` if exists
+ --line.length;
+ isOnlyLF = false;
+ }
+
if (!line || line.length <= 0) {
if (pipeline_size > 128) {
LOG(INFO) << "Large pipeline detected: " << pipeline_size;
@@ -53,6 +62,7 @@ Status Request::Tokenize(evbuffer *input) {
}
return Status::OK();
}
+
pipeline_size++;
svr_->stats_.IncrInbondBytes(line.length);
if (line[0] == '*') {
@@ -61,13 +71,13 @@ Status Request::Tokenize(evbuffer *input) {
} catch (std::exception &e) {
return Status(Status::NotOK, "Protocol error: invalid multibulk length");
}
+ if (isOnlyLF || multi_bulk_len_ > (int64_t)PROTO_MULTI_MAX_SIZE) {
+ return Status(Status::NotOK, "Protocol error: invalid multibulk length");
+ }
if (multi_bulk_len_ <= 0) {
multi_bulk_len_ = 0;
continue;
}
- if (multi_bulk_len_ > (int64_t)PROTO_MULTI_MAX_SIZE) {
- return Status(Status::NotOK, "Protocol error: invalid multibulk length");
- }
state_ = BulkLen;
} else {
if (line.length > PROTO_INLINE_MAX_SIZE) {
diff --git a/tests/tcl/tests/unit/protocol.tcl b/tests/tcl/tests/unit/protocol.tcl
index c6ed5cc..bb8b915 100644
--- a/tests/tcl/tests/unit/protocol.tcl
+++ b/tests/tcl/tests/unit/protocol.tcl
@@ -82,6 +82,29 @@ start_server {tags {"protocol network"}} {
r flush
assert_equal "OK" [r read]
}
+
+ test "Allow only LF protocol separator" {
+ reconnect
+ r write "set foo 123\n"
+ r flush
+ assert_equal "OK" [r read]
+ }
+
+ test "Mix LF/CRLF protocol separator" {
+ reconnect
+ r write "*-1\r\nset foo 123\nget foo\r\n*3\r\n\$3\r\nset\r\n\$3\r\nkey\r\n\$3\r\nval\r\n"
+ r flush
+ assert_equal "OK" [r read]
+ assert_equal "123" [r read]
+ assert_equal "OK" [r read]
+ }
+
+ test "invalid LF in multi bulk protocol" {
+ reconnect
+ r write "*3\n\$3\r\nset\r\n\$3\r\nkey\r\n\$3\r\nval\r\n"
+ r flush
+ assert_error "*invalid multibulk length*" {r read}
+ }
}
start_server {tags {"regression"}} {