Skip to content

Commit

Permalink
Replace std::stol with ParseInt (#897)
Browse files Browse the repository at this point in the history
  • Loading branch information
tanruixiang authored Sep 25, 2022
1 parent 91cebf2 commit 6d8e8f5
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 122 deletions.
177 changes: 87 additions & 90 deletions src/redis_cmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -490,16 +490,12 @@ class CommandSet : public Commander {
if (ttl_ <= 0) return Status(Status::RedisParseErr, errInvalidExpireTime);
} else if (opt == "px" && !ttl_ && !last_arg) {
int64_t ttl_ms = 0;
try {
std::string s = args_[++i];
std::string::size_type sz;
ttl_ms = std::stol(s, &sz);
if (sz != s.size()) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
} catch (std::exception &e) {
std::string s = args_[++i];
auto parse_result = ParseInt<int64_t>(s, 10);
if (!parse_result) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
ttl_ms = *parse_result;
if (ttl_ms <= 0) return Status(Status::RedisParseErr, errInvalidExpireTime);
if (ttl_ms > 0 && ttl_ms < 1000) {
ttl_ = 1; // round up the pttl to second
Expand Down Expand Up @@ -566,17 +562,16 @@ class CommandSetEX : public Commander {
class CommandPSetEX : public Commander {
public:
Status Parse(const std::vector<std::string> &args) override {
try {
auto ttl_ms = std::stol(args[2]);
if (ttl_ms <= 0) return Status(Status::RedisParseErr, errInvalidExpireTime);
if (ttl_ms > 0 && ttl_ms < 1000) {
ttl_ = 1;
} else {
ttl_ = ttl_ms / 1000;
}
} catch (std::exception &e) {
auto ttl_ms = ParseInt<int64_t>(args[2], 10);
if (!ttl_ms) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
if (*ttl_ms <= 0) return Status(Status::RedisParseErr, errInvalidExpireTime);
if (*ttl_ms > 0 && *ttl_ms < 1000) {
ttl_ = 1;
} else {
ttl_ = *ttl_ms / 1000;
}
return Commander::Parse(args);
}

Expand Down Expand Up @@ -679,11 +674,11 @@ class CommandDecr : public Commander {
class CommandIncrBy : public Commander {
public:
Status Parse(const std::vector<std::string> &args) override {
try {
increment_ = std::stoll(args[2]);
} catch (std::exception &e) {
auto parse_result = ParseInt<int64_t>(args[2], 10);
if (!parse_result) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
increment_ = *parse_result;
return Commander::Parse(args);
}

Expand Down Expand Up @@ -727,11 +722,11 @@ class CommandIncrByFloat : public Commander {
class CommandDecrBy : public Commander {
public:
Status Parse(const std::vector<std::string> &args) override {
try {
increment_ = std::stoll(args[2]);
} catch (std::exception &e) {
auto parse_result = ParseInt<int64_t>(args[2], 10);
if (!parse_result) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
increment_ = *parse_result;
return Commander::Parse(args);
}

Expand Down Expand Up @@ -822,16 +817,12 @@ class CommandDel : public Commander {
};

Status getBitOffsetFromArgument(std::string arg, uint32_t *offset) {
int64_t offset_arg = 0;
try {
offset_arg = std::stoll(arg);
} catch (std::exception &e) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
if (offset_arg < 0 || offset_arg > UINT_MAX) {
return Status(Status::RedisParseErr, "bit offset is out of range");
auto parse_result = ParseInt<uint32_t>(arg, 10);
if (!parse_result) {
return parse_result.ToStatus();
}
*offset = static_cast<uint32_t>(offset_arg);

*offset = *parse_result;
return Status::OK();
}

Expand Down Expand Up @@ -891,12 +882,16 @@ class CommandBitCount : public Commander {
return Status(Status::RedisParseErr, errInvalidSyntax);
}
if (args.size() == 4) {
try {
start_ = std::stol(args[2]);
stop_ = std::stol(args[3]);
} catch (std::exception &e) {
auto parse_start = ParseInt<int64_t>(args[2], 10);
if (!parse_start) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
start_ = *parse_start;
auto parse_stop = ParseInt<int64_t>(args[3], 10);
if (!parse_stop) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
stop_ = *parse_stop;
}
return Commander::Parse(args);
}
Expand All @@ -917,14 +912,20 @@ class CommandBitCount : public Commander {
class CommandBitPos: public Commander {
public:
Status Parse(const std::vector<std::string> &args) override {
try {
if (args.size() >= 4) start_ = std::stol(args[3]);
if (args.size() >= 5) {
stop_given_ = true;
stop_ = std::stol(args[4]);
if (args.size() >= 4) {
auto parse_start = ParseInt<int64_t>(args[3], 10);
if (!parse_start) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
} catch (std::exception &e) {
return Status(Status::RedisParseErr, errValueNotInterger);
start_ = *parse_start;
}
if (args.size() >= 5) {
auto parse_stop = ParseInt<int64_t>(args[4], 10);
if (!parse_stop) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
stop_given_ = true;
stop_ = *parse_stop;
}
if (args[2] == "0") {
bit_ = false;
Expand Down Expand Up @@ -1106,20 +1107,19 @@ class CommandPExpire : public Commander {
Status Parse(const std::vector<std::string> &args) override {
int64_t now;
rocksdb::Env::Default()->GetCurrentTime(&now);
try {
auto ttl_ms = std::stol(args[2]);
if (ttl_ms > 0 && ttl_ms < 1000) {
seconds_ = 1;
} else {
seconds_ = ttl_ms / 1000;
if (seconds_ >= INT32_MAX - now) {
return Status(Status::RedisParseErr, "the expire time was overflow");
}
}
seconds_ += now;
} catch (std::exception &e) {
auto ttl_ms = ParseInt<int64_t>(args[2], 10);
if (!ttl_ms) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
if (*ttl_ms > 0 && *ttl_ms < 1000) {
seconds_ = 1;
} else {
seconds_ = *ttl_ms / 1000;
if (seconds_ >= INT32_MAX - now) {
return Status(Status::RedisParseErr, "the expire time was overflow");
}
}
seconds_ += now;
return Commander::Parse(args);
}

Expand Down Expand Up @@ -1169,14 +1169,14 @@ class CommandExpireAt : public Commander {
class CommandPExpireAt : public Commander {
public:
Status Parse(const std::vector<std::string> &args) override {
try {
timestamp_ = static_cast<int>(std::stol(args[2])/1000);
if (timestamp_ >= INT32_MAX) {
return Status(Status::RedisParseErr, "the expire time was overflow");
}
} catch (std::exception &e) {
auto parse_result = ParseInt<int64_t>(args[2], 10);
if (!parse_result) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
if (*parse_result/1000 >= INT32_MAX) {
return Status(Status::RedisParseErr, "the expire time was overflow");
}
timestamp_ = static_cast<int>(*parse_result/1000);
return Commander::Parse(args);
}
Status Execute(Server *svr, Connection *conn, std::string *output) override {
Expand Down Expand Up @@ -1303,11 +1303,11 @@ class CommandHLen : public Commander {
class CommandHIncrBy : public Commander {
public:
Status Parse(const std::vector<std::string> &args) override {
try {
increment_ = std::stoll(args[3]);
} catch (std::exception &e) {
auto parse_result = ParseInt<int64_t>(args[3], 10);
if (!parse_result) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
increment_ = *parse_result;
return Commander::Parse(args);
}
Status Execute(Server *svr, Connection *conn, std::string *output) override {
Expand Down Expand Up @@ -1557,16 +1557,15 @@ class CommandPop : public Commander {
if (args.size() == 2) {
return Status::OK();
}
try {
int32_t v = std::stol(args[2]);
if (v < 0) {
return Status(Status::RedisParseErr, errValueMustBePositive);
}
count_ = v;
with_count_ = true;
} catch (const std::exception& ) {
auto v = ParseInt<int32_t>(args[2], 10);
if (!v) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
if (*v < 0) {
return Status(Status::RedisParseErr, errValueMustBePositive);
}
count_ = *v;
with_count_ = true;
return Status::OK();
}

Expand Down Expand Up @@ -4005,11 +4004,11 @@ class CommandClient : public Commander {
if (!strcasecmp(args[i].c_str(), "addr") && moreargs) {
addr_ = args[i+1];
} else if (!strcasecmp(args[i].c_str(), "id") && moreargs) {
try {
id_ = std::stoll(args[i+1]);
} catch (std::exception &e) {
auto parse_result = ParseInt<uint64_t>(args[i+1], 10);
if (!parse_result) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
id_ = *parse_result;
} else if (!strcasecmp(args[i].c_str(), "skipme") && moreargs) {
if (!strcasecmp(args[i+1].c_str(), "yes")) {
skipme_ = true;
Expand Down Expand Up @@ -4201,12 +4200,12 @@ class CommandHello final : public Commander {
size_t next_arg = 1;
if (args_.size() >= 2) {
int64_t protocol;
auto parseResult = ParseInt<int64_t>(args_[next_arg], /* base= */ 10);
auto parse_result = ParseInt<int64_t>(args_[next_arg], 10);
++next_arg;
if (!parseResult.IsOK()) {
if (!parse_result) {
return Status(Status::NotOK, "Protocol version is not an integer or out of range");
}
protocol = parseResult.GetValue();
protocol = *parse_result;

// In redis, it will check protocol < 2 or protocol > 3,
// kvrocks only supports REPL2 by now, but for supporting some
Expand Down Expand Up @@ -5428,13 +5427,12 @@ class CommandXRead : public Commander {
if (i+1 >= args.size()) {
return Status(Status::RedisParseErr, errInvalidSyntax);
}

try {
with_count_ = true;
count_ = static_cast<uint64_t>(std::stoll(args[i+1]));
} catch (const std::exception &) {
with_count_ = true;
auto parse_result = ParseInt<uint64_t>(args[i+1], 10);
if (!parse_result) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
count_ = *parse_result;
i += 2;
continue;
}
Expand All @@ -5445,15 +5443,14 @@ class CommandXRead : public Commander {
}

block_ = true;
try {
auto v = std::stoll(args[i+1]);
if (v < 0) {
return Status(Status::RedisParseErr, errTimeoutIsNegative);
}
block_timeout_ = v;
} catch (const std::exception &) {
auto parse_result = ParseInt<int64_t>(args[i+1], 10);
if (!parse_result) {
return Status(Status::RedisParseErr, errValueNotInterger);
}
if (*parse_result < 0) {
return Status(Status::RedisParseErr, errTimeoutIsNegative);
}
block_timeout_ = *parse_result;
i += 2;
continue;
}
Expand Down
13 changes: 7 additions & 6 deletions src/redis_hash.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
*/

#include "redis_hash.h"
#include <cctype>
#include <utility>
#include <algorithm>
#include <limits>
#include <cmath>
#include <iostream>
#include <rocksdb/status.h>
#include "db_util.h"
#include "parse_util.h"

namespace Redis {
rocksdb::Status Hash::GetMetadata(const Slice &ns_key, HashMetadata *metadata) {
Expand Down Expand Up @@ -74,18 +76,17 @@ rocksdb::Status Hash::IncrBy(const Slice &user_key, const Slice &field, int64_t
InternalKey(ns_key, field, metadata.version, storage_->IsSlotIdEncoded()).Encode(&sub_key);
if (s.ok()) {
std::string value_bytes;
std::size_t idx = 0;
s = db_->Get(rocksdb::ReadOptions(), sub_key, &value_bytes);
if (!s.ok() && !s.IsNotFound()) return s;
if (s.ok()) {
try {
old_value = std::stoll(value_bytes, &idx);
} catch (std::exception &e) {
return rocksdb::Status::InvalidArgument(e.what());
auto parse_result = ParseInt<int64_t>(value_bytes, 10);
if (!parse_result) {
return rocksdb::Status::InvalidArgument(parse_result.Msg());
}
if (isspace(value_bytes[0]) || idx != value_bytes.size()) {
if (isspace(value_bytes[0])) {
return rocksdb::Status::InvalidArgument("value is not an integer");
}
old_value = *parse_result;
exists = true;
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/redis_request.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "server.h"
#include "redis_slot.h"
#include "event_util.h"
#include "parse_util.h"

namespace Redis {
const size_t PROTO_INLINE_MAX_SIZE = 16 * 1024L;
Expand Down Expand Up @@ -66,11 +67,11 @@ Status Request::Tokenize(evbuffer *input) {
pipeline_size++;
svr_->stats_.IncrInbondBytes(line.length);
if (line[0] == '*') {
try {
multi_bulk_len_ = std::stoll(std::string(line.get() + 1, line.length - 1));
} catch (std::exception &e) {
auto parse_result = ParseInt<int64_t>(std::string(line.get() + 1, line.length - 1), 10);
if (!parse_result) {
return Status(Status::NotOK, "Protocol error: invalid multibulk length");
}
multi_bulk_len_ = *parse_result;
if (isOnlyLF || multi_bulk_len_ > (int64_t)PROTO_MULTI_MAX_SIZE) {
return Status(Status::NotOK, "Protocol error: invalid multibulk length");
}
Expand Down
Loading

0 comments on commit 6d8e8f5

Please sign in to comment.