fix(parser): Don't accept NILs as command arguments in server mode (#1101)

* fix(parser): Don't accept NILs as command arguments in server mode
This commit is contained in:
Roy Jacobson 2023-04-18 17:44:36 +03:00 committed by GitHub
parent 2033b671ef
commit 002ec8a621
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 9 deletions

View file

@ -215,6 +215,7 @@ auto RedisParser::ParseNum(Buffer str, int64_t* res) -> Result {
if (str.size() < 4) {
return INPUT_PENDING;
}
DCHECK(str[0] == '$' || str[0] == '*' || str[0] == '%');
char* s = reinterpret_cast<char*>(str.data() + 1);
char* pos = reinterpret_cast<char*>(memchr(s, '\n', str.size() - 1));
@ -250,7 +251,7 @@ auto RedisParser::ConsumeArrayLen(Buffer str) -> Result {
return BAD_ARRAYLEN;
case OK:
if (len < -1 || len > kMaxArrayLen) {
VLOG_IF(1, len > kMaxArrayLen) << "Milti bulk len is too big " << len;
VLOG_IF(1, len > kMaxArrayLen) << "Multi bulk len is too big " << len;
return BAD_ARRAYLEN;
}
@ -297,14 +298,6 @@ auto RedisParser::ConsumeArrayLen(Buffer str) -> Result {
auto RedisParser::ParseArg(Buffer str) -> Result {
char c = str[0];
if (c == '_') { // Resp3 NIL
state_ = FINISH_ARG_S;
cached_expr_->emplace_back(RespExpr::NIL);
cached_expr_->back().u = Buffer{};
last_consumed_ += 3; // '_','\r','\n'
return OK;
}
if (c == '$') {
int64_t len;
@ -340,6 +333,15 @@ auto RedisParser::ParseArg(Buffer str) -> Result {
return BAD_BULKLEN;
}
if (c == '_') { // Resp3 NIL
// TODO: Do we need to validate that str[1:2] == "\r\n"?
state_ = FINISH_ARG_S;
cached_expr_->emplace_back(RespExpr::NIL);
cached_expr_->back().u = Buffer{};
last_consumed_ += 3; // '_','\r','\n'
return OK;
}
if (c == '*') {
return ConsumeArrayLen(str);
}

View file

@ -191,4 +191,10 @@ TEST_F(RedisParserTest, LargeBulk) {
ASSERT_EQ(RedisParser::OK, Parse("\r\n"));
}
TEST_F(RedisParserTest, NILs) {
ASSERT_EQ(RedisParser::BAD_BULKLEN, Parse("_\r\n"));
parser_.SetClientMode();
ASSERT_EQ(RedisParser::OK, Parse("_\r\n"));
}
} // namespace facade